diff options
Diffstat (limited to 'apps')
658 files changed, 20132 insertions, 5645 deletions
diff --git a/apps/files/ajax/getstoragestats.php b/apps/files/ajax/getstoragestats.php index 32a77bff6c3..dd7c7dc5571 100644 --- a/apps/files/ajax/getstoragestats.php +++ b/apps/files/ajax/getstoragestats.php @@ -3,7 +3,13 @@ // only need filesystem apps $RUNTIME_APPTYPES = array('filesystem'); +$dir = '/'; + +if (isset($_GET['dir'])) { + $dir = $_GET['dir']; +} + OCP\JSON::checkLoggedIn(); // send back json -OCP\JSON::success(array('data' => \OCA\Files\Helper::buildFileStorageStatistics('/'))); +OCP\JSON::success(array('data' => \OCA\Files\Helper::buildFileStorageStatistics($dir))); diff --git a/apps/files/ajax/list.php b/apps/files/ajax/list.php index 350fc7fa5f6..0be38c3b96f 100644 --- a/apps/files/ajax/list.php +++ b/apps/files/ajax/list.php @@ -10,7 +10,7 @@ OCP\JSON::checkLoggedIn(); // Load the files $dir = isset( $_GET['dir'] ) ? $_GET['dir'] : ''; - +$dir = \OC\Files\Filesystem::normalizePath($dir); if (!\OC\Files\Filesystem::is_dir($dir . '/')) { header("HTTP/1.0 404 Not Found"); exit(); diff --git a/apps/files/ajax/newfile.php b/apps/files/ajax/newfile.php index 76c03c87a51..ec5b716fb2a 100644 --- a/apps/files/ajax/newfile.php +++ b/apps/files/ajax/newfile.php @@ -20,15 +20,6 @@ if($source) { OC_JSON::callCheck(); } -if($filename == '') { - OCP\JSON::error(array("data" => array( "message" => "Empty Filename" ))); - exit(); -} -if(strpos($filename, '/')!==false) { - OCP\JSON::error(array("data" => array( "message" => "Invalid Filename" ))); - exit(); -} - function progress($notification_code, $severity, $message, $message_code, $bytes_transferred, $bytes_max) { static $filesize = 0; static $lastsize = 0; @@ -44,7 +35,7 @@ function progress($notification_code, $severity, $message, $message_code, $bytes if (!isset($filesize)) { } else { $progress = (int)(($bytes_transferred/$filesize)*100); - if($progress>$lastsize) {//limit the number or messages send + if($progress>$lastsize) { //limit the number or messages send $eventSource->send('progress', $progress); } $lastsize=$progress; @@ -54,24 +45,65 @@ function progress($notification_code, $severity, $message, $message_code, $bytes } } +$l10n = \OC_L10n::get('files'); + +$result = array( + 'success' => false, + 'data' => NULL + ); + +if(trim($filename) === '') { + $result['data'] = array('message' => (string)$l10n->t('File name cannot be empty.')); + OCP\JSON::error($result); + exit(); +} + +if(strpos($filename, '/') !== false) { + $result['data'] = array('message' => (string)$l10n->t('File name must not contain "/". Please choose a different name.')); + OCP\JSON::error($result); + exit(); +} + +//TODO why is stripslashes used on foldername in newfolder.php but not here? $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(); +} + if($source) { if(substr($source, 0, 8)!='https://' and substr($source, 0, 7)!='http://') { - OCP\JSON::error(array("data" => array( "message" => "Not a valid source" ))); + OCP\JSON::error(array('data' => array('message' => $l10n->t('Not a valid source')))); + exit(); + } + + if (!ini_get('allow_url_fopen')) { + $eventSource->send('error', array('message' => $l10n->t('Server is not allowed to open URLs, please check the server configuration'))); + $eventSource->close(); exit(); } $ctx = stream_context_create(null, array('notification' =>'progress')); - $sourceStream=fopen($source, 'rb', false, $ctx); - $result=\OC\Files\Filesystem::file_put_contents($target, $sourceStream); + $sourceStream=@fopen($source, 'rb', false, $ctx); + $result = 0; + if (is_resource($sourceStream)) { + $result=\OC\Files\Filesystem::file_put_contents($target, $sourceStream); + } if($result) { $meta = \OC\Files\Filesystem::getFileInfo($target); $mime=$meta['mimetype']; $id = $meta['fileid']; - $eventSource->send('success', array('mime'=>$mime, 'size'=>\OC\Files\Filesystem::filesize($target), 'id' => $id)); + $eventSource->send('success', array('mime' => $mime, 'size' => \OC\Files\Filesystem::filesize($target), 'id' => $id, 'etag' => $meta['etag'])); } else { - $eventSource->send('error', "Error while downloading ".$source. ' to '.$target); + $eventSource->send('error', array('message' => $l10n->t('Error while downloading %s to %s', array($source, $target)))); + } + if (is_resource($sourceStream)) { + fclose($sourceStream); } $eventSource->close(); exit(); @@ -99,9 +131,10 @@ if($source) { 'mime' => $mime, 'size' => $size, 'content' => $content, + 'etag' => $meta['etag'], ))); exit(); } } -OCP\JSON::error(array("data" => array( "message" => "Error when creating the file" ))); +OCP\JSON::error(array('data' => array( 'message' => $l10n->t('Error when creating the file') ))); diff --git a/apps/files/ajax/newfolder.php b/apps/files/ajax/newfolder.php index e26e1238bc6..2cbc8cfeba5 100644 --- a/apps/files/ajax/newfolder.php +++ b/apps/files/ajax/newfolder.php @@ -10,25 +10,47 @@ OCP\JSON::callCheck(); $dir = isset( $_POST['dir'] ) ? stripslashes($_POST['dir']) : ''; $foldername = isset( $_POST['foldername'] ) ? stripslashes($_POST['foldername']) : ''; -if(trim($foldername) == '') { - OCP\JSON::error(array("data" => array( "message" => "Empty Foldername" ))); +$l10n = \OC_L10n::get('files'); + +$result = array( + 'success' => false, + 'data' => NULL + ); + +if(trim($foldername) === '') { + $result['data'] = array('message' => $l10n->t('Folder name cannot be empty.')); + OCP\JSON::error($result); + exit(); +} + +if(strpos($foldername, '/') !== false) { + $result['data'] = array('message' => $l10n->t('Folder name must not contain "/". Please choose a different name.')); + OCP\JSON::error($result); exit(); } -if(strpos($foldername, '/')!==false) { - OCP\JSON::error(array("data" => array( "message" => "Invalid Foldername" ))); + +//TODO why is stripslashes used on foldername here but not in newfile.php? +$target = $dir . '/' . stripslashes($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(); } -if(\OC\Files\Filesystem::mkdir($dir . '/' . stripslashes($foldername))) { - if ( $dir != '/') { +if(\OC\Files\Filesystem::mkdir($target)) { + if ( $dir !== '/') { $path = $dir.'/'.$foldername; } else { $path = '/'.$foldername; } $meta = \OC\Files\Filesystem::getFileInfo($path); $id = $meta['fileid']; - OCP\JSON::success(array("data" => array('id'=>$id))); + OCP\JSON::success(array('data' => array('id' => $id))); exit(); } -OCP\JSON::error(array("data" => array( "message" => "Error when creating the folder" ))); +OCP\JSON::error(array('data' => array( 'message' => $l10n->t('Error when creating the folder') ))); diff --git a/apps/files/ajax/upload.php b/apps/files/ajax/upload.php index 0920bf62109..0e905f993ac 100644 --- a/apps/files/ajax/upload.php +++ b/apps/files/ajax/upload.php @@ -7,6 +7,8 @@ OCP\JSON::setContentTypeHeader('text/plain'); // If not, check the login. // If no token is sent along, rely on login only +$allowedPermissions = OCP\PERMISSION_ALL; + $l = OC_L10N::get('files'); if (empty($_POST['dirToken'])) { // The standard case, files are uploaded through logged in users :) @@ -17,6 +19,9 @@ if (empty($_POST['dirToken'])) { die(); } } else { + // return only read permissions for public upload + $allowedPermissions = OCP\PERMISSION_READ; + $linkItem = OCP\Share::getShareByToken($_POST['dirToken']); if ($linkItem === false) { OCP\JSON::error(array('data' => array_merge(array('message' => $l->t('Invalid Token'))))); @@ -110,30 +115,36 @@ if (strpos($dir, '..') === false) { || (isset($_POST['resolution']) && $_POST['resolution']==='replace') ) { // upload and overwrite file - if (is_uploaded_file($files['tmp_name'][$i]) and \OC\Files\Filesystem::fromTmpFile($files['tmp_name'][$i], $target)) { - - // updated max file size after upload - $storageStats = \OCA\Files\Helper::buildFileStorageStatistics($dir); - - $meta = \OC\Files\Filesystem::getFileInfo($target); - if ($meta === false) { - $error = $l->t('Upload failed. Could not get file info.'); + try + { + if (is_uploaded_file($files['tmp_name'][$i]) and \OC\Files\Filesystem::fromTmpFile($files['tmp_name'][$i], $target)) { + + // updated max file size after upload + $storageStats = \OCA\Files\Helper::buildFileStorageStatistics($dir); + + $meta = \OC\Files\Filesystem::getFileInfo($target); + if ($meta === false) { + $error = $l->t('Upload failed. Could not get file info.'); + } else { + $result[] = array('status' => 'success', + 'mime' => $meta['mimetype'], + 'mtime' => $meta['mtime'], + 'size' => $meta['size'], + 'id' => $meta['fileid'], + 'name' => basename($target), + 'etag' => $meta['etag'], + 'originalname' => $files['tmp_name'][$i], + 'uploadMaxFilesize' => $maxUploadFileSize, + 'maxHumanFilesize' => $maxHumanFileSize, + 'permissions' => $meta['permissions'] & $allowedPermissions + ); + } + } else { - $result[] = array('status' => 'success', - 'mime' => $meta['mimetype'], - 'mtime' => $meta['mtime'], - 'size' => $meta['size'], - 'id' => $meta['fileid'], - 'name' => basename($target), - 'originalname' => $files['tmp_name'][$i], - 'uploadMaxFilesize' => $maxUploadFileSize, - 'maxHumanFilesize' => $maxHumanFileSize, - 'permissions' => $meta['permissions'], - ); + $error = $l->t('Upload failed. Could not find uploaded file'); } - - } else { - $error = $l->t('Upload failed. Could not find uploaded file'); + } catch(Exception $ex) { + $error = $ex->getMessage(); } } else { @@ -148,10 +159,11 @@ if (strpos($dir, '..') === false) { 'size' => $meta['size'], 'id' => $meta['fileid'], 'name' => basename($target), + 'etag' => $meta['etag'], 'originalname' => $files['tmp_name'][$i], 'uploadMaxFilesize' => $maxUploadFileSize, 'maxHumanFilesize' => $maxHumanFileSize, - 'permissions' => $meta['permissions'], + 'permissions' => $meta['permissions'] & $allowedPermissions ); } } @@ -164,5 +176,5 @@ if ($error === false) { OCP\JSON::encodedPrint($result); exit(); } else { - OCP\JSON::error(array('data' => array_merge(array('message' => $error), $storageStats))); + OCP\JSON::error(array(array('data' => array_merge(array('message' => $error), $storageStats)))); } diff --git a/apps/files/appinfo/remote.php b/apps/files/appinfo/remote.php index 0c1f2e6580c..9f290796205 100644 --- a/apps/files/appinfo/remote.php +++ b/apps/files/appinfo/remote.php @@ -39,7 +39,7 @@ $rootDir = new OC_Connector_Sabre_Directory(''); $objectTree = new \OC\Connector\Sabre\ObjectTree($rootDir); // Fire up server -$server = new Sabre_DAV_Server($objectTree); +$server = new OC_Connector_Sabre_Server($objectTree); $server->httpRequest = $requestBackend; $server->setBaseUri($baseuri); @@ -48,6 +48,7 @@ $defaults = new OC_Defaults(); $server->addPlugin(new Sabre_DAV_Auth_Plugin($authBackend, $defaults->getName())); $server->addPlugin(new Sabre_DAV_Locks_Plugin($lockBackend)); $server->addPlugin(new Sabre_DAV_Browser_Plugin(false)); // Show something in the Browser, but no upload +$server->addPlugin(new OC_Connector_Sabre_FilesPlugin()); $server->addPlugin(new OC_Connector_Sabre_AbortedUploadDetectionPlugin()); $server->addPlugin(new OC_Connector_Sabre_QuotaPlugin()); $server->addPlugin(new OC_Connector_Sabre_MaintenancePlugin()); diff --git a/apps/files/css/files.css b/apps/files/css/files.css index e26c1a89b78..2fc86ca537d 100644 --- a/apps/files/css/files.css +++ b/apps/files/css/files.css @@ -8,16 +8,19 @@ .actions .button a { color: #555; } .actions .button a:hover, .actions .button a:active { color: #333; } -#new, #trash { +#new { z-index: 1010; float: left; padding: 0 !important; /* override default control bar button padding */ } #trash { - margin-right: 12px; + margin-right: 8px; float: right; + z-index: 1010; + padding: 10px; + font-weight: normal; } -#new>a, #trash>a { +#new>a { padding: 14px 10px; position: relative; top: 7px; @@ -47,7 +50,13 @@ background-repeat:no-repeat; cursor:pointer; } #new>ul>li>p { cursor:pointer; padding-top: 7px; padding-bottom: 7px;} - +#new .error, #fileList .error { + color: #e9322d; + border-color: #e9322d; + -webkit-box-shadow: 0 0 6px #f8b9b7; + -moz-box-shadow: 0 0 6px #f8b9b7; + box-shadow: 0 0 6px #f8b9b7; +} /* FILE TABLE */ @@ -56,6 +65,9 @@ top: 44px; width: 100%; } +#filestable, #controls { + min-width: 680px; +} #filestable tbody tr { background-color:#fff; height:2.5em; } #filestable tbody tr:hover, tbody tr:active { background-color: rgb(240,240,240); @@ -103,8 +115,6 @@ table th#headerDate, table td.date { box-sizing: border-box; position: relative; min-width: 11em; - display: block; - height: 51px; } /* Multiselect bar */ @@ -159,8 +169,6 @@ table td.filename .nametext, .uploadtext, .modified { float:left; padding:.3em 0 } .modified { position: relative; - top: 11px; - left: 5px; } /* TODO fix usability bug (accidental file/folder selection) */ @@ -176,6 +184,9 @@ table td.filename .nametext { table td.filename .uploadtext { font-weight:normal; margin-left:.5em; } table td.filename form { font-size:.85em; margin-left:3em; margin-right:3em; } +.ie8 input[type="checkbox"]{ + padding: 0; +} /* File checkboxes */ #fileList tr td.filename>input[type="checkbox"]:first-child { @@ -238,22 +249,12 @@ table td.filename form { font-size:.85em; margin-left:3em; margin-right:3em; } top: 14px; right: 0; } -#fileList tr:hover .fileactions { /* background to distinguish when overlaying with file names */ - background-color: rgba(240,240,240,0.898); - box-shadow: -5px 0 7px rgba(240,240,240,0.898); -} -#fileList tr.selected:hover .fileactions, #fileList tr.mouseOver .fileactions { /* slightly darker color for selected rows */ - background-color: rgba(230,230,230,.9); - box-shadow: -5px 0 7px rgba(230,230,230,.9); -} #fileList img.move2trash { display:inline; margin:-.5em 0; padding:1em .5em 1em .5em !important; float:right; } #fileList a.action.delete { position: absolute; right: 0; - top: 0; - margin: 0; - padding: 15px 14px 19px !important; + padding: 9px 14px 19px !important; } a.action>img { max-height:16px; max-width:16px; vertical-align:text-bottom; } @@ -323,8 +324,9 @@ table.dragshadow { width:auto; } table.dragshadow td.filename { - padding-left:36px; + padding-left:60px; padding-right:16px; + height: 36px; } table.dragshadow td.size { padding-right:8px; diff --git a/apps/files/download.php b/apps/files/download.php index e3fe24e45d7..6b055e99a53 100644 --- a/apps/files/download.php +++ b/apps/files/download.php @@ -37,12 +37,7 @@ if(!\OC\Files\Filesystem::file_exists($filename)) { $ftype=\OC\Files\Filesystem::getMimeType( $filename ); header('Content-Type:'.$ftype); -if ( preg_match( "/MSIE/", $_SERVER["HTTP_USER_AGENT"] ) ) { - header( 'Content-Disposition: attachment; filename="' . rawurlencode( basename($filename) ) . '"' ); -} else { - header( 'Content-Disposition: attachment; filename*=UTF-8\'\'' . rawurlencode( basename($filename) ) - . '; filename="' . rawurlencode( basename($filename) ) . '"' ); -} +OCP\Response::setContentDispositionHeader(basename($filename), 'attachment'); OCP\Response::disableCaching(); header('Content-Length: '.\OC\Files\Filesystem::filesize($filename)); diff --git a/apps/files/index.php b/apps/files/index.php index 8d877be8ac9..8f6838aa0d9 100644 --- a/apps/files/index.php +++ b/apps/files/index.php @@ -36,6 +36,7 @@ OCP\Util::addscript('files', 'filelist'); OCP\App::setActiveNavigationEntry('files_index'); // Load the files $dir = isset($_GET['dir']) ? stripslashes($_GET['dir']) : ''; +$dir = \OC\Files\Filesystem::normalizePath($dir); // Redirect if directory does not exist if (!\OC\Files\Filesystem::is_dir($dir . '/')) { header('Location: ' . OCP\Util::getScriptName() . ''); @@ -107,7 +108,6 @@ if ($needUpgrade) { // if the encryption app is disabled, than everything is fine (INIT_SUCCESSFUL status code) $encryptionInitStatus = 2; if (OC_App::isEnabled('files_encryption')) { - $publicUploadEnabled = 'no'; $session = new \OCA\Encryption\Session(new \OC\Files\View('/')); $encryptionInitStatus = $session->getInitialized(); } @@ -118,14 +118,18 @@ if ($needUpgrade) { $trashEmpty = \OCA\Files_Trashbin\Trashbin::isEmpty($user); } + $isCreatable = \OC\Files\Filesystem::isCreatable($dir . '/'); + $fileHeader = (!isset($files) or count($files) > 0); + $emptyContent = ($isCreatable and !$fileHeader) or $ajaxLoad; + OCP\Util::addscript('files', 'fileactions'); OCP\Util::addscript('files', 'files'); OCP\Util::addscript('files', 'keyboardshortcuts'); $tmpl = new OCP\Template('files', 'index', 'user'); $tmpl->assign('fileList', $list->fetchPage()); $tmpl->assign('breadcrumb', $breadcrumbNav->fetchPage()); - $tmpl->assign('dir', \OC\Files\Filesystem::normalizePath($dir)); - $tmpl->assign('isCreatable', \OC\Files\Filesystem::isCreatable($dir . '/')); + $tmpl->assign('dir', $dir); + $tmpl->assign('isCreatable', $isCreatable); $tmpl->assign('permissions', $permissions); $tmpl->assign('files', $files); $tmpl->assign('trash', $trashEnabled); @@ -138,9 +142,12 @@ if ($needUpgrade) { $tmpl->assign('publicUploadEnabled', $publicUploadEnabled); $tmpl->assign("encryptedFiles", \OCP\Util::encryptedFiles()); $tmpl->assign("mailNotificationEnabled", \OC_Appconfig::getValue('core', 'shareapi_allow_mail_notification', 'yes')); + $tmpl->assign("allowShareWithLink", \OC_Appconfig::getValue('core', 'shareapi_allow_links', 'yes')); $tmpl->assign("encryptionInitStatus", $encryptionInitStatus); $tmpl->assign('disableSharing', false); $tmpl->assign('ajaxLoad', $ajaxLoad); + $tmpl->assign('emptyContent', $emptyContent); + $tmpl->assign('fileHeader', $fileHeader); $tmpl->printPage(); } diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js index b52221ac1fc..225c3319107 100644 --- a/apps/files/js/file-upload.js +++ b/apps/files/js/file-upload.js @@ -21,13 +21,13 @@ function supportAjaxUploadWithProgress() { var fi = document.createElement('INPUT'); fi.type = 'file'; return 'files' in fi; - }; + } // Are progress events supported? function supportAjaxUploadProgressEvents() { var xhr = new XMLHttpRequest(); return !! (xhr && ('upload' in xhr) && ('onprogress' in xhr.upload)); - }; + } // Is FormData supported? function supportFormData() { @@ -42,26 +42,6 @@ function supportAjaxUploadWithProgress() { OC.Upload = { _uploads: [], /** - * cancels a single upload, - * @deprecated because it was only used when a file currently beeing uploaded was deleted. Now they are added after - * they have been uploaded. - * @param {string} dir - * @param {string} filename - * @returns {unresolved} - */ - cancelUpload:function(dir, filename) { - var self = this; - var deleted = false; - //FIXME _selections - jQuery.each(this._uploads, function(i, jqXHR) { - if (selection.dir === dir && selection.uploads[filename]) { - deleted = self.deleteSelectionUpload(selection, filename); - return false; // end searching through selections - } - }); - return deleted; - }, - /** * deletes the jqHXR object from a data selection * @param {object} data */ @@ -73,12 +53,12 @@ OC.Upload = { */ cancelUploads:function() { this.log('canceling uploads'); - jQuery.each(this._uploads,function(i, jqXHR){ + jQuery.each(this._uploads,function(i, jqXHR) { jqXHR.abort(); }); this._uploads = []; }, - rememberUpload:function(jqXHR){ + rememberUpload:function(jqXHR) { if (jqXHR) { this._uploads.push(jqXHR); } @@ -88,10 +68,10 @@ OC.Upload = { * returns true if any hxr has the state 'pending' * @returns {boolean} */ - isProcessing:function(){ + isProcessing:function() { var count = 0; - jQuery.each(this._uploads,function(i, data){ + jQuery.each(this._uploads,function(i, data) { if (data.state() === 'pending') { count++; } @@ -134,7 +114,7 @@ OC.Upload = { * handle skipping an upload * @param {object} data */ - onSkip:function(data){ + onSkip:function(data) { this.log('skip', null, data); this.deleteUpload(data); }, @@ -142,21 +122,25 @@ OC.Upload = { * handle replacing a file on the server with an uploaded file * @param {object} data */ - onReplace:function(data){ + onReplace:function(data) { this.log('replace', null, data); - data.data.append('resolution', 'replace'); + if (data.data) { + data.data.append('resolution', 'replace'); + } else { + data.formData.push({name:'resolution', value:'replace'}); //hack for ie8 + } data.submit(); }, /** * handle uploading a file and letting the server decide a new name * @param {object} data */ - onAutorename:function(data){ + onAutorename:function(data) { this.log('autorename', null, data); if (data.data) { data.data.append('resolution', 'autorename'); } else { - data.formData.push({name:'resolution',value:'autorename'}); //hack for ie8 + data.formData.push({name:'resolution', value:'autorename'}); //hack for ie8 } data.submit(); }, @@ -178,7 +162,7 @@ OC.Upload = { * @param {function} callbacks.onChooseConflicts * @param {function} callbacks.onCancel */ - checkExistingFiles: function (selection, callbacks){ + checkExistingFiles: function (selection, callbacks) { // TODO check filelist before uploading and show dialog on conflicts, use callbacks callbacks.onNoConflicts(selection); } @@ -231,13 +215,21 @@ $(document).ready(function() { var selection = data.originalFiles.selection; // add uploads - if ( selection.uploads.length < selection.filesToUpload ){ + if ( selection.uploads.length < selection.filesToUpload ) { // remember upload selection.uploads.push(data); } //examine file var file = data.files[0]; + try { + // FIXME: not so elegant... need to refactor that method to return a value + Files.isFileNameValid(file.name); + } + catch (errorMessage) { + data.textStatus = 'invalidcharacters'; + data.errorThrown = errorMessage; + } if (file.type === '' && file.size === 4096) { data.textStatus = 'dirorzero'; @@ -319,16 +311,15 @@ $(document).ready(function() { OC.Upload.log('fail', e, data); if (typeof data.textStatus !== 'undefined' && data.textStatus !== 'success' ) { if (data.textStatus === 'abort') { - $('#notification').text(t('files', 'Upload cancelled.')); + OC.Notification.show(t('files', 'Upload cancelled.')); } else { // HTTP connection problem - $('#notification').text(data.errorThrown); + OC.Notification.show(data.errorThrown); } - $('#notification').fadeIn(); - //hide notification after 5 sec + //hide notification after 10 sec setTimeout(function() { - $('#notification').fadeOut(); - }, 5000); + OC.Notification.hide(); + }, 10000); } OC.Upload.deleteUpload(data); }, @@ -350,8 +341,13 @@ $(document).ready(function() { var result=$.parseJSON(response); delete data.jqXHR; - - if(typeof result[0] === 'undefined') { + + if (result.status === 'error' && result.data && result.data.message){ + data.textStatus = 'servererror'; + data.errorThrown = result.data.message; + var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload'); + fu._trigger('fail', e, data); + } else if (typeof result[0] === 'undefined') { data.textStatus = 'servererror'; data.errorThrown = t('files', 'Could not get result from server.'); var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload'); @@ -365,7 +361,7 @@ $(document).ready(function() { } else if (result[0].status !== 'success') { //delete data.jqXHR; data.textStatus = 'servererror'; - data.errorThrown = result.data.message; // error message has been translated on server + data.errorThrown = result[0].data.message; // error message has been translated on server var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload'); fu._trigger('fail', e, data); } @@ -384,13 +380,13 @@ $(document).ready(function() { var fileupload = $('#file_upload_start').fileupload(file_upload_param); window.file_upload_param = fileupload; - if(supportAjaxUploadWithProgress()) { + if (supportAjaxUploadWithProgress()) { // add progress handlers fileupload.on('fileuploadadd', function(e, data) { OC.Upload.log('progress handle fileuploadadd', e, data); //show cancel button - //if(data.dataType !== 'iframe') { //FIXME when is iframe used? only for ie? + //if (data.dataType !== 'iframe') { //FIXME when is iframe used? only for ie? // $('#uploadprogresswrapper input.stop').show(); //} }); @@ -415,7 +411,7 @@ $(document).ready(function() { $('#uploadprogresswrapper input.stop').fadeOut(); $('#uploadprogressbar').fadeOut(); - + Files.updateStorageStatistics(); }); fileupload.on('fileuploadfail', function(e, data) { OC.Upload.log('progress handle fileuploadfail', e, data); @@ -435,7 +431,9 @@ $(document).ready(function() { // http://stackoverflow.com/a/6700/11236 var size = 0, key; for (key in obj) { - if (obj.hasOwnProperty(key)) size++; + if (obj.hasOwnProperty(key)) { + size++; + } } return size; }; @@ -448,56 +446,65 @@ $(document).ready(function() { }); //add multiply file upload attribute to all browsers except konqueror (which crashes when it's used) - if(navigator.userAgent.search(/konqueror/i)==-1){ - $('#file_upload_start').attr('multiple','multiple'); + if (navigator.userAgent.search(/konqueror/i) === -1) { + $('#file_upload_start').attr('multiple', 'multiple'); } //if the breadcrumb is to long, start by replacing foldernames with '...' except for the current folder var crumb=$('div.crumb').first(); - while($('div.controls').height()>40 && crumb.next('div.crumb').length>0){ + while($('div.controls').height() > 40 && crumb.next('div.crumb').length > 0) { crumb.children('a').text('...'); - crumb=crumb.next('div.crumb'); + crumb = crumb.next('div.crumb'); } //if that isn't enough, start removing items from the breacrumb except for the current folder and it's parent - var crumb=$('div.crumb').first(); - var next=crumb.next('div.crumb'); - while($('div.controls').height()>40 && next.next('div.crumb').length>0){ + var crumb = $('div.crumb').first(); + var next = crumb.next('div.crumb'); + while($('div.controls').height()>40 && next.next('div.crumb').length > 0) { crumb.remove(); - crumb=next; - next=crumb.next('div.crumb'); + crumb = next; + next = crumb.next('div.crumb'); } //still not enough, start shorting down the current folder name var crumb=$('div.crumb>a').last(); - while($('div.controls').height()>40 && crumb.text().length>6){ - var text=crumb.text() - text=text.substr(0,text.length-6)+'...'; + while($('div.controls').height() > 40 && crumb.text().length > 6) { + var text=crumb.text(); + text = text.substr(0,text.length-6)+'...'; crumb.text(text); } - $(document).click(function(){ + $(document).click(function(ev) { + // do not close when clicking in the dropdown + if ($(ev.target).closest('#new').length){ + return; + } $('#new>ul').hide(); $('#new').removeClass('active'); - $('#new li').each(function(i,element){ - if($(element).children('p').length==0){ + if ($('#new .error').length > 0) { + $('#new .error').tipsy('hide'); + } + $('#new li').each(function(i,element) { + if ($(element).children('p').length === 0) { $(element).children('form').remove(); $(element).append('<p>'+$(element).data('text')+'</p>'); } }); }); - $('#new').click(function(event){ + $('#new').click(function(event) { event.stopPropagation(); }); - $('#new>a').click(function(){ + $('#new>a').click(function() { $('#new>ul').toggle(); $('#new').toggleClass('active'); }); - $('#new li').click(function(){ - if($(this).children('p').length==0){ + $('#new li').click(function() { + if ($(this).children('p').length === 0) { return; } + + $('#new .error').tipsy('hide'); - $('#new li').each(function(i,element){ - if($(element).children('p').length==0){ + $('#new li').each(function(i,element) { + if ($(element).children('p').length === 0) { $(element).children('form').remove(); $(element).append('<p>'+$(element).data('text')+'</p>'); } @@ -507,129 +514,180 @@ $(document).ready(function() { var text=$(this).children('p').text(); $(this).data('text',text); $(this).children('p').remove(); - var form=$('<form></form>'); - var input=$('<input type="text">'); + + // add input field + var form = $('<form></form>'); + var input = $('<input type="text">'); + var newName = $(this).attr('data-newname') || ''; + if (newName) { + input.val(newName); + } form.append(input); $(this).append(form); + var lastPos; + var checkInput = function () { + var filename = input.val(); + if (type === 'web' && filename.length === 0) { + throw t('files', 'URL cannot be empty'); + } else if (type !== 'web' && !Files.isFileNameValid(filename)) { + // Files.isFileNameValid(filename) throws an exception itself + } else if ($('#dir').val() === '/' && filename === 'Shared') { + throw t('files', 'In the home folder \'Shared\' is a reserved filename'); + } else if (FileList.inList(filename)) { + throw t('files', '{new_name} already exists', {new_name: filename}); + } else { + return true; + } + }; + + // verify filename on typing + input.keyup(function(event) { + try { + checkInput(); + input.tipsy('hide'); + input.removeClass('error'); + } catch (error) { + input.attr('title', error); + input.tipsy({gravity: 'w', trigger: 'manual'}); + input.tipsy('show'); + input.addClass('error'); + } + }); + input.focus(); - form.submit(function(event){ + // pre select name up to the extension + lastPos = newName.lastIndexOf('.'); + if (lastPos === -1) { + lastPos = newName.length; + } + input.selectRange(0, lastPos); + form.submit(function(event) { event.stopPropagation(); event.preventDefault(); - var newname=input.val(); - if(type == 'web' && newname.length == 0) { - OC.Notification.show(t('files', 'URL cannot be empty.')); - return false; - } else if (type != 'web' && !Files.isFileNameValid(newname)) { - return false; - } else if( type == 'folder' && $('#dir').val() == '/' && newname == 'Shared') { - OC.Notification.show(t('files','Invalid folder name. Usage of \'Shared\' is reserved by ownCloud')); - return false; - } - if (FileList.lastAction) { - FileList.lastAction(); - } - var name = getUniqueName(newname); - if (newname != name) { - FileList.checkName(name, newname, true); - var hidden = true; - } else { - var hidden = false; - } - switch(type){ - case 'file': - $.post( - OC.filePath('files','ajax','newfile.php'), - {dir:$('#dir').val(),filename:name}, - function(result){ - if (result.status == 'success') { - var date=new Date(); - FileList.addFile(name,0,date,false,hidden); - var tr=$('tr').filterAttr('data-file',name); - tr.attr('data-size',result.data.size); - tr.attr('data-mime',result.data.mime); - tr.attr('data-id', result.data.id); - tr.find('.filesize').text(humanFileSize(result.data.size)); - var path = getPathForPreview(name); - lazyLoadPreview(path, result.data.mime, function(previewpath){ - tr.find('td.filename').attr('style','background-image:url('+previewpath+')'); - }); - } else { - OC.dialogs.alert(result.data.message, t('core', 'Error')); + try { + checkInput(); + var newname = input.val(); + if (FileList.lastAction) { + FileList.lastAction(); + } + var name = getUniqueName(newname); + if (newname !== name) { + FileList.checkName(name, newname, true); + var hidden = true; + } else { + var hidden = false; + } + switch(type) { + case 'file': + $.post( + OC.filePath('files', 'ajax', 'newfile.php'), + {dir:$('#dir').val(), filename:name}, + function(result) { + if (result.status === 'success') { + var date = new Date(); + // TODO: ideally addFile should be able to receive + // all attributes and set them automatically, + // and also auto-load the preview + var tr = FileList.addFile(name, 0, date, false, hidden); + tr.attr('data-size', result.data.size); + tr.attr('data-mime', result.data.mime); + tr.attr('data-id', result.data.id); + tr.attr('data-etag', result.data.etag); + tr.find('.filesize').text(humanFileSize(result.data.size)); + var path = getPathForPreview(name); + Files.lazyLoadPreview(path, result.data.mime, function(previewpath) { + tr.find('td.filename').attr('style','background-image:url('+previewpath+')'); + }, null, null, result.data.etag); + FileActions.display(tr.find('td.filename'), true); + } else { + OC.dialogs.alert(result.data.message, t('core', 'Could not create file')); + } } - } - ); - break; - case 'folder': - $.post( - OC.filePath('files','ajax','newfolder.php'), - {dir:$('#dir').val(),foldername:name}, - function(result){ - if (result.status == 'success') { - var date=new Date(); - FileList.addDir(name,0,date,hidden); - var tr=$('tr').filterAttr('data-file',name); - tr.attr('data-id', result.data.id); - } else { - OC.dialogs.alert(result.data.message, t('core', 'Error')); + ); + break; + case 'folder': + $.post( + OC.filePath('files','ajax','newfolder.php'), + {dir:$('#dir').val(), foldername:name}, + function(result) { + if (result.status === 'success') { + var date=new Date(); + FileList.addDir(name, 0, date, hidden); + var tr = FileList.findFileEl(name); + tr.attr('data-id', result.data.id); + } else { + OC.dialogs.alert(result.data.message, t('core', 'Could not create folder')); + } } + ); + break; + case 'web': + if (name.substr(0,8) !== 'https://' && name.substr(0,7) !== 'http://') { + name = 'http://' + name; } - ); - break; - case 'web': - if(name.substr(0,8)!='https://' && name.substr(0,7)!='http://'){ - name='http://'+name; - } - var localName=name; - if(localName.substr(localName.length-1,1)=='/'){//strip / - localName=localName.substr(0,localName.length-1) - } - if(localName.indexOf('/')){//use last part of url - localName=localName.split('/').pop(); - } else { //or the domain - localName=(localName.match(/:\/\/(.[^\/]+)/)[1]).replace('www.',''); - } - localName = getUniqueName(localName); - //IE < 10 does not fire the necessary events for the progress bar. - if($('html.lte9').length === 0) { - $('#uploadprogressbar').progressbar({value:0}); - $('#uploadprogressbar').fadeIn(); - } - - var eventSource=new OC.EventSource(OC.filePath('files','ajax','newfile.php'),{dir:$('#dir').val(),source:name,filename:localName}); - eventSource.listen('progress',function(progress){ + var localName=name; + if (localName.substr(localName.length-1,1)==='/') {//strip / + localName=localName.substr(0,localName.length-1); + } + if (localName.indexOf('/')) {//use last part of url + localName=localName.split('/').pop(); + } else { //or the domain + localName=(localName.match(/:\/\/(.[^\/]+)/)[1]).replace('www.',''); + } + localName = getUniqueName(localName); //IE < 10 does not fire the necessary events for the progress bar. - if($('html.lte9').length === 0) { - $('#uploadprogressbar').progressbar('value',progress); + if ($('html.lte9').length === 0) { + $('#uploadprogressbar').progressbar({value:0}); + $('#uploadprogressbar').fadeIn(); } - }); - eventSource.listen('success',function(data){ - var mime=data.mime; - var size=data.size; - var id=data.id; - $('#uploadprogressbar').fadeOut(); - var date=new Date(); - FileList.addFile(localName,size,date,false,hidden); - var tr=$('tr').filterAttr('data-file',localName); - tr.data('mime',mime).data('id',id); - tr.attr('data-id', id); - var path = $('#dir').val()+'/'+localName; - lazyLoadPreview(path, mime, function(previewpath){ - tr.find('td.filename').attr('style','background-image:url('+previewpath+')'); + + var eventSource=new OC.EventSource(OC.filePath('files','ajax','newfile.php'),{dir:$('#dir').val(),source:name,filename:localName}); + eventSource.listen('progress',function(progress) { + //IE < 10 does not fire the necessary events for the progress bar. + if ($('html.lte9').length === 0) { + $('#uploadprogressbar').progressbar('value',progress); + } }); - }); - eventSource.listen('error',function(error){ - $('#uploadprogressbar').fadeOut(); - alert(error); - }); - break; + eventSource.listen('success',function(data) { + var mime = data.mime; + var size = data.size; + var id = data.id; + $('#uploadprogressbar').fadeOut(); + var date = new Date(); + FileList.addFile(localName, size, date, false, hidden); + var tr = FileList.findFileEl(localName); + tr.data('mime', mime).data('id', id); + tr.attr('data-id', id); + var path = $('#dir').val()+'/'+localName; + Files.lazyLoadPreview(path, mime, function(previewpath) { + tr.find('td.filename').attr('style', 'background-image:url('+previewpath+')'); + }, null, null, data.etag); + FileActions.display(tr.find('td.filename'), true); + }); + eventSource.listen('error',function(error) { + $('#uploadprogressbar').fadeOut(); + var message = (error && error.message) || t('core', 'Error fetching URL'); + OC.Notification.show(message); + //hide notification after 10 sec + setTimeout(function() { + OC.Notification.hide(); + }, 10000); + }); + break; + } + var li=form.parent(); + form.remove(); + /* workaround for IE 9&10 click event trap, 2 lines: */ + $('input').first().focus(); + $('#content').focus(); + li.append('<p>'+li.data('text')+'</p>'); + $('#new>a').click(); + } catch (error) { + input.attr('title', error); + input.tipsy({gravity: 'w', trigger: 'manual'}); + input.tipsy('show'); + input.addClass('error'); } - var li=form.parent(); - form.remove(); - /* workaround for IE 9&10 click event trap, 2 lines: */ - $('input').first().focus(); - $('#content').focus(); - li.append('<p>'+li.data('text')+'</p>'); - $('#new>a').click(); }); }); window.file_upload_param = file_upload_param; diff --git a/apps/files/js/fileactions.js b/apps/files/js/fileactions.js index 67d3d5ead8d..74bb711ef3d 100644 --- a/apps/files/js/fileactions.js +++ b/apps/files/js/fileactions.js @@ -61,11 +61,17 @@ var FileActions = { var actions = this.get(mime, type, permissions); return actions[name]; }, - display: function (parent) { + /** + * Display file actions for the given element + * @param parent "td" element of the file for which to display actions + * @param triggerEvent if true, triggers the fileActionsReady on the file + * list afterwards (false by default) + */ + display: function (parent, triggerEvent) { FileActions.currentFile = parent; var actions = FileActions.get(FileActions.getCurrentMimeType(), FileActions.getCurrentType(), FileActions.getCurrentPermissions()); var file = FileActions.getCurrentFile(); - if ($('tr[data-file="'+file+'"]').data('renaming')) { + if (FileList.findFileEl(file).data('renaming')) { return; } @@ -137,6 +143,10 @@ var FileActions = { element.on('click', {a: null, elem: parent, actionFunc: actions['Delete']}, actionHandler); parent.parent().children().last().append(element); } + + if (triggerEvent){ + $('#fileList').trigger(jQuery.Event("fileActionsReady")); + } }, getCurrentFile: function () { return FileActions.currentFile.parent().attr('data-file'); @@ -177,20 +187,7 @@ $(document).ready(function () { FileActions.register('all', 'Delete', OC.PERMISSION_DELETE, function () { return OC.imagePath('core', 'actions/delete'); }, function (filename) { - if (OC.Upload.cancelUpload($('#dir').val(), filename)) { - if (filename.substr) { - filename = [filename]; - } - $.each(filename, function (index, file) { - var filename = $('tr').filterAttr('data-file', file); - filename.hide(); - filename.find('input[type="checkbox"]').removeAttr('checked'); - filename.removeClass('selected'); - }); - procesSelection(); - } else { - FileList.do_delete(filename); - } + FileList.do_delete(filename); $('.tipsy').remove(); }); diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index 3c99e3876c7..c02ab70ce8d 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -1,30 +1,35 @@ var FileList={ useUndo:true, - postProcessList: function(){ - $('#fileList tr').each(function(){ + postProcessList: function() { + $('#fileList tr').each(function() { //little hack to set unescape filenames in attribute $(this).attr('data-file',decodeURIComponent($(this).attr('data-file'))); }); }, + /** + * Returns the tr element for a given file name + */ + findFileEl: function(fileName){ + // use filterAttr to avoid escaping issues + return $('#fileList tr').filterAttr('data-file', fileName); + }, update:function(fileListHtml) { - var $fileList = $('#fileList'), - permissions = $('#permissions').val(), - isCreatable = (permissions & OC.PERMISSION_CREATE) !== 0; + var $fileList = $('#fileList'); $fileList.empty().html(fileListHtml); - $('#emptycontent').toggleClass('hidden', !isCreatable || $fileList.find('tr').length > 0); + FileList.updateEmptyContent(); $fileList.find('tr').each(function () { FileActions.display($(this).children('td.filename')); }); $fileList.trigger(jQuery.Event("fileActionsReady")); FileList.postProcessList(); // "Files" might not be loaded in extending apps - if (window.Files){ + if (window.Files) { Files.setupDragAndDrop(); } FileList.updateFileSummary(); $fileList.trigger(jQuery.Event("updated")); }, - createRow:function(type, name, iconurl, linktarget, size, lastModified, permissions){ + createRow:function(type, name, iconurl, linktarget, size, lastModified, permissions) { var td, simpleSize, basename, extension; //containing tr var tr = $('<tr></tr>').attr({ @@ -45,7 +50,7 @@ var FileList={ "href": linktarget }); //split extension from filename for non dirs - if (type != 'dir' && name.indexOf('.')!=-1) { + if (type !== 'dir' && name.indexOf('.') !== -1) { basename=name.substr(0,name.lastIndexOf('.')); extension=name.substr(name.lastIndexOf('.')); } else { @@ -54,11 +59,11 @@ var FileList={ } var name_span=$('<span></span>').addClass('nametext').text(basename); link_elem.append(name_span); - if(extension){ + if (extension) { name_span.append($('<span></span>').addClass('extension').text(extension)); } //dirs can show the number of uploaded files - if (type == 'dir') { + if (type === 'dir') { link_elem.append($('<span></span>').attr({ 'class': 'uploadtext', 'currentUploads': 0 @@ -68,9 +73,9 @@ var FileList={ tr.append(td); //size column - if(size!=t('files', 'Pending')){ + if (size !== t('files', 'Pending')) { simpleSize = humanFileSize(size); - }else{ + } else { simpleSize=t('files', 'Pending'); } var sizeColor = Math.round(160-Math.pow((size/(1024*1024)),2)); @@ -92,7 +97,7 @@ var FileList={ tr.append(td); return tr; }, - addFile:function(name,size,lastModified,loading,hidden,param){ + addFile:function(name, size, lastModified, loading, hidden, param) { var imgurl; if (!param) { @@ -122,9 +127,9 @@ var FileList={ ); FileList.insertElement(name, 'file', tr); - if(loading){ - tr.data('loading',true); - }else{ + if (loading) { + tr.data('loading', true); + } else { tr.find('td.filename').draggable(dragOptions); } if (hidden) { @@ -132,7 +137,7 @@ var FileList={ } return tr; }, - addDir:function(name,size,lastModified,hidden){ + addDir:function(name, size, lastModified, hidden) { var tr = this.createRow( 'dir', @@ -144,39 +149,49 @@ var FileList={ $('#permissions').val() ); - FileList.insertElement(name,'dir',tr); + FileList.insertElement(name, 'dir', tr); var td = tr.find('td.filename'); td.draggable(dragOptions); td.droppable(folderDropOptions); if (hidden) { tr.hide(); } - FileActions.display(tr.find('td.filename')); + FileActions.display(tr.find('td.filename'), true); return tr; }, + getCurrentDirectory: function(){ + return $('#dir').val() || '/'; + }, /** * @brief Changes the current directory and reload the file list. * @param targetDir target directory (non URL encoded) * @param changeUrl false if the URL must not be changed (defaults to true) + * @param {boolean} force set to true to force changing directory */ - changeDirectory: function(targetDir, changeUrl, force){ + changeDirectory: function(targetDir, changeUrl, force) { var $dir = $('#dir'), url, currentDir = $dir.val() || '/'; targetDir = targetDir || '/'; - if (!force && currentDir === targetDir){ + if (!force && currentDir === targetDir) { return; } FileList.setCurrentDir(targetDir, changeUrl); + $('#fileList').trigger( + jQuery.Event('changeDirectory', { + dir: targetDir, + previousDir: currentDir + } + )); FileList.reload(); }, - linkTo: function(dir){ + linkTo: function(dir) { return OC.linkTo('files', 'index.php')+"?dir="+ encodeURIComponent(dir).replace(/%2F/g, '/'); }, - setCurrentDir: function(targetDir, changeUrl){ + setCurrentDir: function(targetDir, changeUrl) { $('#dir').val(targetDir); - if (changeUrl !== false){ - if (window.history.pushState && changeUrl !== false){ + if (changeUrl !== false) { + if (window.history.pushState && changeUrl !== false) { url = FileList.linkTo(targetDir); window.history.pushState({dir: targetDir}, '', url); } @@ -189,9 +204,9 @@ var FileList={ /** * @brief Reloads the file list using ajax call */ - reload: function(){ + reload: function() { FileList.showMask(); - if (FileList._reloadCall){ + if (FileList._reloadCall) { FileList._reloadCall.abort(); } FileList._reloadCall = $.ajax({ @@ -200,7 +215,7 @@ var FileList={ dir : $('#dir').val(), breadcrumb: true }, - error: function(result){ + error: function(result) { FileList.reloadCallback(result); }, success: function(result) { @@ -208,7 +223,7 @@ var FileList={ } }); }, - reloadCallback: function(result){ + reloadCallback: function(result) { var $controls = $('#controls'); delete FileList._reloadCall; @@ -219,17 +234,21 @@ var FileList={ return; } - if (result.status === 404){ + if (result.status === 404) { // go back home FileList.changeDirectory('/'); return; } - if (result.data.permissions){ + // TODO: should rather return upload file size through + // the files list ajax call + Files.updateStorageStatistics(true); + + if (result.data.permissions) { FileList.setDirectoryPermissions(result.data.permissions); } - if(typeof(result.data.breadcrumb) != 'undefined'){ + if (typeof(result.data.breadcrumb) !== 'undefined') { $controls.find('.crumb').remove(); $controls.prepend(result.data.breadcrumb); @@ -238,81 +257,114 @@ var FileList={ Files.resizeBreadcrumbs(width, true); // in case svg is not supported by the browser we need to execute the fallback mechanism - if(!SVGSupport()) { + if (!SVGSupport()) { replaceSVG(); } } FileList.update(result.data.files); }, - setDirectoryPermissions: function(permissions){ + setDirectoryPermissions: function(permissions) { var isCreatable = (permissions & OC.PERMISSION_CREATE) !== 0; $('#permissions').val(permissions); $('.creatable').toggleClass('hidden', !isCreatable); $('.notCreatable').toggleClass('hidden', isCreatable); }, + /** + * Shows/hides action buttons + * + * @param show true for enabling, false for disabling + */ + showActions: function(show){ + $('.actions,#file_action_panel').toggleClass('hidden', !show); + if (show){ + // make sure to display according to permissions + var permissions = $('#permissions').val(); + var isCreatable = (permissions & OC.PERMISSION_CREATE) !== 0; + $('.creatable').toggleClass('hidden', !isCreatable); + $('.notCreatable').toggleClass('hidden', isCreatable); + } + else{ + $('.creatable, .notCreatable').addClass('hidden'); + } + }, + /** + * Enables/disables viewer mode. + * In viewer mode, apps can embed themselves under the controls bar. + * In viewer mode, the actions of the file list will be hidden. + * @param show true for enabling, false for disabling + */ + setViewerMode: function(show){ + this.showActions(!show); + $('#filestable').toggleClass('hidden', show); + }, remove:function(name){ - $('tr').filterAttr('data-file',name).find('td.filename').draggable('destroy'); - $('tr').filterAttr('data-file',name).remove(); + var fileEl = FileList.findFileEl(name); + fileEl.find('td.filename').draggable('destroy'); + fileEl.remove(); FileList.updateFileSummary(); - if($('tr[data-file]').length==0){ + if ( ! $('tr[data-file]').exists() ) { $('#emptycontent').removeClass('hidden'); + $('#filescontent th').addClass('hidden'); } }, - insertElement:function(name,type,element){ + insertElement:function(name, type, element) { //find the correct spot to insert the file or folder var pos, fileElements=$('tr[data-file][data-type="'+type+'"]:visible'); - if(name.localeCompare($(fileElements[0]).attr('data-file'))<0){ - pos=-1; - }else if(name.localeCompare($(fileElements[fileElements.length-1]).attr('data-file'))>0){ - pos=fileElements.length-1; - }else{ - for(pos=0;pos<fileElements.length-1;pos++){ - if(name.localeCompare($(fileElements[pos]).attr('data-file'))>0 && name.localeCompare($(fileElements[pos+1]).attr('data-file'))<0){ + if (name.localeCompare($(fileElements[0]).attr('data-file')) < 0) { + pos = -1; + } else if (name.localeCompare($(fileElements[fileElements.length-1]).attr('data-file')) > 0) { + pos = fileElements.length - 1; + } else { + for(pos = 0; pos<fileElements.length-1; pos++) { + if (name.localeCompare($(fileElements[pos]).attr('data-file')) > 0 + && name.localeCompare($(fileElements[pos+1]).attr('data-file')) < 0) + { break; } } } - if(fileElements.length){ - if(pos==-1){ + if (fileElements.exists()) { + if (pos === -1) { $(fileElements[0]).before(element); - }else{ + } else { $(fileElements[pos]).after(element); } - }else if(type=='dir' && $('tr[data-file]').length>0){ + } else if (type === 'dir' && $('tr[data-file]').exists()) { $('tr[data-file]').first().before(element); - } else if(type=='file' && $('tr[data-file]').length>0) { + } else if (type === 'file' && $('tr[data-file]').exists()) { $('tr[data-file]').last().before(element); - }else{ + } else { $('#fileList').append(element); } $('#emptycontent').addClass('hidden'); + $('#filestable th').removeClass('hidden'); FileList.updateFileSummary(); }, - loadingDone:function(name, id){ - var mime, tr=$('tr').filterAttr('data-file',name); - tr.data('loading',false); - mime=tr.data('mime'); - tr.attr('data-mime',mime); - if (id != null) { + loadingDone:function(name, id) { + var mime, tr = FileList.findFileEl(name); + tr.data('loading', false); + mime = tr.data('mime'); + tr.attr('data-mime', mime); + if (id) { tr.attr('data-id', id); } var path = getPathForPreview(name); - lazyLoadPreview(path, mime, function(previewpath){ + Files.lazyLoadPreview(path, mime, function(previewpath) { tr.find('td.filename').attr('style','background-image:url('+previewpath+')'); - }); + }, null, null, tr.attr('data-etag')); tr.find('td.filename').draggable(dragOptions); }, - isLoading:function(name){ - return $('tr').filterAttr('data-file',name).data('loading'); + isLoading:function(file) { + return FileList.findFileEl(file).data('loading'); }, - rename:function(name){ + rename:function(oldname) { var tr, td, input, form; - tr=$('tr').filterAttr('data-file',name); + tr = FileList.findFileEl(oldname); tr.data('renaming',true); - td=tr.children('td.filename'); - input=$('<input type="text" class="filename"/>').val(name); - form=$('<form></form>'); + td = tr.children('td.filename'); + input = $('<input type="text" class="filename"/>').val(oldname); + form = $('<form></form>'); form.append(input); td.children('a.name').hide(); td.append(form); @@ -322,18 +374,29 @@ var FileList={ if (len === -1) { len = input.val().length; } - input.selectRange(0,len); - - form.submit(function(event){ + input.selectRange(0, len); + + var checkInput = function () { + var filename = input.val(); + if (filename !== oldname) { + if (!Files.isFileNameValid(filename)) { + // Files.isFileNameValid(filename) throws an exception itself + } else if($('#dir').val() === '/' && filename === 'Shared') { + throw t('files','In the home folder \'Shared\' is a reserved filename'); + } else if (FileList.inList(filename)) { + throw t('files', '{new_name} already exists', {new_name: filename}); + } + } + return true; + }; + + form.submit(function(event) { event.stopPropagation(); event.preventDefault(); - var newname=input.val(); - if (!Files.isFileNameValid(newname)) { - return false; - } else if (newname != name) { - if (FileList.checkName(name, newname, false)) { - newname = name; - } else { + try { + var newname = input.val(); + if (newname !== oldname) { + checkInput(); // save background image, because it's replaced by a spinner while async request var oldBackgroundImage = td.css('background-image'); // mark as loading @@ -343,16 +406,16 @@ var FileList={ data: { dir : $('#dir').val(), newname: newname, - file: name + file: oldname }, success: function(result) { if (!result || result.status === 'error') { - OC.Notification.show(result.data.message); - newname = name; + OC.dialogs.alert(result.data.message, t('core', 'Could not rename file')); // revert changes + newname = oldname; tr.attr('data-file', newname); var path = td.children('a.name').attr('href'); - td.children('a.name').attr('href', path.replace(encodeURIComponent(name), encodeURIComponent(newname))); + td.children('a.name').attr('href', path.replace(encodeURIComponent(oldname), encodeURIComponent(newname))); if (newname.indexOf('.') > 0 && tr.data('type') !== 'dir') { var basename=newname.substr(0,newname.lastIndexOf('.')); } else { @@ -360,78 +423,101 @@ var FileList={ } td.find('a.name span.nametext').text(basename); if (newname.indexOf('.') > 0 && tr.data('type') !== 'dir') { - if (td.find('a.name span.extension').length === 0 ) { + if ( ! td.find('a.name span.extension').exists() ) { td.find('a.name span.nametext').append('<span class="extension"></span>'); } td.find('a.name span.extension').text(newname.substr(newname.lastIndexOf('.'))); } tr.find('.fileactions').effect('highlight', {}, 5000); tr.effect('highlight', {}, 5000); + // remove loading mark and recover old image + td.css('background-image', oldBackgroundImage); } - // remove loading mark and recover old image - td.css('background-image', oldBackgroundImage); + else { + var fileInfo = result.data; + tr.attr('data-mime', fileInfo.mime); + tr.attr('data-etag', fileInfo.etag); + if (fileInfo.isPreviewAvailable) { + Files.lazyLoadPreview(fileInfo.directory + '/' + fileInfo.name, result.data.mime, function(previewpath) { + tr.find('td.filename').attr('style','background-image:url('+previewpath+')'); + }, null, null, result.data.etag); + } + else { + tr.find('td.filename').removeClass('preview').attr('style','background-image:url('+fileInfo.icon+')'); + } + } + // reinsert row + tr.detach(); + FileList.insertElement( tr.attr('data-file'), tr.attr('data-type'),tr ); + // update file actions in case the extension changed + FileActions.display( tr.find('td.filename'), true); } }); } - } - tr.data('renaming',false); - tr.attr('data-file', newname); - var path = td.children('a.name').attr('href'); - td.children('a.name').attr('href', path.replace(encodeURIComponent(name), encodeURIComponent(newname))); - if (newname.indexOf('.') > 0 && tr.data('type') != 'dir') { - var basename=newname.substr(0,newname.lastIndexOf('.')); - } else { - var basename=newname; - } - td.find('a.name span.nametext').text(basename); - if (newname.indexOf('.') > 0 && tr.data('type') != 'dir') { - if (td.find('a.name span.extension').length == 0 ) { - td.find('a.name span.nametext').append('<span class="extension"></span>'); + input.tipsy('hide'); + tr.data('renaming',false); + tr.attr('data-file', newname); + var path = td.children('a.name').attr('href'); + // FIXME this will fail if the path contains the filename. + td.children('a.name').attr('href', path.replace(encodeURIComponent(oldname), encodeURIComponent(newname))); + var basename = newname; + if (newname.indexOf('.') > 0 && tr.data('type') !== 'dir') { + basename = newname.substr(0, newname.lastIndexOf('.')); + } + td.find('a.name span.nametext').text(basename); + if (newname.indexOf('.') > 0 && tr.data('type') !== 'dir') { + if ( ! td.find('a.name span.extension').exists() ) { + td.find('a.name span.nametext').append('<span class="extension"></span>'); + } + td.find('a.name span.extension').text(newname.substr(newname.lastIndexOf('.'))); } - td.find('a.name span.extension').text(newname.substr(newname.lastIndexOf('.'))); + form.remove(); + td.children('a.name').show(); + } catch (error) { + input.attr('title', error); + input.tipsy({gravity: 'w', trigger: 'manual'}); + input.tipsy('show'); + input.addClass('error'); } - form.remove(); - td.children('a.name').show(); return false; }); - input.keyup(function(event){ - if (event.keyCode == 27) { + input.keyup(function(event) { + // verify filename on typing + try { + checkInput(); + input.tipsy('hide'); + input.removeClass('error'); + } catch (error) { + input.attr('title', error); + input.tipsy({gravity: 'w', trigger: 'manual'}); + input.tipsy('show'); + input.addClass('error'); + } + if (event.keyCode === 27) { + input.tipsy('hide'); tr.data('renaming',false); form.remove(); td.children('a.name').show(); } }); - input.click(function(event){ + input.click(function(event) { event.stopPropagation(); event.preventDefault(); }); - input.blur(function(){ + input.blur(function() { form.trigger('submit'); }); }, - checkName:function(oldName, newName, isNewFile) { - if (isNewFile || $('tr').filterAttr('data-file', newName).length > 0) { - var html; - if(isNewFile){ - html = t('files', '{new_name} already exists', {new_name: escapeHTML(newName)})+'<span class="replace">'+t('files', 'replace')+'</span><span class="suggest">'+t('files', 'suggest name')+'</span> <span class="cancel">'+t('files', 'cancel')+'</span>'; - }else{ - html = t('files', '{new_name} already exists', {new_name: escapeHTML(newName)})+'<span class="replace">'+t('files', 'replace')+'</span><span class="cancel">'+t('files', 'cancel')+'</span>'; - } - html = $('<span>' + html + '</span>'); - html.attr('data-oldName', oldName); - html.attr('data-newName', newName); - html.attr('data-isNewFile', isNewFile); - OC.Notification.showHtml(html); - return true; - } else { - return false; - } + inList:function(file) { + return FileList.findFileEl(file).length; }, replace:function(oldName, newName, isNewFile) { // Finish any existing actions - $('tr').filterAttr('data-file', oldName).hide(); - $('tr').filterAttr('data-file', newName).hide(); - var tr = $('tr').filterAttr('data-file', oldName).clone(); + var oldFileEl = FileList.findFileEl(oldName); + var newFileEl = FileList.findFileEl(newName); + oldFileEl.hide(); + newFileEl.hide(); + var tr = oldFileEl.clone(); tr.attr('data-replace', 'true'); tr.attr('data-file', newName); var td = tr.children('td.filename'); @@ -460,14 +546,14 @@ var FileList={ FileList.finishReplace(); }; if (!isNewFile) { - OC.Notification.showHtml(t('files', 'replaced {new_name} with {old_name}', {new_name: newName}, {old_name: oldName})+'<span class="undo">'+t('files', 'undo')+'</span>'); + OC.Notification.showHtml(t('files', 'replaced {new_name} with {old_name}', {new_name: newName}, {old_name: oldName})+'<span class="undo">'+t('files', 'undo')+'</span>'); } }, finishReplace:function() { if (!FileList.replaceCanceled && FileList.replaceOldName && FileList.replaceNewName) { $.ajax({url: OC.filePath('files', 'ajax', 'rename.php'), async: false, data: { dir: $('#dir').val(), newname: FileList.replaceNewName, file: FileList.replaceOldName }, success: function(result) { - if (result && result.status == 'success') { - $('tr').filterAttr('data-replace', 'true').removeAttr('data-replace'); + if (result && result.status === 'success') { + $('tr[data-replace="true"').removeAttr('data-replace'); } else { OC.dialogs.alert(result.data.message, 'Error moving file'); } @@ -478,12 +564,12 @@ var FileList={ }}); } }, - do_delete:function(files){ - if(files.substr){ + do_delete:function(files) { + if (files.substr) { files=[files]; } for (var i=0; i<files.length; i++) { - var deleteAction = $('tr').filterAttr('data-file',files[i]).children("td.date").children(".action.delete"); + var deleteAction = FileList.findFileEl(files[i]).children("td.date").children(".action.delete"); deleteAction.removeClass('delete-icon').addClass('progress-icon'); } // Finish any existing actions @@ -494,10 +580,10 @@ var FileList={ var fileNames = JSON.stringify(files); $.post(OC.filePath('files', 'ajax', 'delete.php'), {dir:$('#dir').val(),files:fileNames}, - function(result){ - if (result.status == 'success') { - $.each(files,function(index,file){ - var files = $('tr').filterAttr('data-file',file); + function(result) { + if (result.status === 'success') { + $.each(files,function(index,file) { + var files = FileList.findFileEl(file); files.remove(); files.find('input[type="checkbox"]').removeAttr('checked'); files.removeClass('selected'); @@ -505,65 +591,86 @@ var FileList={ procesSelection(); checkTrashStatus(); FileList.updateFileSummary(); + FileList.updateEmptyContent(); + Files.updateStorageStatistics(); } else { + if (result.status === 'error' && result.data.message) { + OC.Notification.show(result.data.message); + } + else { + OC.Notification.show(t('files', 'Error deleting file.')); + } + // hide notification after 10 sec + setTimeout(function() { + OC.Notification.hide(); + }, 10000); $.each(files,function(index,file) { - var deleteAction = $('tr').filterAttr('data-file',files[i]).children("td.date").children(".action.delete"); + var deleteAction = FileList.findFileEl(file).find('.action.delete'); deleteAction.removeClass('progress-icon').addClass('delete-icon'); }); } }); }, createFileSummary: function() { - if( $('#fileList tr').length > 0 ) { - var totalDirs = 0; - var totalFiles = 0; - var totalSize = 0; - - // Count types and filesize - $.each($('tr[data-file]'), function(index, value) { - if ($(value).data('type') === 'dir') { - totalDirs++; - } else if ($(value).data('type') === 'file') { - totalFiles++; - } - totalSize += parseInt($(value).data('size')); - }); + if( $('#fileList tr').exists() ) { + var summary = this._calculateFileSummary(); // Get translations - var directoryInfo = n('files', '%n folder', '%n folders', totalDirs); - var fileInfo = n('files', '%n file', '%n files', totalFiles); + var directoryInfo = n('files', '%n folder', '%n folders', summary.totalDirs); + var fileInfo = n('files', '%n file', '%n files', summary.totalFiles); var infoVars = { dirs: '<span class="dirinfo">'+directoryInfo+'</span><span class="connector">', files: '</span><span class="fileinfo">'+fileInfo+'</span>' - } + }; var info = t('files', '{dirs} and {files}', infoVars); // don't show the filesize column, if filesize is NaN (e.g. in trashbin) - if (isNaN(totalSize)) { + if (isNaN(summary.totalSize)) { var fileSize = ''; } else { - var fileSize = '<td class="filesize">'+humanFileSize(totalSize)+'</td>'; + var fileSize = '<td class="filesize">'+humanFileSize(summary.totalSize)+'</td>'; } - $('#fileList').append('<tr class="summary"><td><span class="info">'+info+'</span></td>'+fileSize+'<td></td></tr>'); + var $summary = $('<tr class="summary" data-file="undefined"><td><span class="info">'+info+'</span></td>'+fileSize+'<td></td></tr>'); + $('#fileList').append($summary); - var $dirInfo = $('.summary .dirinfo'); - var $fileInfo = $('.summary .fileinfo'); - var $connector = $('.summary .connector'); + var $dirInfo = $summary.find('.dirinfo'); + var $fileInfo = $summary.find('.fileinfo'); + var $connector = $summary.find('.connector'); // Show only what's necessary, e.g.: no files: don't show "0 files" - if ($dirInfo.html().charAt(0) === "0") { + if (summary.totalDirs === 0) { $dirInfo.hide(); $connector.hide(); } - if ($fileInfo.html().charAt(0) === "0") { + if (summary.totalFiles === 0) { $fileInfo.hide(); $connector.hide(); } } }, + _calculateFileSummary: function() { + var result = { + totalDirs: 0, + totalFiles: 0, + totalSize: 0 + }; + $.each($('tr[data-file]'), function(index, value) { + var $value = $(value); + if ($value.data('type') === 'dir') { + result.totalDirs++; + } else if ($value.data('type') === 'file') { + result.totalFiles++; + } + if ($value.data('size') !== undefined && $value.data('id') !== -1) { + //Skip shared as it does not count toward quota + result.totalSize += parseInt($value.data('size')); + } + }); + return result; + }, updateFileSummary: function() { var $summary = $('.summary'); @@ -577,51 +684,46 @@ var FileList={ } // There's a summary and data -> Update the summary else if ($('#fileList tr').length > 1 && $summary.length === 1) { - var totalDirs = 0; - var totalFiles = 0; - var totalSize = 0; - $.each($('tr[data-file]'), function(index, value) { - if ($(value).data('type') === 'dir') { - totalDirs++; - } else if ($(value).data('type') === 'file') { - totalFiles++; - } - if ($(value).data('size') !== undefined) { - totalSize += parseInt($(value).data('size')); - } - }); - + var fileSummary = this._calculateFileSummary(); var $dirInfo = $('.summary .dirinfo'); var $fileInfo = $('.summary .fileinfo'); var $connector = $('.summary .connector'); // Substitute old content with new translations - $dirInfo.html(n('files', '%n folder', '%n folders', totalDirs)); - $fileInfo.html(n('files', '%n file', '%n files', totalFiles)); - $('.summary .filesize').html(humanFileSize(totalSize)); + $dirInfo.html(n('files', '%n folder', '%n folders', fileSummary.totalDirs)); + $fileInfo.html(n('files', '%n file', '%n files', fileSummary.totalFiles)); + $('.summary .filesize').html(humanFileSize(fileSummary.totalSize)); // Show only what's necessary (may be hidden) - if ($dirInfo.html().charAt(0) === "0") { + if (fileSummary.totalDirs === 0) { $dirInfo.hide(); $connector.hide(); } else { $dirInfo.show(); } - if ($fileInfo.html().charAt(0) === "0") { + if (fileSummary.totalFiles === 0) { $fileInfo.hide(); $connector.hide(); } else { $fileInfo.show(); } - if ($dirInfo.html().charAt(0) !== "0" && $fileInfo.html().charAt(0) !== "0") { + if (fileSummary.totalDirs > 0 && fileSummary.totalFiles > 0) { $connector.show(); } } }, - showMask: function(){ + updateEmptyContent: function() { + var $fileList = $('#fileList'); + var permissions = $('#permissions').val(); + var isCreatable = (permissions & OC.PERMISSION_CREATE) !== 0; + var exists = $fileList.find('tr:first').exists(); + $('#emptycontent').toggleClass('hidden', !isCreatable || exists); + $('#filestable th').toggleClass('hidden', !exists); + }, + showMask: function() { // in case one was shown before var $mask = $('#content .mask'); - if ($mask.length){ + if ($mask.exists()) { return; } @@ -632,32 +734,32 @@ var FileList={ $('#content').append($mask); // block UI, but only make visible in case loading takes longer - FileList._maskTimeout = window.setTimeout(function(){ + FileList._maskTimeout = window.setTimeout(function() { // reset opacity $mask.removeClass('transparent'); }, 250); }, - hideMask: function(){ + hideMask: function() { var $mask = $('#content .mask').remove(); - if (FileList._maskTimeout){ + if (FileList._maskTimeout) { window.clearTimeout(FileList._maskTimeout); } }, scrollTo:function(file) { //scroll to and highlight preselected file - var scrolltorow = $('tr[data-file="'+file+'"]'); - if (scrolltorow.length > 0) { - scrolltorow.addClass('searchresult'); - $(window).scrollTop(scrolltorow.position().top); + var $scrolltorow = FileList.findFileEl(file); + if ($scrolltorow.exists()) { + $scrolltorow.addClass('searchresult'); + $(window).scrollTop($scrolltorow.position().top); //remove highlight when hovered over - scrolltorow.one('hover', function(){ - scrolltorow.removeClass('searchresult'); + $scrolltorow.one('hover', function() { + $scrolltorow.removeClass('searchresult'); }); } }, - filter:function(query){ - $('#fileList tr:not(.summary)').each(function(i,e){ - if ($(e).data('file').toLowerCase().indexOf(query.toLowerCase()) !== -1) { + filter:function(query) { + $('#fileList tr:not(.summary)').each(function(i,e) { + if ($(e).data('file').toString().toLowerCase().indexOf(query.toLowerCase()) !== -1) { $(e).addClass("searchresult"); } else { $(e).removeClass("searchresult"); @@ -665,18 +767,19 @@ var FileList={ }); //do not use scrollto to prevent removing searchresult css class var first = $('#fileList tr.searchresult').first(); - if (first.length !== 0) { + if (first.exists()) { $(window).scrollTop(first.position().top); } }, - unfilter:function(){ - $('#fileList tr.searchresult').each(function(i,e){ + unfilter:function() { + $('#fileList tr.searchresult').each(function(i,e) { $(e).removeClass("searchresult"); }); } }; -$(document).ready(function(){ +$(document).ready(function() { + var isPublic = !!$('#isPublic').val(); // handle upload events var file_upload_start = $('#file_upload_start'); @@ -684,28 +787,32 @@ $(document).ready(function(){ file_upload_start.on('fileuploaddrop', function(e, data) { OC.Upload.log('filelist handle fileuploaddrop', e, data); - var dropTarget = $(e.originalEvent.target).closest('tr'); - if(dropTarget && dropTarget.data('type') === 'dir') { // drag&drop upload to folder + var dropTarget = $(e.originalEvent.target).closest('tr, .crumb'); + if (dropTarget && (dropTarget.data('type') === 'dir' || dropTarget.hasClass('crumb'))) { // drag&drop upload to folder // remember as context data.context = dropTarget; var dir = dropTarget.data('file'); + // if from file list, need to prepend parent dir + if (dir) { + var parentDir = $('#dir').val() || '/'; + if (parentDir[parentDir.length - 1] !== '/') { + parentDir += '/'; + } + dir = parentDir + dir; + } + else{ + // read full path from crumb + dir = dropTarget.data('dir') || '/'; + } // update folder in form data.formData = function(form) { - var formArray = form.serializeArray(); - // array index 0 contains the max files size - // array index 1 contains the request token - // array index 2 contains the directory - var parentDir = formArray[2]['value']; - if (parentDir === '/') { - formArray[2]['value'] += dir; - } else { - formArray[2]['value'] += '/' + dir; - } - - return formArray; + return [ + {name: 'dir', value: dir}, + {name: 'requesttoken', value: oc_requesttoken} + ]; }; } @@ -714,12 +821,12 @@ $(document).ready(function(){ OC.Upload.log('filelist handle fileuploadadd', e, data); //finish delete if we are uploading a deleted file - if(FileList.deleteFiles && FileList.deleteFiles.indexOf(data.files[0].name)!==-1){ + if (FileList.deleteFiles && FileList.deleteFiles.indexOf(data.files[0].name)!==-1) { FileList.finishDelete(null, true); //delete file before continuing } // add ui visualization to existing folder - if(data.context && data.context.data('type') === 'dir') { + if (data.context && data.context.data('type') === 'dir') { // add to existing folder // update upload counter ui @@ -729,7 +836,7 @@ $(document).ready(function(){ uploadtext.attr('currentUploads', currentUploads); var translatedText = n('files', 'Uploading %n file', 'Uploading %n files', currentUploads); - if(currentUploads === 1) { + if (currentUploads === 1) { var img = OC.imagePath('core', 'loading.gif'); data.context.find('td.filename').attr('style','background-image:url('+img+')'); uploadtext.text(translatedText); @@ -756,7 +863,7 @@ $(document).ready(function(){ } var result=$.parseJSON(response); - if(typeof result[0] !== 'undefined' && result[0].status === 'success') { + if (typeof result[0] !== 'undefined' && result[0].status === 'success') { var file = result[0]; if (data.context && data.context.data('type') === 'dir') { @@ -767,7 +874,7 @@ $(document).ready(function(){ currentUploads -= 1; uploadtext.attr('currentUploads', currentUploads); var translatedText = n('files', 'Uploading %n file', 'Uploading %n files', currentUploads); - if(currentUploads === 0) { + if (currentUploads === 0) { var img = OC.imagePath('core', 'filetypes/folder.png'); data.context.find('td.filename').attr('style','background-image:url('+img+')'); uploadtext.text(translatedText); @@ -783,15 +890,19 @@ $(document).ready(function(){ data.context.find('td.filesize').text(humanFileSize(size)); } else { + // only append new file if dragged onto current dir's crumb (last) + if (data.context && data.context.hasClass('crumb') && !data.context.hasClass('last')) { + return; + } // add as stand-alone row to filelist var size=t('files', 'Pending'); - if (data.files[0].size>=0){ + if (data.files[0].size>=0) { size=data.files[0].size; } var date=new Date(); var param = {}; - if ($('#publicUploadRequestToken').length) { + if ($('#publicUploadRequestToken').exists()) { param.download_url = document.location.href + '&download&path=/' + $('#dir').val() + '/' + file.name; } //should the file exist in the list remove it @@ -801,19 +912,19 @@ $(document).ready(function(){ data.context = FileList.addFile(file.name, file.size, date, false, false, param); // update file data - data.context.attr('data-mime',file.mime).attr('data-id',file.id); + data.context.attr('data-mime',file.mime).attr('data-id',file.id).attr('data-etag', file.etag); var permissions = data.context.data('permissions'); - if(permissions != file.permissions) { + if (permissions !== file.permissions) { data.context.attr('data-permissions', file.permissions); data.context.data('permissions', file.permissions); } - FileActions.display(data.context.find('td.filename')); + FileActions.display(data.context.find('td.filename'), true); var path = getPathForPreview(file.name); - lazyLoadPreview(path, file.mime, function(previewpath){ + Files.lazyLoadPreview(path, file.mime, function(previewpath) { data.context.find('td.filename').attr('style','background-image:url('+previewpath+')'); - }); + }, null, null, file.etag); } } }); @@ -845,10 +956,10 @@ $(document).ready(function(){ }); $('#notification').hide(); - $('#notification').on('click', '.undo', function(){ + $('#notification').on('click', '.undo', function() { if (FileList.deleteFiles) { - $.each(FileList.deleteFiles,function(index,file){ - $('tr').filterAttr('data-file',file).show(); + $.each(FileList.deleteFiles,function(index,file) { + FileList.findFileEl(file).show(); }); FileList.deleteCanceled=true; FileList.deleteFiles=null; @@ -858,10 +969,10 @@ $(document).ready(function(){ FileList.deleteCanceled = false; FileList.deleteFiles = [FileList.replaceOldName]; } else { - $('tr').filterAttr('data-file', FileList.replaceOldName).show(); + FileList.findFileEl(FileList.replaceOldName).show(); } - $('tr').filterAttr('data-replace', 'true').remove(); - $('tr').filterAttr('data-file', FileList.replaceNewName).show(); + $('tr[data-replace="true"').remove(); + FileList.findFileEl(FileList.replaceNewName).show(); FileList.replaceCanceled = true; FileList.replaceOldName = null; FileList.replaceNewName = null; @@ -876,7 +987,8 @@ $(document).ready(function(){ }); }); $('#notification:first-child').on('click', '.suggest', function() { - $('tr').filterAttr('data-file', $('#notification > span').attr('data-oldName')).show(); + var file = $('#notification > span').attr('data-oldName'); + FileList.findFileEl(file).show(); OC.Notification.hide(); }); $('#notification:first-child').on('click', '.cancel', function() { @@ -886,67 +998,70 @@ $(document).ready(function(){ } }); FileList.useUndo=(window.onbeforeunload)?true:false; - $(window).bind('beforeunload', function (){ + $(window).bind('beforeunload', function () { if (FileList.lastAction) { FileList.lastAction(); } }); - $(window).unload(function (){ + $(window).unload(function () { $(window).trigger('beforeunload'); }); - function decodeQuery(query){ + function decodeQuery(query) { return query.replace(/\+/g, ' '); } - function parseHashQuery(){ + function parseHashQuery() { var hash = window.location.hash, pos = hash.indexOf('?'), query; - if (pos >= 0){ + if (pos >= 0) { return hash.substr(pos + 1); } return ''; } - function parseCurrentDirFromUrl(){ + function parseCurrentDirFromUrl() { var query = parseHashQuery(), params, dir = '/'; // try and parse from URL hash first - if (query){ + if (query) { params = OC.parseQueryString(decodeQuery(query)); } // else read from query attributes - if (!params){ + if (!params) { params = OC.parseQueryString(decodeQuery(location.search)); } return (params && params.dir) || '/'; } - // fallback to hashchange when no history support - if (!window.history.pushState){ - $(window).on('hashchange', function(){ - FileList.changeDirectory(parseCurrentDirFromUrl(), false); - }); - } - window.onpopstate = function(e){ - var targetDir; - if (e.state && e.state.dir){ - targetDir = e.state.dir; - } - else{ - // read from URL - targetDir = parseCurrentDirFromUrl(); - } - if (targetDir){ - FileList.changeDirectory(targetDir, false); + // disable ajax/history API for public app (TODO: until it gets ported) + if (!isPublic) { + // fallback to hashchange when no history support + if (!window.history.pushState) { + $(window).on('hashchange', function() { + FileList.changeDirectory(parseCurrentDirFromUrl(), false); + }); } - } + window.onpopstate = function(e) { + var targetDir; + if (e.state && e.state.dir) { + targetDir = e.state.dir; + } + else{ + // read from URL + targetDir = parseCurrentDirFromUrl(); + } + if (targetDir) { + FileList.changeDirectory(targetDir, false); + } + }; - if (parseInt($('#ajaxLoad').val(), 10) === 1){ - // need to initially switch the dir to the one from the hash (IE8) - FileList.changeDirectory(parseCurrentDirFromUrl(), false, true); + if (parseInt($('#ajaxLoad').val(), 10) === 1) { + // need to initially switch the dir to the one from the hash (IE8) + FileList.changeDirectory(parseCurrentDirFromUrl(), false, true); + } } FileList.createFileSummary(); diff --git a/apps/files/js/files.js b/apps/files/js/files.js index 899bc6469e5..1f12ade8d79 100644 --- a/apps/files/js/files.js +++ b/apps/files/js/files.js @@ -1,18 +1,54 @@ Files={ + // file space size sync + _updateStorageStatistics: function() { + Files._updateStorageStatisticsTimeout = null; + var currentDir = FileList.getCurrentDirectory(), + state = Files.updateStorageStatistics; + if (state.dir){ + if (state.dir === currentDir) { + return; + } + // cancel previous call, as it was for another dir + state.call.abort(); + } + state.dir = currentDir; + state.call = $.getJSON(OC.filePath('files','ajax','getstoragestats.php') + '?dir=' + encodeURIComponent(currentDir),function(response) { + state.dir = null; + state.call = null; + Files.updateMaxUploadFilesize(response); + }); + }, + updateStorageStatistics: function(force) { + if (!OC.currentUser) { + return; + } + + // debounce to prevent calling too often + if (Files._updateStorageStatisticsTimeout) { + clearTimeout(Files._updateStorageStatisticsTimeout); + } + if (force) { + Files._updateStorageStatistics(); + } + else { + Files._updateStorageStatisticsTimeout = setTimeout(Files._updateStorageStatistics, 250); + } + }, + updateMaxUploadFilesize:function(response) { - if(response == undefined) { + if (response === undefined) { return; } - if(response.data !== undefined && response.data.uploadMaxFilesize !== undefined) { + if (response.data !== undefined && response.data.uploadMaxFilesize !== undefined) { $('#max_upload').val(response.data.uploadMaxFilesize); $('#upload.button').attr('original-title', response.data.maxHumanFilesize); $('#usedSpacePercent').val(response.data.usedSpacePercent); Files.displayStorageWarnings(); } - if(response[0] == undefined) { + if (response[0] === undefined) { return; } - if(response[0].uploadMaxFilesize !== undefined) { + if (response[0].uploadMaxFilesize !== undefined) { $('#max_upload').val(response[0].uploadMaxFilesize); $('#upload.button').attr('original-title', response[0].maxHumanFilesize); $('#usedSpacePercent').val(response[0].usedSpacePercent); @@ -20,25 +56,31 @@ Files={ } }, + + /** + * Fix path name by removing double slash at the beginning, if any + */ + fixPath: function(fileName) { + if (fileName.substr(0, 2) == '//') { + return fileName.substr(1); + } + return fileName; + }, + isFileNameValid:function (name) { if (name === '.') { - OC.Notification.show(t('files', '\'.\' is an invalid file name.')); - return false; - } - if (name.length == 0) { - OC.Notification.show(t('files', 'File name cannot be empty.')); - return false; + throw t('files', '\'.\' is an invalid file name.'); + } else if (name.length === 0) { + throw t('files', 'File name cannot be empty.'); } // check for invalid characters var invalid_characters = ['\\', '/', '<', '>', ':', '"', '|', '?', '*']; for (var i = 0; i < invalid_characters.length; i++) { - if (name.indexOf(invalid_characters[i]) != -1) { - OC.Notification.show(t('files', "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed.")); - return false; + if (name.indexOf(invalid_characters[i]) !== -1) { + throw t('files', "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed."); } } - OC.Notification.hide(); return true; }, displayStorageWarnings: function() { @@ -78,18 +120,18 @@ Files={ } }, - setupDragAndDrop: function(){ + setupDragAndDrop: function() { var $fileList = $('#fileList'); //drag/drop of files - $fileList.find('tr td.filename').each(function(i,e){ + $fileList.find('tr td.filename').each(function(i,e) { if ($(e).parent().data('permissions') & OC.PERMISSION_DELETE) { $(e).draggable(dragOptions); } }); - $fileList.find('tr[data-type="dir"] td.filename').each(function(i,e){ - if ($(e).parent().data('permissions') & OC.PERMISSION_CREATE){ + $fileList.find('tr[data-type="dir"] td.filename').each(function(i,e) { + if ($(e).parent().data('permissions') & OC.PERMISSION_CREATE) { $(e).droppable(folderDropOptions); } }); @@ -98,6 +140,8 @@ Files={ lastWidth: 0, initBreadCrumbs: function () { + var $controls = $('#controls'); + Files.lastWidth = 0; Files.breadcrumbs = []; @@ -118,13 +162,16 @@ Files={ }); // event handlers for breadcrumb items - $('#controls .crumb a').on('click', onClickBreadcrumb); + $controls.find('.crumb a').on('click', onClickBreadcrumb); + + // setup drag and drop + $controls.find('.crumb:not(.last)').droppable(crumbDropOptions); }, resizeBreadcrumbs: function (width, firstRun) { - if (width != Files.lastWidth) { + if (width !== Files.lastWidth) { if ((width < Files.lastWidth || firstRun) && width < Files.breadcrumbsWidth) { - if (Files.hiddenBreadcrumbs == 0) { + if (Files.hiddenBreadcrumbs === 0) { Files.breadcrumbsWidth -= $(Files.breadcrumbs[1]).get(0).offsetWidth; $(Files.breadcrumbs[1]).find('a').hide(); $(Files.breadcrumbs[1]).append('<span>...</span>'); @@ -136,12 +183,12 @@ Files={ Files.breadcrumbsWidth -= $(Files.breadcrumbs[i]).get(0).offsetWidth; $(Files.breadcrumbs[i]).hide(); Files.hiddenBreadcrumbs = i; - i++ + i++; } } else if (width > Files.lastWidth && Files.hiddenBreadcrumbs > 0) { var i = Files.hiddenBreadcrumbs; while (width > Files.breadcrumbsWidth && i > 0) { - if (Files.hiddenBreadcrumbs == 1) { + if (Files.hiddenBreadcrumbs === 1) { Files.breadcrumbsWidth -= $(Files.breadcrumbs[1]).get(0).offsetWidth; $(Files.breadcrumbs[1]).find('span').remove(); $(Files.breadcrumbs[1]).find('a').show(); @@ -165,7 +212,7 @@ Files={ }; $(document).ready(function() { // FIXME: workaround for trashbin app - if (window.trashBinApp){ + if (window.trashBinApp) { return; } Files.displayEncryptionWarning(); @@ -176,11 +223,8 @@ $(document).ready(function() { $('#file_action_panel').attr('activeAction', false); - $('div.crumb:not(.last)').droppable(crumbDropOptions); - $('ul#apps>li:first-child').data('dir',''); - if($('div.crumb').length){ - $('ul#apps>li:first-child').droppable(crumbDropOptions); - } + // allow dropping on the "files" app icon + $('ul#apps li:first-child').data('dir','').droppable(crumbDropOptions); // Triggers invisible file input $('#upload a').on('click', function() { @@ -213,7 +257,7 @@ $(document).ready(function() { var rows = $(this).parent().parent().parent().children('tr'); for (var i = start; i < end; i++) { $(rows).each(function(index) { - if (index == i) { + if (index === i) { var checkbox = $(this).children().children('input:checkbox'); $(checkbox).attr('checked', 'checked'); $(checkbox).parent().parent().addClass('selected'); @@ -230,23 +274,23 @@ $(document).ready(function() { } else { $(checkbox).attr('checked', 'checked'); $(checkbox).parent().parent().toggleClass('selected'); - var selectedCount=$('td.filename input:checkbox:checked').length; - if (selectedCount == $('td.filename input:checkbox').length) { + var selectedCount = $('td.filename input:checkbox:checked').length; + if (selectedCount === $('td.filename input:checkbox').length) { $('#select_all').attr('checked', 'checked'); } } procesSelection(); } else { var filename=$(this).parent().parent().attr('data-file'); - var tr=$('tr').filterAttr('data-file',filename); + var tr = FileList.findFileEl(filename); var renaming=tr.data('renaming'); - if(!renaming && !FileList.isLoading(filename)){ + if (!renaming && !FileList.isLoading(filename)) { FileActions.currentFile = $(this).parent(); var mime=FileActions.getCurrentMimeType(); var type=FileActions.getCurrentType(); var permissions = FileActions.getCurrentPermissions(); var action=FileActions.getDefault(mime,type, permissions); - if(action){ + if (action) { event.preventDefault(); action(filename); } @@ -257,11 +301,11 @@ $(document).ready(function() { // Sets the select_all checkbox behaviour : $('#select_all').click(function() { - if($(this).attr('checked')){ + if ($(this).attr('checked')) { // Check all $('td.filename input:checkbox').attr('checked', true); $('td.filename input:checkbox').parent().parent().addClass('selected'); - }else{ + } else { // Uncheck all $('td.filename input:checkbox').attr('checked', false); $('td.filename input:checkbox').parent().parent().removeClass('selected'); @@ -278,7 +322,7 @@ $(document).ready(function() { var rows = $(this).parent().parent().parent().children('tr'); for (var i = start; i < end; i++) { $(rows).each(function(index) { - if (index == i) { + if (index === i) { var checkbox = $(this).children().children('input:checkbox'); $(checkbox).attr('checked', 'checked'); $(checkbox).parent().parent().addClass('selected'); @@ -288,10 +332,10 @@ $(document).ready(function() { } var selectedCount=$('td.filename input:checkbox:checked').length; $(this).parent().parent().toggleClass('selected'); - if(!$(this).attr('checked')){ + if (!$(this).attr('checked')) { $('#select_all').attr('checked',false); - }else{ - if(selectedCount==$('td.filename input:checkbox').length){ + } else { + if (selectedCount===$('td.filename input:checkbox').length) { $('#select_all').attr('checked',true); } } @@ -299,21 +343,22 @@ $(document).ready(function() { }); $('.download').click('click',function(event) { - var files=getSelectedFiles('name'); + var files=getSelectedFilesTrash('name'); var fileslist = JSON.stringify(files); var dir=$('#dir').val()||'/'; OC.Notification.show(t('files','Your download is being prepared. This might take some time if the files are big.')); // use special download URL if provided, e.g. for public shared files - if ( (downloadURL = document.getElementById("downloadURL")) ) { - window.location=downloadURL.value+"&download&files="+encodeURIComponent(fileslist); + var downloadURL = document.getElementById("downloadURL"); + if ( downloadURL ) { + window.location = downloadURL.value+"&download&files=" + encodeURIComponent(fileslist); } else { - window.location=OC.filePath('files', 'ajax', 'download.php') + '?'+ $.param({ dir: dir, files: fileslist }); + window.location = OC.filePath('files', 'ajax', 'download.php') + '?'+ $.param({ dir: dir, files: fileslist }); } return false; }); $('.delete-selected').click(function(event) { - var files=getSelectedFiles('name'); + var files=getSelectedFilesTrash('name'); event.preventDefault(); FileList.do_delete(files); return false; @@ -342,44 +387,40 @@ $(document).ready(function() { setTimeout ( "Files.displayStorageWarnings()", 100 ); OC.Notification.setDefault(Files.displayStorageWarnings); - // file space size sync - function update_storage_statistics() { - $.getJSON(OC.filePath('files','ajax','getstoragestats.php'),function(response) { - Files.updateMaxUploadFilesize(response); - }); - } - - // start on load - we ask the server every 5 minutes - var update_storage_statistics_interval = 5*60*1000; - var update_storage_statistics_interval_id = setInterval(update_storage_statistics, update_storage_statistics_interval); - - // Use jquery-visibility to de-/re-activate file stats sync - if ($.support.pageVisibility) { - $(document).on({ - 'show.visibility': function() { - if (!update_storage_statistics_interval_id) { - update_storage_statistics_interval_id = setInterval(update_storage_statistics, update_storage_statistics_interval); + // only possible at the moment if user is logged in + if (OC.currentUser) { + // start on load - we ask the server every 5 minutes + var updateStorageStatisticsInterval = 5*60*1000; + var updateStorageStatisticsIntervalId = setInterval(Files.updateStorageStatistics, updateStorageStatisticsInterval); + + // Use jquery-visibility to de-/re-activate file stats sync + if ($.support.pageVisibility) { + $(document).on({ + 'show.visibility': function() { + if (!updateStorageStatisticsIntervalId) { + updateStorageStatisticsIntervalId = setInterval(Files.updateStorageStatistics, updateStorageStatisticsInterval); + } + }, + 'hide.visibility': function() { + clearInterval(updateStorageStatisticsIntervalId); + updateStorageStatisticsIntervalId = 0; } - }, - 'hide.visibility': function() { - clearInterval(update_storage_statistics_interval_id); - update_storage_statistics_interval_id = 0; - } - }); + }); + } } - + //scroll to and highlight preselected file if (getURLParameter('scrollto')) { FileList.scrollTo(getURLParameter('scrollto')); } }); -function scanFiles(force, dir, users){ +function scanFiles(force, dir, users) { if (!OC.currentUser) { return; } - if(!dir){ + if (!dir) { dir = ''; } force = !!force; //cast to bool @@ -397,17 +438,18 @@ function scanFiles(force, dir, users){ scannerEventSource = new OC.EventSource(OC.filePath('files','ajax','scan.php'),{force: force,dir: dir}); } scanFiles.cancel = scannerEventSource.close.bind(scannerEventSource); - scannerEventSource.listen('count',function(count){ - console.log(count + ' files scanned') + scannerEventSource.listen('count',function(count) { + console.log(count + ' files scanned'); }); - scannerEventSource.listen('folder',function(path){ - console.log('now scanning ' + path) + scannerEventSource.listen('folder',function(path) { + console.log('now scanning ' + path); }); - scannerEventSource.listen('done',function(count){ + scannerEventSource.listen('done',function(count) { scanFiles.scanning=false; console.log('done after ' + count + ' files'); + Files.updateStorageStatistics(); }); - scannerEventSource.listen('user',function(user){ + scannerEventSource.listen('user',function(user) { console.log('scanning files for ' + user); }); } @@ -416,14 +458,14 @@ scanFiles.scanning=false; function boolOperationFinished(data, callback) { result = jQuery.parseJSON(data.responseText); Files.updateMaxUploadFilesize(result); - if(result.status == 'success'){ + if (result.status === 'success') { callback.call(); } else { alert(result.data.message); } } -var createDragShadow = function(event){ +var createDragShadow = function(event) { //select dragged file var isDragSelected = $(event.target).parents('tr').find('td input:first').prop('checked'); if (!isDragSelected) { @@ -431,9 +473,9 @@ var createDragShadow = function(event){ $(event.target).parents('tr').find('td input:first').prop('checked',true); } - var selectedFiles = getSelectedFiles(); + var selectedFiles = getSelectedFilesTrash(); - if (!isDragSelected && selectedFiles.length == 1) { + if (!isDragSelected && selectedFiles.length === 1) { //revert the selection $(event.target).parents('tr').find('td input:first').prop('checked',false); } @@ -450,7 +492,7 @@ var createDragShadow = function(event){ var dir=$('#dir').val(); - $(selectedFiles).each(function(i,elem){ + $(selectedFiles).each(function(i,elem) { var newtr = $('<tr/>').attr('data-dir', dir).attr('data-filename', elem.name); newtr.append($('<td/>').addClass('filename').text(elem.name)); newtr.append($('<td/>').addClass('size').text(humanFileSize(elem.size))); @@ -459,24 +501,24 @@ var createDragShadow = function(event){ newtr.find('td.filename').attr('style','background-image:url('+OC.imagePath('core', 'filetypes/folder.png')+')'); } else { var path = getPathForPreview(elem.name); - lazyLoadPreview(path, elem.mime, function(previewpath){ + Files.lazyLoadPreview(path, elem.mime, function(previewpath) { newtr.find('td.filename').attr('style','background-image:url('+previewpath+')'); - }); + }, null, null, elem.etag); } }); return dragshadow; -} +}; //options for file drag/drop var dragOptions={ revert: 'invalid', revertDuration: 300, - opacity: 0.7, zIndex: 100, appendTo: 'body', cursorAt: { left: -5, top: -5 }, + opacity: 0.7, zIndex: 100, appendTo: 'body', cursorAt: { left: 24, top: 18 }, helper: createDragShadow, cursor: 'move', stop: function(event, ui) { $('#fileList tr td.filename').addClass('ui-draggable'); } -} +}; // sane browsers support using the distance option if ( $('html.ie').length === 0) { dragOptions['distance'] = 20; @@ -489,20 +531,22 @@ var folderDropOptions={ return false; } - var target=$.trim($(this).find('.nametext').text()); + var target = $(this).closest('tr').data('file'); var files = ui.helper.find('tr'); - $(files).each(function(i,row){ + $(files).each(function(i,row) { var dir = $(row).data('dir'); var file = $(row).data('filename'); $.post(OC.filePath('files', 'ajax', 'move.php'), { dir: dir, file: file, target: dir+'/'+target }, function(result) { if (result) { if (result.status === 'success') { //recalculate folder size - var oldSize = $('#fileList tr').filterAttr('data-file',target).data('size'); - var newSize = oldSize + $('#fileList tr').filterAttr('data-file',file).data('size'); - $('#fileList tr').filterAttr('data-file',target).data('size', newSize); - $('#fileList tr').filterAttr('data-file',target).find('td.filesize').text(humanFileSize(newSize)); + var oldFile = FileList.findFileEl(target); + var newFile = FileList.findFileEl(file); + var oldSize = oldFile.data('size'); + var newSize = oldSize + newFile.data('size'); + oldFile.data('size', newSize); + oldFile.find('td.filesize').text(humanFileSize(newSize)); FileList.remove(file); procesSelection(); @@ -519,24 +563,24 @@ var folderDropOptions={ }); }, tolerance: 'pointer' -} +}; var crumbDropOptions={ drop: function( event, ui ) { var target=$(this).data('dir'); - var dir=$('#dir').val(); - while(dir.substr(0,1)=='/'){//remove extra leading /'s + var dir = $('#dir').val(); + while(dir.substr(0,1) === '/') {//remove extra leading /'s dir=dir.substr(1); } - dir='/'+dir; - if(dir.substr(-1,1)!='/'){ - dir=dir+'/'; + dir = '/' + dir; + if (dir.substr(-1,1) !== '/') { + dir = dir + '/'; } - if(target==dir || target+'/'==dir){ + if (target === dir || target+'/' === dir) { return; } var files = ui.helper.find('tr'); - $(files).each(function(i,row){ + $(files).each(function(i,row) { var dir = $(row).data('dir'); var file = $(row).data('filename'); $.post(OC.filePath('files', 'ajax', 'move.php'), { dir: dir, file: file, target: target }, function(result) { @@ -557,13 +601,17 @@ var crumbDropOptions={ }); }, tolerance: 'pointer' -} +}; -function procesSelection(){ - var selected=getSelectedFiles(); - var selectedFiles=selected.filter(function(el){return el.type=='file'}); - var selectedFolders=selected.filter(function(el){return el.type=='dir'}); - if(selectedFiles.length==0 && selectedFolders.length==0) { +function procesSelection() { + var selected = getSelectedFilesTrash(); + var selectedFiles = selected.filter(function(el) { + return el.type==='file'; + }); + var selectedFolders = selected.filter(function(el) { + return el.type==='dir'; + }); + if (selectedFiles.length === 0 && selectedFolders.length === 0) { $('#headerName>span.name').text(t('files','Name')); $('#headerSize').text(t('files','Size')); $('#modified').text(t('files','Modified')); @@ -572,25 +620,25 @@ function procesSelection(){ } else { $('.selectedActions').show(); - var totalSize=0; - for(var i=0;i<selectedFiles.length;i++){ + var totalSize = 0; + for(var i=0; i<selectedFiles.length; i++) { totalSize+=selectedFiles[i].size; }; - for(var i=0;i<selectedFolders.length;i++){ + for(var i=0; i<selectedFolders.length; i++) { totalSize+=selectedFolders[i].size; }; $('#headerSize').text(humanFileSize(totalSize)); - var selection=''; - if(selectedFolders.length>0){ + var selection = ''; + if (selectedFolders.length > 0) { selection += n('files', '%n folder', '%n folders', selectedFolders.length); - if(selectedFiles.length>0){ - selection+=' & '; + if (selectedFiles.length > 0) { + selection += ' & '; } } - if(selectedFiles.length>0){ + if (selectedFiles.length>0) { selection += n('files', '%n file', '%n files', selectedFiles.length); } - $('#headerName>span.name').text(selection); + $('#headerName span.name').text(selection); $('#modified').text(''); $('table').addClass('multiselect'); } @@ -598,54 +646,57 @@ function procesSelection(){ /** * @brief get a list of selected files - * @param string property (option) the property of the file requested - * @return array + * @param {string} property (option) the property of the file requested + * @return {array} * * possible values for property: name, mime, size and type * if property is set, an array with that property for each file is returnd * if it's ommited an array of objects with all properties is returned */ -function getSelectedFiles(property){ +function getSelectedFilesTrash(property) { var elements=$('td.filename input:checkbox:checked').parent().parent(); var files=[]; - elements.each(function(i,element){ + elements.each(function(i,element) { var file={ name:$(element).attr('data-file'), mime:$(element).data('mime'), type:$(element).data('type'), - size:$(element).data('size') + size:$(element).data('size'), + etag:$(element).data('etag') }; - if(property){ + if (property) { files.push(file[property]); - }else{ + } else { files.push(file); } }); return files; } -function getMimeIcon(mime, ready){ - if(getMimeIcon.cache[mime]){ - ready(getMimeIcon.cache[mime]); - }else{ - $.get( OC.filePath('files','ajax','mimeicon.php'), {mime: mime}, function(path){ - getMimeIcon.cache[mime]=path; - ready(getMimeIcon.cache[mime]); +Files.getMimeIcon = function(mime, ready) { + if (Files.getMimeIcon.cache[mime]) { + ready(Files.getMimeIcon.cache[mime]); + } else { + $.get( OC.filePath('files','ajax','mimeicon.php'), {mime: mime}, function(path) { + Files.getMimeIcon.cache[mime]=path; + ready(Files.getMimeIcon.cache[mime]); }); } } -getMimeIcon.cache={}; +Files.getMimeIcon.cache={}; function getPathForPreview(name) { var path = $('#dir').val() + '/' + name; return path; } -function lazyLoadPreview(path, mime, ready, width, height) { +Files.lazyLoadPreview = function(path, mime, ready, width, height, etag) { // get mime icon url - getMimeIcon(mime, function(iconURL) { + Files.getMimeIcon(mime, function(iconURL) { + var urlSpec = {}; + var previewURL; ready(iconURL); // set mimeicon URL - + // now try getting a preview thumbnail URL if ( ! width ) { width = $('#filestable').data('preview-x'); @@ -653,22 +704,43 @@ function lazyLoadPreview(path, mime, ready, width, height) { if ( ! height ) { height = $('#filestable').data('preview-y'); } - if( $('#publicUploadButtonMock').length ) { - var previewURL = OC.Router.generate('core_ajax_public_preview', {file: encodeURIComponent(path), x:width, y:height, t:$('#dirToken').val()}); + // note: the order of arguments must match the one + // from the server's template so that the browser + // knows it's the same file for caching + urlSpec.x = width; + urlSpec.y = height; + urlSpec.file = Files.fixPath(path); + + if (etag){ + // use etag as cache buster + urlSpec.c = etag; + } + else { + console.warn('Files.lazyLoadPreview(): missing etag argument'); + } + + if ( $('#publicUploadButtonMock').length ) { + urlSpec.t = $('#dirToken').val(); + previewURL = OC.Router.generate('core_ajax_public_preview', urlSpec); } else { - var previewURL = OC.Router.generate('core_ajax_preview', {file: encodeURIComponent(path), x:width, y:height}); + previewURL = OC.Router.generate('core_ajax_preview', urlSpec); } - $.get(previewURL, function() { - previewURL = previewURL.replace('(', '%28'); - previewURL = previewURL.replace(')', '%29'); + previewURL = previewURL.replace('(', '%28'); + previewURL = previewURL.replace(')', '%29'); + + // preload image to prevent delay + // this will make the browser cache the image + var img = new Image(); + img.onload = function(){ //set preview thumbnail URL - ready(previewURL + '&reload=true'); - }); + ready(previewURL); + } + img.src = previewURL; }); } -function getUniqueName(name){ - if($('tr').filterAttr('data-file',name).length>0){ +function getUniqueName(name) { + if (FileList.findFileEl(name).exists()) { var parts=name.split('.'); var extension = ""; if (parts.length > 1) { @@ -677,9 +749,9 @@ function getUniqueName(name){ var base=parts.join('.'); numMatch=base.match(/\((\d+)\)/); var num=2; - if(numMatch && numMatch.length>0){ + if (numMatch && numMatch.length>0) { num=parseInt(numMatch[numMatch.length-1])+1; - base=base.split('(') + base=base.split('('); base.pop(); base=$.trim(base.join('(')); } @@ -693,15 +765,20 @@ function getUniqueName(name){ } function checkTrashStatus() { - $.post(OC.filePath('files_trashbin', 'ajax', 'isEmpty.php'), function(result){ + $.post(OC.filePath('files_trashbin', 'ajax', 'isEmpty.php'), function(result) { if (result.data.isEmpty === false) { $("input[type=button][id=trash]").removeAttr("disabled"); } }); } -function onClickBreadcrumb(e){ - var $el = $(e.target).closest('.crumb'); - e.preventDefault(); - FileList.changeDirectory(decodeURIComponent($el.data('dir'))); +function onClickBreadcrumb(e) { + var $el = $(e.target).closest('.crumb'), + $targetDir = $el.data('dir'); + isPublic = !!$('#isPublic').val(); + + if ($targetDir !== undefined && !isPublic) { + e.preventDefault(); + FileList.changeDirectory(decodeURIComponent($targetDir)); + } } diff --git a/apps/files/l10n/ady.php b/apps/files/l10n/ady.php new file mode 100644 index 00000000000..0157af093e9 --- /dev/null +++ b/apps/files/l10n/ady.php @@ -0,0 +1,7 @@ +<?php +$TRANSLATIONS = array( +"_%n folder_::_%n folders_" => array("",""), +"_%n file_::_%n files_" => array("",""), +"_Uploading %n file_::_Uploading %n files_" => array("","") +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files/l10n/af.php b/apps/files/l10n/af.php new file mode 100644 index 00000000000..0157af093e9 --- /dev/null +++ b/apps/files/l10n/af.php @@ -0,0 +1,7 @@ +<?php +$TRANSLATIONS = array( +"_%n folder_::_%n folders_" => array("",""), +"_%n file_::_%n files_" => array("",""), +"_Uploading %n file_::_Uploading %n files_" => array("","") +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files/l10n/ak.php b/apps/files/l10n/ak.php new file mode 100644 index 00000000000..f229792722d --- /dev/null +++ b/apps/files/l10n/ak.php @@ -0,0 +1,7 @@ +<?php +$TRANSLATIONS = array( +"_%n folder_::_%n folders_" => array("",""), +"_%n file_::_%n files_" => array("",""), +"_Uploading %n file_::_Uploading %n files_" => array("","") +); +$PLURAL_FORMS = "nplurals=2; plural=n > 1;"; diff --git a/apps/files/l10n/ar.php b/apps/files/l10n/ar.php index 67a3414819b..0148f5ca3c1 100644 --- a/apps/files/l10n/ar.php +++ b/apps/files/l10n/ar.php @@ -2,6 +2,7 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "فشل في نقل الملف %s - يوجد ملف بنفس هذا الاسم", "Could not move %s" => "فشل في نقل %s", +"File name cannot be empty." => "اسم الملف لا يجوز أن يكون فارغا", "Unable to set upload directory." => "غير قادر على تحميل المجلد", "Invalid Token" => "علامة غير صالحة", "No file was uploaded. Unknown error" => "لم يتم رفع أي ملف , خطأ غير معروف", @@ -13,38 +14,40 @@ $TRANSLATIONS = array( "Missing a temporary folder" => "المجلد المؤقت غير موجود", "Failed to write to disk" => "خطأ في الكتابة على القرص الصلب", "Not enough storage available" => "لا يوجد مساحة تخزينية كافية", +"Upload failed. Could not get file info." => "فشلت عملية الرفع. تعذر الحصول على معلومات الملف.", +"Upload failed. Could not find uploaded file" => "*فشلت علمية الرفع. تعذر إيجاد الملف الذي تم رفعه.\n*فشلت علمية التحميل. تعذر إيجاد الملف الذي تم تحميله.", "Invalid directory." => "مسار غير صحيح.", "Files" => "الملفات", +"Unable to upload {filename} as it is a directory or has 0 bytes" => "تعذر رفع الملف {filename} إما لأنه مجلد أو لان حجم الملف 0 بايت", "Not enough space available" => "لا توجد مساحة كافية", "Upload cancelled." => "تم إلغاء عملية رفع الملفات .", +"Could not get result from server." => "تعذر الحصول على نتيجة من الخادم", "File upload is in progress. Leaving the page now will cancel the upload." => "عملية رفع الملفات قيد التنفيذ. اغلاق الصفحة سوف يلغي عملية رفع الملفات.", -"URL cannot be empty." => "عنوان ال URL لا يجوز أن يكون فارغا.", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "تسمية ملف غير صالحة. استخدام الاسم \"shared\" محجوز بواسطة ownCloud", -"Error" => "خطأ", +"{new_name} already exists" => "{new_name} موجود مسبقا", "Share" => "شارك", "Delete permanently" => "حذف بشكل دائم", "Rename" => "إعادة تسميه", "Pending" => "قيد الانتظار", -"{new_name} already exists" => "{new_name} موجود مسبقا", -"replace" => "استبدال", -"suggest name" => "اقترح إسم", -"cancel" => "إلغاء", "replaced {new_name} with {old_name}" => "استبدل {new_name} بـ {old_name}", "undo" => "تراجع", -"_%n folder_::_%n folders_" => array("","","","","",""), -"_%n file_::_%n files_" => array("","","","","",""), +"_%n folder_::_%n folders_" => array("لا يوجد مجلدات %n","1 مجلد %n","2 مجلد %n","عدد قليل من مجلدات %n","عدد كبير من مجلدات %n","مجلدات %n"), +"_%n file_::_%n files_" => array("لا يوجد ملفات %n","ملف %n","2 ملف %n","قليل من ملفات %n","الكثير من ملفات %n"," ملفات %n"), "{dirs} and {files}" => "{dirs} و {files}", -"_Uploading %n file_::_Uploading %n files_" => array("","","","","",""), +"_Uploading %n file_::_Uploading %n files_" => array("لا يوجد ملفات %n لتحميلها","تحميل 1 ملف %n","تحميل 2 ملف %n","يتم تحميل عدد قليل من ملفات %n","يتم تحميل عدد كبير من ملفات %n","يتم تحميل ملفات %n"), "'.' is an invalid file name." => "\".\" اسم ملف غير صحيح.", -"File name cannot be empty." => "اسم الملف لا يجوز أن يكون فارغا", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "اسم غير صحيح , الرموز '\\', '/', '<', '>', ':', '\"', '|', '?' و \"*\" غير مسموح استخدامها", "Your storage is full, files can not be updated or synced anymore!" => "مساحتك التخزينية ممتلئة, لا يمكم تحديث ملفاتك أو مزامنتها بعد الآن !", "Your storage is almost full ({usedSpacePercent}%)" => "مساحتك التخزينية امتلأت تقريبا ", +"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "تم تمكين تشفير البرامج لكن لم يتم تهيئة المفاتيح لذا يرجى تسجيل الخروج ثم تسجيل الدخول مرة آخرى.", +"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "المفتاح الخاص بتشفير التطبيقات غير صالح. يرجى تحديث كلمة السر الخاصة بالمفتاح الخاص من الإعدادت الشخصية حتى تتمكن من الوصول للملفات المشفرة.", "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "تم تعطيل التشفير لكن ملفاتك لا تزال مشفرة. فضلا اذهب إلى الإعدادات الشخصية لإزالة التشفير عن ملفاتك.", "Your download is being prepared. This might take some time if the files are big." => "جاري تجهيز عملية التحميل. قد تستغرق بعض الوقت اذا كان حجم الملفات كبير.", +"Error moving file" => "حدث خطأ أثناء نقل الملف", +"Error" => "خطأ", "Name" => "اسم", "Size" => "حجم", "Modified" => "معدل", +"%s could not be renamed" => "%s لا يمكن إعادة تسميته. ", "Upload" => "رفع", "File handling" => "التعامل مع الملف", "Maximum upload size" => "الحد الأقصى لحجم الملفات التي يمكن رفعها", @@ -60,10 +63,8 @@ $TRANSLATIONS = array( "From link" => "من رابط", "Deleted files" => "حذف الملفات", "Cancel upload" => "إلغاء رفع الملفات", -"You don’t have write permissions here." => "لا تملك صلاحيات الكتابة هنا.", "Nothing in here. Upload something!" => "لا يوجد شيء هنا. إرفع بعض الملفات!", "Download" => "تحميل", -"Unshare" => "إلغاء مشاركة", "Delete" => "إلغاء", "Upload too large" => "حجم الترفيع أعلى من المسموح", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "حجم الملفات التي تريد ترفيعها أعلى من المسموح على الخادم.", diff --git a/apps/files/l10n/az.php b/apps/files/l10n/az.php new file mode 100644 index 00000000000..70ab6572ba4 --- /dev/null +++ b/apps/files/l10n/az.php @@ -0,0 +1,7 @@ +<?php +$TRANSLATIONS = array( +"_%n folder_::_%n folders_" => array(""), +"_%n file_::_%n files_" => array(""), +"_Uploading %n file_::_Uploading %n files_" => array("") +); +$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/files/l10n/be.php b/apps/files/l10n/be.php index 17262d2184d..830400b93fb 100644 --- a/apps/files/l10n/be.php +++ b/apps/files/l10n/be.php @@ -2,6 +2,7 @@ $TRANSLATIONS = array( "_%n folder_::_%n folders_" => array("","","",""), "_%n file_::_%n files_" => array("","","",""), -"_Uploading %n file_::_Uploading %n files_" => array("","","","") +"_Uploading %n file_::_Uploading %n files_" => array("","","",""), +"Error" => "Памылка" ); $PLURAL_FORMS = "nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"; diff --git a/apps/files/l10n/bg_BG.php b/apps/files/l10n/bg_BG.php index e7dafd1c43a..12e699064be 100644 --- a/apps/files/l10n/bg_BG.php +++ b/apps/files/l10n/bg_BG.php @@ -9,17 +9,15 @@ $TRANSLATIONS = array( "Invalid directory." => "Невалидна директория.", "Files" => "Файлове", "Upload cancelled." => "Качването е спряно.", -"Error" => "Грешка", "Share" => "Споделяне", "Delete permanently" => "Изтриване завинаги", "Rename" => "Преименуване", "Pending" => "Чакащо", -"replace" => "препокриване", -"cancel" => "отказ", "undo" => "възтановяване", "_%n folder_::_%n folders_" => array("",""), "_%n file_::_%n files_" => array("",""), "_Uploading %n file_::_Uploading %n files_" => array("",""), +"Error" => "Грешка", "Name" => "Име", "Size" => "Размер", "Modified" => "Променено", @@ -29,6 +27,7 @@ $TRANSLATIONS = array( "Save" => "Запис", "New" => "Ново", "Text file" => "Текстов файл", +"New folder" => "Нова папка", "Folder" => "Папка", "Cancel upload" => "Спри качването", "Nothing in here. Upload something!" => "Няма нищо тук. Качете нещо.", diff --git a/apps/files/l10n/bn_BD.php b/apps/files/l10n/bn_BD.php index 66ac3a2165f..f7266517e9e 100644 --- a/apps/files/l10n/bn_BD.php +++ b/apps/files/l10n/bn_BD.php @@ -2,6 +2,7 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "%s কে স্থানান্তর করা সম্ভব হলো না - এই নামের ফাইল বিদ্যমান", "Could not move %s" => "%s কে স্থানান্তর করা সম্ভব হলো না", +"File name cannot be empty." => "ফাইলের নামটি ফাঁকা রাখা যাবে না।", "No file was uploaded. Unknown error" => "কোন ফাইল আপলোড করা হয় নি। সমস্যার কারণটি অজ্ঞাত।", "There is no error, the file uploaded with success" => "কোন সমস্যা হয় নি, ফাইল আপলোড সুসম্পন্ন হয়েছে।", "The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "আপলোড করা ফাইলটি php.ini তে বর্ণিত upload_max_filesize নির্দেশিত আয়তন অতিক্রম করছেঃ", @@ -15,23 +16,18 @@ $TRANSLATIONS = array( "Not enough space available" => "যথেষ্ঠ পরিমাণ স্থান নেই", "Upload cancelled." => "আপলোড বাতিল করা হয়েছে।", "File upload is in progress. Leaving the page now will cancel the upload." => "ফাইল আপলোড চলমান। এই পৃষ্ঠা পরিত্যাগ করলে আপলোড বাতিল করা হবে।", -"URL cannot be empty." => "URL ফাঁকা রাখা যাবে না।", -"Error" => "সমস্যা", +"{new_name} already exists" => "{new_name} টি বিদ্যমান", "Share" => "ভাগাভাগি কর", "Rename" => "পূনঃনামকরণ", "Pending" => "মুলতুবি", -"{new_name} already exists" => "{new_name} টি বিদ্যমান", -"replace" => "প্রতিস্থাপন", -"suggest name" => "নাম সুপারিশ করুন", -"cancel" => "বাতিল", "replaced {new_name} with {old_name}" => "{new_name} কে {old_name} নামে প্রতিস্থাপন করা হয়েছে", "undo" => "ক্রিয়া প্রত্যাহার", "_%n folder_::_%n folders_" => array("",""), "_%n file_::_%n files_" => array("",""), "_Uploading %n file_::_Uploading %n files_" => array("",""), "'.' is an invalid file name." => "টি একটি অননুমোদিত নাম।", -"File name cannot be empty." => "ফাইলের নামটি ফাঁকা রাখা যাবে না।", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "নামটি সঠিক নয়, '\\', '/', '<', '>', ':', '\"', '|', '?' এবং '*' অনুমোদিত নয়।", +"Error" => "সমস্যা", "Name" => "রাম", "Size" => "আকার", "Modified" => "পরিবর্তিত", @@ -51,7 +47,6 @@ $TRANSLATIONS = array( "Cancel upload" => "আপলোড বাতিল কর", "Nothing in here. Upload something!" => "এখানে কিছুই নেই। কিছু আপলোড করুন !", "Download" => "ডাউনলোড", -"Unshare" => "ভাগাভাগি বাতিল ", "Delete" => "মুছে", "Upload too large" => "আপলোডের আকারটি অনেক বড়", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "আপনি এই সার্ভারে আপলোড করার জন্য অনুমোদিত ফাইলের সর্বোচ্চ আকারের চেয়ে বৃহদাকার ফাইল আপলোড করার চেষ্টা করছেন ", diff --git a/apps/files/l10n/bs.php b/apps/files/l10n/bs.php index 8ab07a97761..47276eccda0 100644 --- a/apps/files/l10n/bs.php +++ b/apps/files/l10n/bs.php @@ -7,6 +7,7 @@ $TRANSLATIONS = array( "Name" => "Ime", "Size" => "Veličina", "Save" => "Spasi", +"New folder" => "Nova fascikla", "Folder" => "Fasikla" ); $PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"; diff --git a/apps/files/l10n/ca.php b/apps/files/l10n/ca.php index 5c2cade8d63..261713bc581 100644 --- a/apps/files/l10n/ca.php +++ b/apps/files/l10n/ca.php @@ -2,6 +2,15 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "No s'ha pogut moure %s - Ja hi ha un fitxer amb aquest nom", "Could not move %s" => " No s'ha pogut moure %s", +"File name cannot be empty." => "El nom del fitxer no pot ser buit.", +"File name must not contain \"/\". Please choose a different name." => "El nom de fitxer no pot contenir \"/\". Indiqueu un nom diferent.", +"The name %s is already used in the folder %s. Please choose a different name." => "El nom %s ja s'usa en la carpeta %s. Indiqueu un nom diferent.", +"Not a valid source" => "No és un origen vàlid", +"Error while downloading %s to %s" => "S'ha produït un error en baixar %s a %s", +"Error when creating the file" => "S'ha produït un error en crear el fitxer", +"Folder name cannot be empty." => "El nom de la carpeta no pot ser buit.", +"Folder name must not contain \"/\". Please choose a different name." => "El nom de la carpeta no pot contenir \"/\". Indiqueu un nom diferent.", +"Error when creating the folder" => "S'ha produït un error en crear la carpeta", "Unable to set upload directory." => "No es pot establir la carpeta de pujada.", "Invalid Token" => "Testimoni no vàlid", "No file was uploaded. Unknown error" => "No s'ha carregat cap fitxer. Error desconegut", @@ -22,34 +31,37 @@ $TRANSLATIONS = array( "Upload cancelled." => "La pujada s'ha cancel·lat.", "Could not get result from server." => "No hi ha resposta del servidor.", "File upload is in progress. Leaving the page now will cancel the upload." => "Hi ha una pujada en curs. Si abandoneu la pàgina la pujada es cancel·larà.", -"URL cannot be empty." => "La URL no pot ser buida", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Nom de carpeta no vàlid. L'ús de 'Shared' està reservat per Owncloud", -"Error" => "Error", +"URL cannot be empty" => "L'URL no pot ser buit", +"In the home folder 'Shared' is a reserved filename" => "A la carpeta inici 'Compartit' és un nom de fitxer reservat", +"{new_name} already exists" => "{new_name} ja existeix", +"Could not create file" => "No s'ha pogut crear el fitxer", +"Could not create folder" => "No s'ha pogut crear la carpeta", "Share" => "Comparteix", "Delete permanently" => "Esborra permanentment", "Rename" => "Reanomena", "Pending" => "Pendent", -"{new_name} already exists" => "{new_name} ja existeix", -"replace" => "substitueix", -"suggest name" => "sugereix un nom", -"cancel" => "cancel·la", +"Could not rename file" => "No es pot canviar el nom de fitxer", "replaced {new_name} with {old_name}" => "s'ha substituït {old_name} per {new_name}", "undo" => "desfés", +"Error deleting file." => "Error en esborrar el fitxer.", "_%n folder_::_%n folders_" => array("%n carpeta","%n carpetes"), "_%n file_::_%n files_" => array("%n fitxer","%n fitxers"), "{dirs} and {files}" => "{dirs} i {files}", "_Uploading %n file_::_Uploading %n files_" => array("Pujant %n fitxer","Pujant %n fitxers"), "'.' is an invalid file name." => "'.' és un nom no vàlid per un fitxer.", -"File name cannot be empty." => "El nom del fitxer no pot ser buit.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "El nóm no és vàlid, '\\', '/', '<', '>', ':', '\"', '|', '?' i '*' no estan permesos.", "Your storage is full, files can not be updated or synced anymore!" => "El vostre espai d'emmagatzemament és ple, els fitxers ja no es poden actualitzar o sincronitzar!", "Your storage is almost full ({usedSpacePercent}%)" => "El vostre espai d'emmagatzemament és gairebé ple ({usedSpacePercent}%)", +"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "L'aplicació d'encriptació està activada però les claus no estan inicialitzades, sortiu i acrediteu-vos de nou.", +"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "La clau privada de l'aplicació d'encriptació no és vàlida! Actualitzeu la contrasenya de la clau privada a l'arranjament personal per recuperar els fitxers encriptats.", "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "L'encriptació s'ha desactivat però els vostres fitxers segueixen encriptats. Aneu a la vostra configuració personal per desencriptar els vostres fitxers.", "Your download is being prepared. This might take some time if the files are big." => "S'està preparant la baixada. Pot trigar una estona si els fitxers són grans.", "Error moving file" => "Error en moure el fitxer", +"Error" => "Error", "Name" => "Nom", "Size" => "Mida", "Modified" => "Modificat", +"Invalid folder name. Usage of 'Shared' is reserved." => "Nom de carpeta no vàlid. L'ús de 'Shared' és reservat", "%s could not be renamed" => "%s no es pot canviar el nom", "Upload" => "Puja", "File handling" => "Gestió de fitxers", @@ -61,15 +73,16 @@ $TRANSLATIONS = array( "Maximum input size for ZIP files" => "Mida màxima d'entrada per fitxers ZIP", "Save" => "Desa", "New" => "Nou", +"New text file" => "Nou fitxer de text", "Text file" => "Fitxer de text", +"New folder" => "Carpeta nova", "Folder" => "Carpeta", "From link" => "Des d'enllaç", "Deleted files" => "Fitxers esborrats", "Cancel upload" => "Cancel·la la pujada", -"You don’t have write permissions here." => "No teniu permisos d'escriptura aquí.", +"You don’t have permission to upload or create files here" => "No teniu permisos per a pujar o crear els fitxers aquí", "Nothing in here. Upload something!" => "Res per aquí. Pugeu alguna cosa!", "Download" => "Baixa", -"Unshare" => "Deixa de compartir", "Delete" => "Esborra", "Upload too large" => "La pujada és massa gran", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Els fitxers que esteu intentant pujar excedeixen la mida màxima de pujada del servidor", diff --git a/apps/files/l10n/cs_CZ.php b/apps/files/l10n/cs_CZ.php index f1e54ee5fc3..44e0fdae1f1 100644 --- a/apps/files/l10n/cs_CZ.php +++ b/apps/files/l10n/cs_CZ.php @@ -2,6 +2,16 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "Nelze přesunout %s - již existuje soubor se stejným názvem", "Could not move %s" => "Nelze přesunout %s", +"File name cannot be empty." => "Název souboru nemůže být prázdný řetězec.", +"File name must not contain \"/\". Please choose a different name." => "Název souboru nesmí obsahovat \"/\". Vyberte prosím jiné jméno.", +"The name %s is already used in the folder %s. Please choose a different name." => "Název %s ve složce %s již existuje. Vyberte prosím jiné jméno.", +"Not a valid source" => "Neplatný zdroj", +"Server is not allowed to open URLs, please check the server configuration" => "Server není oprávněn otevírat adresy URL. Ověřte, prosím, konfiguraci serveru.", +"Error while downloading %s to %s" => "Chyba při stahování %s do %s", +"Error when creating the file" => "Chyba při vytváření souboru", +"Folder name cannot be empty." => "Název složky nemůže být prázdný.", +"Folder name must not contain \"/\". Please choose a different name." => "Název složky nesmí obsahovat \"/\". Zvolte prosím jiný.", +"Error when creating the folder" => "Chyba při vytváření složky", "Unable to set upload directory." => "Nelze nastavit adresář pro nahrané soubory.", "Invalid Token" => "Neplatný token", "No file was uploaded. Unknown error" => "Žádný soubor nebyl odeslán. Neznámá chyba", @@ -13,39 +23,47 @@ $TRANSLATIONS = array( "Missing a temporary folder" => "Chybí adresář pro dočasné soubory", "Failed to write to disk" => "Zápis na disk selhal", "Not enough storage available" => "Nedostatek dostupného úložného prostoru", +"Upload failed. Could not get file info." => "Nahrávání selhalo. Nepodařilo se získat informace o souboru.", +"Upload failed. Could not find uploaded file" => "Nahrávání selhalo. Nepodařilo se nalézt nahraný soubor.", "Invalid directory." => "Neplatný adresář", "Files" => "Soubory", +"Unable to upload {filename} as it is a directory or has 0 bytes" => "Nelze nahrát soubor {filename}, protože je to buď adresář nebo má velikost 0 bytů", "Not enough space available" => "Nedostatek volného místa", "Upload cancelled." => "Odesílání zrušeno.", +"Could not get result from server." => "Nepodařilo se získat výsledek ze serveru.", "File upload is in progress. Leaving the page now will cancel the upload." => "Probíhá odesílání souboru. Opuštění stránky způsobí zrušení nahrávání.", -"URL cannot be empty." => "URL nemůže být prázdná.", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Název složky nelze použít. Použití názvu 'Shared' je ownCloudem rezervováno", -"Error" => "Chyba", +"URL cannot be empty" => "URL nemůže zůstat prázdná", +"In the home folder 'Shared' is a reserved filename" => "V osobní složce je název 'Shared' rezervovaný", +"{new_name} already exists" => "{new_name} již existuje", +"Could not create file" => "Nepodařilo se vytvořit soubor", +"Could not create folder" => "Nepodařilo se vytvořit složku", +"Error fetching URL" => "Chyba při načítání URL", "Share" => "Sdílet", "Delete permanently" => "Trvale odstranit", "Rename" => "Přejmenovat", "Pending" => "Nevyřízené", -"{new_name} already exists" => "{new_name} již existuje", -"replace" => "nahradit", -"suggest name" => "navrhnout název", -"cancel" => "zrušit", +"Could not rename file" => "Nepodařilo se přejmenovat soubor", "replaced {new_name} with {old_name}" => "nahrazeno {new_name} s {old_name}", "undo" => "vrátit zpět", +"Error deleting file." => "Chyba při mazání souboru.", "_%n folder_::_%n folders_" => array("%n složka","%n složky","%n složek"), "_%n file_::_%n files_" => array("%n soubor","%n soubory","%n souborů"), "{dirs} and {files}" => "{dirs} a {files}", "_Uploading %n file_::_Uploading %n files_" => array("Nahrávám %n soubor","Nahrávám %n soubory","Nahrávám %n souborů"), "'.' is an invalid file name." => "'.' je neplatným názvem souboru.", -"File name cannot be empty." => "Název souboru nemůže být prázdný řetězec.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Neplatný název, znaky '\\', '/', '<', '>', ':', '\"', '|', '?' a '*' nejsou povoleny.", "Your storage is full, files can not be updated or synced anymore!" => "Vaše úložiště je plné, nelze aktualizovat ani synchronizovat soubory.", "Your storage is almost full ({usedSpacePercent}%)" => "Vaše úložiště je téměř plné ({usedSpacePercent}%)", +"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "Aplikace pro šifrování je zapnuta, ale vaše klíče nejsou inicializované. Prosím odhlaste se a znovu přihlaste", +"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "Chybný soukromý klíč pro šifrovací aplikaci. Aktualizujte prosím heslo svého soukromého klíče ve vašem osobním nastavení, abyste znovu získali přístup k vašim zašifrovaným souborům.", "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Šifrování bylo vypnuto, vaše soubory jsou však stále zašifrované. Běžte prosím do osobního nastavení, kde soubory odšifrujete.", "Your download is being prepared. This might take some time if the files are big." => "Vaše soubory ke stažení se připravují. Pokud jsou velké, může to chvíli trvat.", "Error moving file" => "Chyba při přesunu souboru", +"Error" => "Chyba", "Name" => "Název", "Size" => "Velikost", "Modified" => "Upraveno", +"Invalid folder name. Usage of 'Shared' is reserved." => "Neplatný název složky. Použití 'Shared' je rezervováno.", "%s could not be renamed" => "%s nemůže být přejmenován", "Upload" => "Odeslat", "File handling" => "Zacházení se soubory", @@ -57,15 +75,16 @@ $TRANSLATIONS = array( "Maximum input size for ZIP files" => "Maximální velikost vstupu pro ZIP soubory", "Save" => "Uložit", "New" => "Nový", +"New text file" => "Nový textový soubor", "Text file" => "Textový soubor", +"New folder" => "Nová složka", "Folder" => "Složka", "From link" => "Z odkazu", "Deleted files" => "Odstraněné soubory", "Cancel upload" => "Zrušit odesílání", -"You don’t have write permissions here." => "Nemáte zde práva zápisu.", +"You don’t have permission to upload or create files here" => "Nemáte oprávnění zde nahrávat či vytvářet soubory", "Nothing in here. Upload something!" => "Žádný obsah. Nahrajte něco.", "Download" => "Stáhnout", -"Unshare" => "Zrušit sdílení", "Delete" => "Smazat", "Upload too large" => "Odesílaný soubor je příliš velký", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Soubory, které se snažíte odeslat, překračují limit velikosti odesílání na tomto serveru.", diff --git a/apps/files/l10n/cy_GB.php b/apps/files/l10n/cy_GB.php index 86e5f65e7b0..2a007761c52 100644 --- a/apps/files/l10n/cy_GB.php +++ b/apps/files/l10n/cy_GB.php @@ -2,6 +2,7 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "Methwyd symud %s - Mae ffeil gyda'r enw hwn eisoes yn bodoli", "Could not move %s" => "Methwyd symud %s", +"File name cannot be empty." => "Does dim hawl cael enw ffeil gwag.", "No file was uploaded. Unknown error" => "Ni lwythwyd ffeil i fyny. Gwall anhysbys.", "There is no error, the file uploaded with success" => "Does dim gwall, llwythodd y ffeil i fyny'n llwyddiannus", "The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Mae'r ffeil lwythwyd i fyny'n fwy na chyfarwyddeb upload_max_filesize yn php.ini:", @@ -16,27 +17,22 @@ $TRANSLATIONS = array( "Not enough space available" => "Dim digon o le ar gael", "Upload cancelled." => "Diddymwyd llwytho i fyny.", "File upload is in progress. Leaving the page now will cancel the upload." => "Mae ffeiliau'n cael eu llwytho i fyny. Bydd gadael y dudalen hon nawr yn diddymu'r broses.", -"URL cannot be empty." => "Does dim hawl cael URL gwag.", -"Error" => "Gwall", +"{new_name} already exists" => "{new_name} yn bodoli'n barod", "Share" => "Rhannu", "Delete permanently" => "Dileu'n barhaol", "Rename" => "Ailenwi", "Pending" => "I ddod", -"{new_name} already exists" => "{new_name} yn bodoli'n barod", -"replace" => "amnewid", -"suggest name" => "awgrymu enw", -"cancel" => "diddymu", "replaced {new_name} with {old_name}" => "newidiwyd {new_name} yn lle {old_name}", "undo" => "dadwneud", "_%n folder_::_%n folders_" => array("","","",""), "_%n file_::_%n files_" => array("","","",""), "_Uploading %n file_::_Uploading %n files_" => array("","","",""), "'.' is an invalid file name." => "Mae '.' yn enw ffeil annilys.", -"File name cannot be empty." => "Does dim hawl cael enw ffeil gwag.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Enw annilys, ni chaniateir, '\\', '/', '<', '>', ':', '\"', '|', '?' na '*'.", "Your storage is full, files can not be updated or synced anymore!" => "Mae eich storfa'n llawn, ni ellir diweddaru a chydweddu ffeiliau mwyach!", "Your storage is almost full ({usedSpacePercent}%)" => "Mae eich storfa bron a bod yn llawn ({usedSpacePercent}%)", "Your download is being prepared. This might take some time if the files are big." => "Wrthi'n paratoi i lwytho i lawr. Gall gymryd peth amser os yw'r ffeiliau'n fawr.", +"Error" => "Gwall", "Name" => "Enw", "Size" => "Maint", "Modified" => "Addaswyd", @@ -55,10 +51,8 @@ $TRANSLATIONS = array( "From link" => "Dolen o", "Deleted files" => "Ffeiliau ddilewyd", "Cancel upload" => "Diddymu llwytho i fyny", -"You don’t have write permissions here." => "Nid oes gennych hawliau ysgrifennu fan hyn.", "Nothing in here. Upload something!" => "Does dim byd fan hyn. Llwythwch rhywbeth i fyny!", "Download" => "Llwytho i lawr", -"Unshare" => "Dad-rannu", "Delete" => "Dileu", "Upload too large" => "Maint llwytho i fyny'n rhy fawr", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Mae'r ffeiliau rydych yn ceisio llwytho i fyny'n fwy na maint mwyaf llwytho ffeiliau i fyny ar y gweinydd hwn.", diff --git a/apps/files/l10n/da.php b/apps/files/l10n/da.php index c2a20931ba0..9b7722444a8 100644 --- a/apps/files/l10n/da.php +++ b/apps/files/l10n/da.php @@ -2,6 +2,16 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "Kunne ikke flytte %s - der findes allerede en fil med dette navn", "Could not move %s" => "Kunne ikke flytte %s", +"File name cannot be empty." => "Filnavnet kan ikke stå tomt.", +"File name must not contain \"/\". Please choose a different name." => "Filnavnet må ikke indeholde \"/\". Vælg venligst et andet navn.", +"The name %s is already used in the folder %s. Please choose a different name." => "Navnet %s er allerede i brug i mappen %s. Vælg venligst et andet navn.", +"Not a valid source" => "Ikke en gyldig kilde", +"Server is not allowed to open URLs, please check the server configuration" => "Server har ikke tilladelse til at åbne URL'er. Kontroller venligst serverens indstillinger", +"Error while downloading %s to %s" => "Fejl ved hentning af %s til %s", +"Error when creating the file" => "Fejl ved oprettelse af fil", +"Folder name cannot be empty." => "Mappenavnet kan ikke være tomt.", +"Folder name must not contain \"/\". Please choose a different name." => "Mappenavnet må ikke indeholde \"/\". Vælg venligst et andet navn.", +"Error when creating the folder" => "Fejl ved oprettelse af mappen", "Unable to set upload directory." => "Ude af stand til at vælge upload mappe.", "Invalid Token" => "Ugyldig Token ", "No file was uploaded. Unknown error" => "Ingen fil blev uploadet. Ukendt fejl.", @@ -13,38 +23,47 @@ $TRANSLATIONS = array( "Missing a temporary folder" => "Manglende midlertidig mappe.", "Failed to write to disk" => "Fejl ved skrivning til disk.", "Not enough storage available" => "Der er ikke nok plads til rådlighed", +"Upload failed. Could not get file info." => "Upload fejlede. Kunne ikke hente filinformation.", +"Upload failed. Could not find uploaded file" => "Upload fejlede. Kunne ikke finde den uploadede fil.", "Invalid directory." => "Ugyldig mappe.", "Files" => "Filer", +"Unable to upload {filename} as it is a directory or has 0 bytes" => "Kan ikke upload {filename} da det er enten en mappe eller indholder 0 bytes.", "Not enough space available" => "ikke nok tilgængelig ledig plads ", "Upload cancelled." => "Upload afbrudt.", +"Could not get result from server." => "Kunne ikke hente resultat fra server.", "File upload is in progress. Leaving the page now will cancel the upload." => "Fil upload kører. Hvis du forlader siden nu, vil uploadet blive annuleret.", -"URL cannot be empty." => "URLen kan ikke være tom.", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Ugyldigt mappenavn. Brug af 'Shared' er forbeholdt af ownCloud", -"Error" => "Fejl", +"URL cannot be empty" => "URL kan ikke være tom", +"In the home folder 'Shared' is a reserved filename" => "Navnet 'Shared' er reserveret i hjemmemappen.", +"{new_name} already exists" => "{new_name} eksisterer allerede", +"Could not create file" => "Kunne ikke oprette fil", +"Could not create folder" => "Kunne ikke oprette mappe", +"Error fetching URL" => "Fejl ved URL", "Share" => "Del", "Delete permanently" => "Slet permanent", "Rename" => "Omdøb", "Pending" => "Afventer", -"{new_name} already exists" => "{new_name} eksisterer allerede", -"replace" => "erstat", -"suggest name" => "foreslå navn", -"cancel" => "fortryd", +"Could not rename file" => "Kunne ikke omdøbe filen", "replaced {new_name} with {old_name}" => "erstattede {new_name} med {old_name}", "undo" => "fortryd", +"Error deleting file." => "Fejl ved sletnign af fil.", "_%n folder_::_%n folders_" => array("%n mappe","%n mapper"), "_%n file_::_%n files_" => array("%n fil","%n filer"), "{dirs} and {files}" => "{dirs} og {files}", "_Uploading %n file_::_Uploading %n files_" => array("Uploader %n fil","Uploader %n filer"), "'.' is an invalid file name." => "'.' er et ugyldigt filnavn.", -"File name cannot be empty." => "Filnavnet kan ikke stå tomt.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Ugyldigt navn, '\\', '/', '<', '>', ':' | '?', '\"', '', og '*' er ikke tilladt.", "Your storage is full, files can not be updated or synced anymore!" => "Din opbevaringsplads er fyldt op, filer kan ikke opdateres eller synkroniseres længere!", "Your storage is almost full ({usedSpacePercent}%)" => "Din opbevaringsplads er næsten fyldt op ({usedSpacePercent}%)", +"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "Krypteringsprogrammet er aktiveret, men din nøgle er ikke igangsat. Log venligst ud og ind igen.", +"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "Ugyldig privat nøgle for krypteringsprogrammet. Opdater venligst dit kodeord for den private nøgle i dine personlige indstillinger. Det kræves for at få adgang til dine krypterede filer.", "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Krypteringen blev deaktiveret, men dine filer er stadig krypteret. Gå venligst til dine personlige indstillinger for at dekryptere dine filer. ", "Your download is being prepared. This might take some time if the files are big." => "Dit download forberedes. Dette kan tage lidt tid ved større filer.", +"Error moving file" => "Fejl ved flytning af fil", +"Error" => "Fejl", "Name" => "Navn", "Size" => "Størrelse", "Modified" => "Ændret", +"Invalid folder name. Usage of 'Shared' is reserved." => "Ugyldig mappenavn. 'Shared' er reserveret.", "%s could not be renamed" => "%s kunne ikke omdøbes", "Upload" => "Upload", "File handling" => "Filhåndtering", @@ -56,15 +75,16 @@ $TRANSLATIONS = array( "Maximum input size for ZIP files" => "Maksimal størrelse på ZIP filer", "Save" => "Gem", "New" => "Ny", +"New text file" => "Ny tekstfil", "Text file" => "Tekstfil", +"New folder" => "Ny Mappe", "Folder" => "Mappe", "From link" => "Fra link", "Deleted files" => "Slettede filer", "Cancel upload" => "Fortryd upload", -"You don’t have write permissions here." => "Du har ikke skriverettigheder her.", +"You don’t have permission to upload or create files here" => "Du har ikke tilladelse til at uploade eller oprette filer her", "Nothing in here. Upload something!" => "Her er tomt. Upload noget!", "Download" => "Download", -"Unshare" => "Fjern deling", "Delete" => "Slet", "Upload too large" => "Upload er for stor", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Filerne, du prøver at uploade, er større end den maksimale størrelse for fil-upload på denne server.", diff --git a/apps/files/l10n/de.php b/apps/files/l10n/de.php index 143a5efc3da..b209fee88ae 100644 --- a/apps/files/l10n/de.php +++ b/apps/files/l10n/de.php @@ -2,6 +2,16 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "Konnte %s nicht verschieben. Eine Datei mit diesem Namen existiert bereits", "Could not move %s" => "Konnte %s nicht verschieben", +"File name cannot be empty." => "Der Dateiname darf nicht leer sein.", +"File name must not contain \"/\". Please choose a different name." => "Der Dateiname darf kein \"/\" enthalten. Bitte wähle einen anderen Namen.", +"The name %s is already used in the folder %s. Please choose a different name." => "Der Name %s wird bereits im Ordner %s benutzt. Bitte wähle einen anderen Namen.", +"Not a valid source" => "Keine gültige Quelle", +"Server is not allowed to open URLs, please check the server configuration" => "Dem Server ist das Öffnen von URLs nicht erlaubt, bitte die Serverkonfiguration prüfen", +"Error while downloading %s to %s" => "Fehler beim Herunterladen von %s nach %s", +"Error when creating the file" => "Fehler beim Erstellen der Datei", +"Folder name cannot be empty." => "Der Ordner-Name darf nicht leer sein.", +"Folder name must not contain \"/\". Please choose a different name." => "Der Ordner-Name darf kein \"/\" enthalten. Bitte wähle einen anderen Namen.", +"Error when creating the folder" => "Fehler beim Erstellen des Ordners", "Unable to set upload directory." => "Das Upload-Verzeichnis konnte nicht gesetzt werden.", "Invalid Token" => "Ungültiges Merkmal", "No file was uploaded. Unknown error" => "Keine Datei hochgeladen. Unbekannter Fehler", @@ -17,39 +27,43 @@ $TRANSLATIONS = array( "Upload failed. Could not find uploaded file" => "Hochladen fehlgeschlagen. Hochgeladene Datei konnte nicht gefunden werden.", "Invalid directory." => "Ungültiges Verzeichnis.", "Files" => "Dateien", -"Unable to upload {filename} as it is a directory or has 0 bytes" => "Datei {filename} kann nicht hochgeladen werden, da sie entweder ein Verzeichnis oder 0 Bytes groß ist", +"Unable to upload {filename} as it is a directory or has 0 bytes" => "Die Datei {filename} kann nicht hochgeladen werden, da sie entweder ein Verzeichnis oder 0 Bytes groß ist", "Not enough space available" => "Nicht genug Speicherplatz verfügbar", "Upload cancelled." => "Upload abgebrochen.", "Could not get result from server." => "Ergebnis konnte nicht vom Server abgerufen werden.", "File upload is in progress. Leaving the page now will cancel the upload." => "Dateiupload läuft. Wenn Du die Seite jetzt verlässt, wird der Upload abgebrochen.", -"URL cannot be empty." => "Die URL darf nicht leer sein.", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Der Ordnername ist ungültig. Nur ownCloud kann den Ordner \"Shared\" anlegen", -"Error" => "Fehler", +"URL cannot be empty" => "Die URL darf nicht leer sein", +"In the home folder 'Shared' is a reserved filename" => "Das Benutzerverzeichnis 'Shared' ist ein reservierter Dateiname", +"{new_name} already exists" => "{new_name} existiert bereits", +"Could not create file" => "Die Datei konnte nicht erstellt werden", +"Could not create folder" => "Der Ordner konnte nicht erstellt werden", +"Error fetching URL" => "Fehler beim Abrufen der URL", "Share" => "Teilen", "Delete permanently" => "Endgültig löschen", "Rename" => "Umbenennen", "Pending" => "Ausstehend", -"{new_name} already exists" => "{new_name} existiert bereits", -"replace" => "ersetzen", -"suggest name" => "Namen vorschlagen", -"cancel" => "abbrechen", +"Could not rename file" => "Die Datei konnte nicht umbenannt werden", "replaced {new_name} with {old_name}" => "{old_name} ersetzt durch {new_name}", "undo" => "rückgängig machen", +"Error deleting file." => "Fehler beim Löschen der Datei.", "_%n folder_::_%n folders_" => array("%n Ordner","%n Ordner"), "_%n file_::_%n files_" => array("%n Datei","%n Dateien"), "{dirs} and {files}" => "{dirs} und {files}", "_Uploading %n file_::_Uploading %n files_" => array("%n Datei wird hochgeladen","%n Dateien werden hochgeladen"), "'.' is an invalid file name." => "'.' ist kein gültiger Dateiname.", -"File name cannot be empty." => "Der Dateiname darf nicht leer sein.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Ungültiger Name, '\\', '/', '<', '>', ':', '\"', '|', '?' und '*' sind nicht zulässig.", "Your storage is full, files can not be updated or synced anymore!" => "Dein Speicher ist voll, daher können keine Dateien mehr aktualisiert oder synchronisiert werden!", "Your storage is almost full ({usedSpacePercent}%)" => "Dein Speicher ist fast voll ({usedSpacePercent}%)", -"Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Die Verschlüsselung wurde deaktiviert, jedoch sind deine Dateien nach wie vor verschlüsselt. Bitte gehe zu deinen persönlichen Einstellungen, um deine Dateien zu entschlüsseln.", +"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "Die Verschlüsselung-App ist aktiviert, aber Deine Schlüssel sind nicht initialisiert. Bitte melden Dich nochmals ab und wieder an.", +"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "Ungültiger privater Schlüssel für die Verschlüsselung-App. Bitte aktualisiere Dein privates Schlüssel-Passwort, um den Zugriff auf Deine verschlüsselten Dateien wiederherzustellen.", +"Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Die Verschlüsselung wurde deaktiviert, jedoch sind Deine Dateien nach wie vor verschlüsselt. Bitte gehe zu Deinen persönlichen Einstellungen, um Deine Dateien zu entschlüsseln.", "Your download is being prepared. This might take some time if the files are big." => "Dein Download wird vorbereitet. Dies kann bei größeren Dateien etwas dauern.", "Error moving file" => "Fehler beim Verschieben der Datei", +"Error" => "Fehler", "Name" => "Name", "Size" => "Größe", "Modified" => "Geändert", +"Invalid folder name. Usage of 'Shared' is reserved." => "Ungültiger Verzeichnisname. Die Nutzung von 'Shared' ist reserviert.", "%s could not be renamed" => "%s konnte nicht umbenannt werden", "Upload" => "Hochladen", "File handling" => "Dateibehandlung", @@ -61,15 +75,16 @@ $TRANSLATIONS = array( "Maximum input size for ZIP files" => "Maximale Größe für ZIP-Dateien", "Save" => "Speichern", "New" => "Neu", +"New text file" => "Neue Textdatei", "Text file" => "Textdatei", +"New folder" => "Neuer Ordner", "Folder" => "Ordner", "From link" => "Von einem Link", "Deleted files" => "Gelöschte Dateien", "Cancel upload" => "Upload abbrechen", -"You don’t have write permissions here." => "Du hast hier keine Schreib-Berechtigung.", +"You don’t have permission to upload or create files here" => "Du besitzt hier keine Berechtigung, um Dateien hochzuladen oder zu erstellen", "Nothing in here. Upload something!" => "Alles leer. Lade etwas hoch!", "Download" => "Herunterladen", -"Unshare" => "Freigabe aufheben", "Delete" => "Löschen", "Upload too large" => "Der Upload ist zu groß", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Die Datei überschreitet die Maximalgröße für Uploads auf diesem Server.", diff --git a/apps/files/l10n/de_CH.php b/apps/files/l10n/de_CH.php index a7074a8b1cc..b9504293467 100644 --- a/apps/files/l10n/de_CH.php +++ b/apps/files/l10n/de_CH.php @@ -2,6 +2,7 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "%s konnte nicht verschoben werden. Eine Datei mit diesem Namen existiert bereits.", "Could not move %s" => "Konnte %s nicht verschieben", +"File name cannot be empty." => "Der Dateiname darf nicht leer sein.", "Unable to set upload directory." => "Das Upload-Verzeichnis konnte nicht gesetzt werden.", "Invalid Token" => "Ungültiges Merkmal", "No file was uploaded. Unknown error" => "Keine Datei hochgeladen. Unbekannter Fehler", @@ -18,29 +19,23 @@ $TRANSLATIONS = array( "Not enough space available" => "Nicht genügend Speicherplatz verfügbar", "Upload cancelled." => "Upload abgebrochen.", "File upload is in progress. Leaving the page now will cancel the upload." => "Dateiupload läuft. Wenn Sie die Seite jetzt verlassen, wird der Upload abgebrochen.", -"URL cannot be empty." => "Die URL darf nicht leer sein.", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Ungültiger Ordnername. Die Verwendung von «Shared» ist ownCloud vorbehalten.", -"Error" => "Fehler", +"{new_name} already exists" => "{new_name} existiert bereits", "Share" => "Teilen", "Delete permanently" => "Endgültig löschen", "Rename" => "Umbenennen", "Pending" => "Ausstehend", -"{new_name} already exists" => "{new_name} existiert bereits", -"replace" => "ersetzen", -"suggest name" => "Namen vorschlagen", -"cancel" => "abbrechen", "replaced {new_name} with {old_name}" => "{old_name} wurde ersetzt durch {new_name}", "undo" => "rückgängig machen", "_%n folder_::_%n folders_" => array("","%n Ordner"), "_%n file_::_%n files_" => array("","%n Dateien"), "_Uploading %n file_::_Uploading %n files_" => array("%n Datei wird hochgeladen","%n Dateien werden hochgeladen"), "'.' is an invalid file name." => "'.' ist kein gültiger Dateiname.", -"File name cannot be empty." => "Der Dateiname darf nicht leer sein.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Ungültiger Name, «\\», «/», «<», «>», «:», «\"», «|», «?» und «*» sind nicht zulässig.", "Your storage is full, files can not be updated or synced anymore!" => "Ihr Speicher ist voll, daher können keine Dateien mehr aktualisiert oder synchronisiert werden!", "Your storage is almost full ({usedSpacePercent}%)" => "Ihr Speicher ist fast voll ({usedSpacePercent}%)", "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Die Verschlüsselung wurde deaktiviert, jedoch sind Ihre Dateien nach wie vor verschlüsselt. Bitte gehen Sie zu Ihren persönlichen Einstellungen, um Ihre Dateien zu entschlüsseln.", "Your download is being prepared. This might take some time if the files are big." => "Ihr Download wird vorbereitet. Dies kann bei grösseren Dateien etwas dauern.", +"Error" => "Fehler", "Name" => "Name", "Size" => "Grösse", "Modified" => "Geändert", @@ -56,14 +51,13 @@ $TRANSLATIONS = array( "Save" => "Speichern", "New" => "Neu", "Text file" => "Textdatei", +"New folder" => "Neues Verzeichnis", "Folder" => "Ordner", "From link" => "Von einem Link", "Deleted files" => "Gelöschte Dateien", "Cancel upload" => "Upload abbrechen", -"You don’t have write permissions here." => "Sie haben hier keine Schreib-Berechtigungen.", "Nothing in here. Upload something!" => "Alles leer. Laden Sie etwas hoch!", "Download" => "Herunterladen", -"Unshare" => "Freigabe aufheben", "Delete" => "Löschen", "Upload too large" => "Der Upload ist zu gross", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Die Datei überschreitet die Maximalgrösse für Uploads auf diesem Server.", diff --git a/apps/files/l10n/de_DE.php b/apps/files/l10n/de_DE.php index c58cb4bbe3e..76cdce00e4c 100644 --- a/apps/files/l10n/de_DE.php +++ b/apps/files/l10n/de_DE.php @@ -2,6 +2,16 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "%s konnte nicht verschoben werden. Eine Datei mit diesem Namen existiert bereits.", "Could not move %s" => "Konnte %s nicht verschieben", +"File name cannot be empty." => "Der Dateiname darf nicht leer sein.", +"File name must not contain \"/\". Please choose a different name." => "Der Dateiname darf kein \"/\" enthalten. Bitte wählen Sie einen anderen Namen.", +"The name %s is already used in the folder %s. Please choose a different name." => "Der Name %s wird bereits im Ordner %s benutzt. Bitte wählen Sie einen anderen Namen.", +"Not a valid source" => "Keine gültige Quelle", +"Server is not allowed to open URLs, please check the server configuration" => "Dem Server ist das Öffnen von URLs nicht erlaubt, bitte die Serverkonfiguration prüfen", +"Error while downloading %s to %s" => "Fehler beim Herunterladen von %s nach %s", +"Error when creating the file" => "Fehler beim Erstellen der Datei", +"Folder name cannot be empty." => "Der Ordner-Name darf nicht leer sein.", +"Folder name must not contain \"/\". Please choose a different name." => "Der Ordner-Name darf kein \"/\" enthalten. Bitte wählen Sie einen anderen Namen.", +"Error when creating the folder" => "Fehler beim Erstellen des Ordners", "Unable to set upload directory." => "Das Upload-Verzeichnis konnte nicht gesetzt werden.", "Invalid Token" => "Ungültiges Merkmal", "No file was uploaded. Unknown error" => "Keine Datei hochgeladen. Unbekannter Fehler", @@ -13,43 +23,47 @@ $TRANSLATIONS = array( "Missing a temporary folder" => "Kein temporärer Ordner vorhanden", "Failed to write to disk" => "Fehler beim Schreiben auf die Festplatte", "Not enough storage available" => "Nicht genug Speicher vorhanden.", -"Upload failed. Could not get file info." => "Hochladen fehlgeschlagen. Dateiinformationen konnten nicht abgerufen werden.", -"Upload failed. Could not find uploaded file" => "Hochladen fehlgeschlagen. Hochgeladene Datei konnte nicht gefunden werden.", +"Upload failed. Could not get file info." => "Hochladen fehlgeschlagen. Die Dateiinformationen konnten nicht abgerufen werden.", +"Upload failed. Could not find uploaded file" => "Hochladen fehlgeschlagen. Die hochgeladene Datei konnte nicht gefunden werden.", "Invalid directory." => "Ungültiges Verzeichnis.", "Files" => "Dateien", -"Unable to upload {filename} as it is a directory or has 0 bytes" => "Datei {filename} kann nicht hochgeladen werden, da sie entweder ein Verzeichnis oder 0 Bytes groß ist", +"Unable to upload {filename} as it is a directory or has 0 bytes" => "Die Datei {filename} kann nicht hochgeladen werden, da sie entweder ein Verzeichnis oder 0 Bytes groß ist", "Not enough space available" => "Nicht genügend Speicherplatz verfügbar", "Upload cancelled." => "Upload abgebrochen.", "Could not get result from server." => "Ergebnis konnte nicht vom Server abgerufen werden.", "File upload is in progress. Leaving the page now will cancel the upload." => "Dateiupload läuft. Wenn Sie die Seite jetzt verlassen, wird der Upload abgebrochen.", -"URL cannot be empty." => "Die URL darf nicht leer sein.", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Ungültiger Ordnername. Die Verwendung von \"Shared\" ist ownCloud vorbehalten.", -"Error" => "Fehler", +"URL cannot be empty" => "Die URL darf nicht leer sein", +"In the home folder 'Shared' is a reserved filename" => "Das Benutzerverzeichnis 'Shared' ist ein reservierter Dateiname", +"{new_name} already exists" => "{new_name} existiert bereits", +"Could not create file" => "Die Datei konnte nicht erstellt werden", +"Could not create folder" => "Der Ordner konnte nicht erstellt werden", +"Error fetching URL" => "Fehler beim Abrufen der URL", "Share" => "Teilen", "Delete permanently" => "Endgültig löschen", "Rename" => "Umbenennen", "Pending" => "Ausstehend", -"{new_name} already exists" => "{new_name} existiert bereits", -"replace" => "ersetzen", -"suggest name" => "Namen vorschlagen", -"cancel" => "abbrechen", +"Could not rename file" => "Die Datei konnte nicht umbenannt werden", "replaced {new_name} with {old_name}" => "{old_name} wurde ersetzt durch {new_name}", "undo" => "rückgängig machen", +"Error deleting file." => "Fehler beim Löschen der Datei.", "_%n folder_::_%n folders_" => array("%n Ordner","%n Ordner"), "_%n file_::_%n files_" => array("%n Datei","%n Dateien"), "{dirs} and {files}" => "{dirs} und {files}", "_Uploading %n file_::_Uploading %n files_" => array("%n Datei wird hoch geladen","%n Dateien werden hoch geladen"), "'.' is an invalid file name." => "'.' ist kein gültiger Dateiname.", -"File name cannot be empty." => "Der Dateiname darf nicht leer sein.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Ungültiger Name, '\\', '/', '<', '>', ':', '\"', '|', '?' und '*' sind nicht zulässig.", "Your storage is full, files can not be updated or synced anymore!" => "Ihr Speicher ist voll, daher können keine Dateien mehr aktualisiert oder synchronisiert werden!", "Your storage is almost full ({usedSpacePercent}%)" => "Ihr Speicher ist fast voll ({usedSpacePercent}%)", +"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "Verschlüsselung-App ist aktiviert, aber Ihre Schlüssel sind nicht initialisiert. Bitte melden sich nochmals ab und wieder an.", +"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "Ungültiger privater Schlüssel für die Verschlüsselung-App. Bitte aktualisieren Sie Ihr privates Schlüssel-Passwort, um den Zugriff auf Ihre verschlüsselten Dateien wiederherzustellen.", "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Die Verschlüsselung wurde deaktiviert, jedoch sind Ihre Dateien nach wie vor verschlüsselt. Bitte gehen Sie zu Ihren persönlichen Einstellungen, um Ihre Dateien zu entschlüsseln.", "Your download is being prepared. This might take some time if the files are big." => "Ihr Download wird vorbereitet. Dies kann bei größeren Dateien etwas dauern.", "Error moving file" => "Fehler beim Verschieben der Datei", +"Error" => "Fehler", "Name" => "Name", "Size" => "Größe", "Modified" => "Geändert", +"Invalid folder name. Usage of 'Shared' is reserved." => "Ungültiger Verzeichnisname. Die Nutzung von 'Shared' ist reserviert.", "%s could not be renamed" => "%s konnte nicht umbenannt werden", "Upload" => "Hochladen", "File handling" => "Dateibehandlung", @@ -61,15 +75,16 @@ $TRANSLATIONS = array( "Maximum input size for ZIP files" => "Maximale Größe für ZIP-Dateien", "Save" => "Speichern", "New" => "Neu", +"New text file" => "Neue Textdatei", "Text file" => "Textdatei", +"New folder" => "Neues Verzeichnis", "Folder" => "Ordner", "From link" => "Von einem Link", "Deleted files" => "Gelöschte Dateien", "Cancel upload" => "Upload abbrechen", -"You don’t have write permissions here." => "Sie haben hier keine Schreib-Berechtigungen.", +"You don’t have permission to upload or create files here" => "Sie besitzen hier keine Berechtigung Dateien hochzuladen oder zu erstellen", "Nothing in here. Upload something!" => "Alles leer. Laden Sie etwas hoch!", "Download" => "Herunterladen", -"Unshare" => "Freigabe aufheben", "Delete" => "Löschen", "Upload too large" => "Der Upload ist zu groß", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Die Datei überschreitet die Maximalgröße für Uploads auf diesem Server.", diff --git a/apps/files/l10n/el.php b/apps/files/l10n/el.php index de524f4dd90..9efe1af7dd3 100644 --- a/apps/files/l10n/el.php +++ b/apps/files/l10n/el.php @@ -2,6 +2,16 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "Αδυναμία μετακίνησης του %s - υπάρχει ήδη αρχείο με αυτό το όνομα", "Could not move %s" => "Αδυναμία μετακίνησης του %s", +"File name cannot be empty." => "Το όνομα αρχείου δεν μπορεί να είναι κενό.", +"File name must not contain \"/\". Please choose a different name." => "Το όνομα αρχείου δεν μπορεί να περιέχει \"/\". Παρακαλώ επιλέξτε ένα διαφορετικό όνομα. ", +"The name %s is already used in the folder %s. Please choose a different name." => "Το όνομα %s χρησιμοποιείτε ήδη στον φάκελο %s. Παρακαλώ επιλέξτε ένα άλλο όνομα.", +"Not a valid source" => "Μη έγκυρη πηγή", +"Server is not allowed to open URLs, please check the server configuration" => "Ο διακομιστής δεν επιτρέπεται να ανοίγει URL, παρακαλώ ελέγξτε τις ρυθμίσεις του διακομιστή", +"Error while downloading %s to %s" => "Σφάλμα κατά τη λήψη του %s στο %s", +"Error when creating the file" => "Σφάλμα κατά τη δημιουργία του αρχείου", +"Folder name cannot be empty." => "Το όνομα φακέλου δεν μπορεί να είναι κενό.", +"Folder name must not contain \"/\". Please choose a different name." => "Το όνομα φακέλου δεν μπορεί να περιέχει \"/\". Παρακαλώ επιλέξτε ένα διαφορετικό όνομα. ", +"Error when creating the folder" => "Σφάλμα δημιουργίας φακέλου", "Unable to set upload directory." => "Αδυναμία ορισμού καταλόγου αποστολής.", "Invalid Token" => "Μη έγκυρο Token", "No file was uploaded. Unknown error" => "Δεν ανέβηκε κάποιο αρχείο. Άγνωστο σφάλμα", @@ -13,38 +23,47 @@ $TRANSLATIONS = array( "Missing a temporary folder" => "Λείπει ο προσωρινός φάκελος", "Failed to write to disk" => "Αποτυχία εγγραφής στο δίσκο", "Not enough storage available" => "Μη επαρκής διαθέσιμος αποθηκευτικός χώρος", +"Upload failed. Could not get file info." => "Η φόρτωση απέτυχε. Αδυναμία λήψης πληροφοριών αρχείων.", +"Upload failed. Could not find uploaded file" => "Η φόρτωση απέτυχε. Αδυναμία εύρεσης αρχείου προς φόρτωση.", "Invalid directory." => "Μη έγκυρος φάκελος.", "Files" => "Αρχεία", +"Unable to upload {filename} as it is a directory or has 0 bytes" => "Αδυναμία φόρτωσης {filename} καθώς είναι κατάλογος αρχείων ή έχει 0 bytes", "Not enough space available" => "Δεν υπάρχει αρκετός διαθέσιμος χώρος", "Upload cancelled." => "Η αποστολή ακυρώθηκε.", +"Could not get result from server." => "Αδυναμία λήψης αποτελέσματος από το διακομιστή.", "File upload is in progress. Leaving the page now will cancel the upload." => "Η αποστολή του αρχείου βρίσκεται σε εξέλιξη. Το κλείσιμο της σελίδας θα ακυρώσει την αποστολή.", -"URL cannot be empty." => "Η URL δεν μπορεί να είναι κενή.", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Μη έγκυρο όνομα φακέλου. Η χρήση του 'Κοινόχρηστος' χρησιμοποιείται από το ownCloud", -"Error" => "Σφάλμα", +"URL cannot be empty" => "Η URL δεν πρέπει να είναι κενή", +"In the home folder 'Shared' is a reserved filename" => "Στον αρχικό φάκελο το όνομα 'Shared' διατηρείται από το σύστημα", +"{new_name} already exists" => "{new_name} υπάρχει ήδη", +"Could not create file" => "Αδυναμία δημιουργίας αρχείου", +"Could not create folder" => "Αδυναμία δημιουργίας φακέλου", +"Error fetching URL" => "Σφάλμα φόρτωσης URL", "Share" => "Διαμοιρασμός", "Delete permanently" => "Μόνιμη διαγραφή", "Rename" => "Μετονομασία", "Pending" => "Εκκρεμεί", -"{new_name} already exists" => "{new_name} υπάρχει ήδη", -"replace" => "αντικατέστησε", -"suggest name" => "συνιστώμενο όνομα", -"cancel" => "ακύρωση", +"Could not rename file" => "Αδυναμία μετονομασίας αρχείου", "replaced {new_name} with {old_name}" => "αντικαταστάθηκε το {new_name} με {old_name}", "undo" => "αναίρεση", +"Error deleting file." => "Σφάλμα διαγραφής αρχείου.", "_%n folder_::_%n folders_" => array("%n φάκελος","%n φάκελοι"), "_%n file_::_%n files_" => array("%n αρχείο","%n αρχεία"), +"{dirs} and {files}" => "{Κατάλογοι αρχείων} και {αρχεία}", "_Uploading %n file_::_Uploading %n files_" => array("Ανέβασμα %n αρχείου","Ανέβασμα %n αρχείων"), "'.' is an invalid file name." => "'.' είναι μη έγκυρο όνομα αρχείου.", -"File name cannot be empty." => "Το όνομα αρχείου δεν μπορεί να είναι κενό.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Μη έγκυρο όνομα, '\\', '/', '<', '>', ':', '\"', '|', '?' και '*' δεν επιτρέπονται.", "Your storage is full, files can not be updated or synced anymore!" => "Ο αποθηκευτικός σας χώρος είναι γεμάτος, τα αρχεία δεν μπορούν να ενημερωθούν ή να συγχρονιστούν πια!", "Your storage is almost full ({usedSpacePercent}%)" => "Ο αποθηκευτικός χώρος είναι σχεδόν γεμάτος ({usedSpacePercent}%)", +"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "Η εφαρμογή κρυπτογράφησης είναι ενεργοποιημένη αλλά τα κλειδιά σας δεν έχουν καταγραφεί, παρακαλώ αποσυνδεθείτε και επανασυνδεθείτε.", +"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "Άκυρο προσωπικό κλειδί για την εφαρμογή κρυπτογράφησης. Παρακαλώ ενημερώστε τον κωδικό του προσωπικού κλειδίου σας στις προσωπικές ρυθμίσεις για να επανακτήσετε πρόσβαση στα κρυπτογραφημένα σας αρχεία.", "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Η κρυπτογράφηση απενεργοποιήθηκε, αλλά τα αρχεία σας είναι ακόμα κρυπτογραφημένα. Παρακαλούμε απενεργοποιήσετε την κρυπτογράφηση αρχείων από τις προσωπικές σας ρυθμίσεις", "Your download is being prepared. This might take some time if the files are big." => "Η λήψη προετοιμάζεται. Αυτό μπορεί να πάρει ώρα εάν τα αρχεία έχουν μεγάλο μέγεθος.", "Error moving file" => "Σφάλμα κατά τη μετακίνηση του αρχείου", +"Error" => "Σφάλμα", "Name" => "Όνομα", "Size" => "Μέγεθος", "Modified" => "Τροποποιήθηκε", +"Invalid folder name. Usage of 'Shared' is reserved." => "Άκυρο όνομα φακέλου. Η χρήση του 'Shared' διατηρείται από το σύστημα.", "%s could not be renamed" => "Αδυναμία μετονομασίας του %s", "Upload" => "Μεταφόρτωση", "File handling" => "Διαχείριση αρχείων", @@ -56,15 +75,16 @@ $TRANSLATIONS = array( "Maximum input size for ZIP files" => "Μέγιστο μέγεθος για αρχεία ZIP", "Save" => "Αποθήκευση", "New" => "Νέο", +"New text file" => "Νέο αρχείο κειμένου", "Text file" => "Αρχείο κειμένου", +"New folder" => "Νέος κατάλογος", "Folder" => "Φάκελος", "From link" => "Από σύνδεσμο", "Deleted files" => "Διαγραμμένα αρχεία", "Cancel upload" => "Ακύρωση αποστολής", -"You don’t have write permissions here." => "Δεν έχετε δικαιώματα εγγραφής εδώ.", +"You don’t have permission to upload or create files here" => "Δεν έχετε δικαιώματα φόρτωσης ή δημιουργίας αρχείων εδώ", "Nothing in here. Upload something!" => "Δεν υπάρχει τίποτα εδώ. Ανεβάστε κάτι!", "Download" => "Λήψη", -"Unshare" => "Σταμάτημα διαμοιρασμού", "Delete" => "Διαγραφή", "Upload too large" => "Πολύ μεγάλο αρχείο προς αποστολή", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Τα αρχεία που προσπαθείτε να ανεβάσετε υπερβαίνουν το μέγιστο μέγεθος αποστολής αρχείων σε αυτόν τον διακομιστή.", diff --git a/apps/files/l10n/en_GB.php b/apps/files/l10n/en_GB.php index c747555e40b..ac93aa68abb 100644 --- a/apps/files/l10n/en_GB.php +++ b/apps/files/l10n/en_GB.php @@ -2,6 +2,16 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "Could not move %s - File with this name already exists", "Could not move %s" => "Could not move %s", +"File name cannot be empty." => "File name cannot be empty.", +"File name must not contain \"/\". Please choose a different name." => "File name must not contain \"/\". Please choose a different name.", +"The name %s is already used in the folder %s. Please choose a different name." => "The name %s is already used in the folder %s. Please choose a different name.", +"Not a valid source" => "Not a valid source", +"Server is not allowed to open URLs, please check the server configuration" => "Server is not allowed to open URLs, please check the server configuration", +"Error while downloading %s to %s" => "Error whilst downloading %s to %s", +"Error when creating the file" => "Error when creating the file", +"Folder name cannot be empty." => "Folder name cannot be empty.", +"Folder name must not contain \"/\". Please choose a different name." => "Folder name must not contain \"/\". Please choose a different name.", +"Error when creating the folder" => "Error when creating the folder", "Unable to set upload directory." => "Unable to set upload directory.", "Invalid Token" => "Invalid Token", "No file was uploaded. Unknown error" => "No file was uploaded. Unknown error", @@ -22,34 +32,38 @@ $TRANSLATIONS = array( "Upload cancelled." => "Upload cancelled.", "Could not get result from server." => "Could not get result from server.", "File upload is in progress. Leaving the page now will cancel the upload." => "File upload is in progress. Leaving the page now will cancel the upload.", -"URL cannot be empty." => "URL cannot be empty.", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Invalid folder name. Usage of 'Shared' is reserved by ownCloud", -"Error" => "Error", +"URL cannot be empty" => "URL cannot be empty", +"In the home folder 'Shared' is a reserved filename" => "In the home folder 'Shared' is a reserved file name", +"{new_name} already exists" => "{new_name} already exists", +"Could not create file" => "Could not create file", +"Could not create folder" => "Could not create folder", +"Error fetching URL" => "Error fetching URL", "Share" => "Share", "Delete permanently" => "Delete permanently", "Rename" => "Rename", "Pending" => "Pending", -"{new_name} already exists" => "{new_name} already exists", -"replace" => "replace", -"suggest name" => "suggest name", -"cancel" => "cancel", +"Could not rename file" => "Could not rename file", "replaced {new_name} with {old_name}" => "replaced {new_name} with {old_name}", "undo" => "undo", +"Error deleting file." => "Error deleting file.", "_%n folder_::_%n folders_" => array("%n folder","%n folders"), "_%n file_::_%n files_" => array("%n file","%n files"), "{dirs} and {files}" => "{dirs} and {files}", "_Uploading %n file_::_Uploading %n files_" => array("Uploading %n file","Uploading %n files"), "'.' is an invalid file name." => "'.' is an invalid file name.", -"File name cannot be empty." => "File name cannot be empty.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Invalid name: '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed.", "Your storage is full, files can not be updated or synced anymore!" => "Your storage is full, files can not be updated or synced anymore!", "Your storage is almost full ({usedSpacePercent}%)" => "Your storage is almost full ({usedSpacePercent}%)", +"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "Encryption App is enabled but your keys are not initialised, please log-out and log-in again", +"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files.", "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files.", "Your download is being prepared. This might take some time if the files are big." => "Your download is being prepared. This might take some time if the files are big.", "Error moving file" => "Error moving file", +"Error" => "Error", "Name" => "Name", "Size" => "Size", "Modified" => "Modified", +"Invalid folder name. Usage of 'Shared' is reserved." => "Invalid folder name. Usage of 'Shared' is reserved.", "%s could not be renamed" => "%s could not be renamed", "Upload" => "Upload", "File handling" => "File handling", @@ -61,15 +75,16 @@ $TRANSLATIONS = array( "Maximum input size for ZIP files" => "Maximum input size for ZIP files", "Save" => "Save", "New" => "New", +"New text file" => "New text file", "Text file" => "Text file", +"New folder" => "New folder", "Folder" => "Folder", "From link" => "From link", "Deleted files" => "Deleted files", "Cancel upload" => "Cancel upload", -"You don’t have write permissions here." => "You don’t have write permission here.", +"You don’t have permission to upload or create files here" => "You don’t have permission to upload or create files here", "Nothing in here. Upload something!" => "Nothing in here. Upload something!", "Download" => "Download", -"Unshare" => "Unshare", "Delete" => "Delete", "Upload too large" => "Upload too large", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "The files you are trying to upload exceed the maximum size for file uploads on this server.", diff --git a/apps/files/l10n/eo.php b/apps/files/l10n/eo.php index eb6e6ba2d39..81cfa03fd6d 100644 --- a/apps/files/l10n/eo.php +++ b/apps/files/l10n/eo.php @@ -2,6 +2,16 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "Ne eblis movi %s: dosiero kun ĉi tiu nomo jam ekzistas", "Could not move %s" => "Ne eblis movi %s", +"File name cannot be empty." => "Dosiernomo devas ne malpleni.", +"File name must not contain \"/\". Please choose a different name." => "La dosieronomo ne devas enhavi “/”. Bonvolu elekti malsaman nomon.", +"The name %s is already used in the folder %s. Please choose a different name." => "La nomo %s jam uziĝas en la dosierujo %s. Bonvolu elekti malsaman nomon.", +"Not a valid source" => "Nevalida fonto", +"Error while downloading %s to %s" => "Eraris elŝuto de %s al %s", +"Error when creating the file" => "Eraris la kreo de la dosiero", +"Folder name cannot be empty." => "La dosierujnomo ne povas malpleni.", +"Folder name must not contain \"/\". Please choose a different name." => "La dosiernomo ne devas enhavi “/”. Bonvolu elekti malsaman nomon.", +"Error when creating the folder" => "Eraris la kreo de la dosierujo", +"Unable to set upload directory." => "Ne povis agordiĝi la alŝuta dosierujo.", "No file was uploaded. Unknown error" => "Neniu dosiero alŝutiĝis. Nekonata eraro.", "There is no error, the file uploaded with success" => "Ne estas eraro, la dosiero alŝutiĝis sukcese.", "The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "La dosiero alŝutita superas la regulon upload_max_filesize el php.ini: ", @@ -11,36 +21,41 @@ $TRANSLATIONS = array( "Missing a temporary folder" => "Mankas provizora dosierujo.", "Failed to write to disk" => "Malsukcesis skribo al disko", "Not enough storage available" => "Ne haveblas sufiĉa memoro", +"Upload failed. Could not get file info." => "La alŝuto malsukcesis. Ne povis ekhaviĝi informo pri dosiero.", +"Upload failed. Could not find uploaded file" => "La alŝuto malsukcesis. Ne troviĝis alŝutota dosiero.", "Invalid directory." => "Nevalida dosierujo.", "Files" => "Dosieroj", +"Unable to upload {filename} as it is a directory or has 0 bytes" => "Ne povis alŝutiĝi {filename} ĉar ĝi estas dosierujo aŭ ĝi havas 0 duumokojn", "Not enough space available" => "Ne haveblas sufiĉa spaco", "Upload cancelled." => "La alŝuto nuliĝis.", +"Could not get result from server." => "Ne povis ekhaviĝi rezulto el la servilo.", "File upload is in progress. Leaving the page now will cancel the upload." => "Dosieralŝuto plenumiĝas. Lasi la paĝon nun nuligus la alŝuton.", -"URL cannot be empty." => "URL ne povas esti malplena.", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Nevalida dosierujnomo. La uzo de “Shared” estas rezervita de ownCloud.", -"Error" => "Eraro", +"URL cannot be empty" => "La URL ne povas malpleni", +"{new_name} already exists" => "{new_name} jam ekzistas", +"Could not create file" => "Ne povis kreiĝi dosiero", +"Could not create folder" => "Ne povis kreiĝi dosierujo", "Share" => "Kunhavigi", "Delete permanently" => "Forigi por ĉiam", "Rename" => "Alinomigi", "Pending" => "Traktotaj", -"{new_name} already exists" => "{new_name} jam ekzistas", -"replace" => "anstataŭigi", -"suggest name" => "sugesti nomon", -"cancel" => "nuligi", +"Could not rename file" => "Ne povis alinomiĝi dosiero", "replaced {new_name} with {old_name}" => "anstataŭiĝis {new_name} per {old_name}", "undo" => "malfari", -"_%n folder_::_%n folders_" => array("",""), -"_%n file_::_%n files_" => array("",""), -"_Uploading %n file_::_Uploading %n files_" => array("",""), +"_%n folder_::_%n folders_" => array("%n dosierujo","%n dosierujoj"), +"_%n file_::_%n files_" => array("%n dosiero","%n dosieroj"), +"{dirs} and {files}" => "{dirs} kaj {files}", +"_Uploading %n file_::_Uploading %n files_" => array("Alŝutatas %n dosiero","Alŝutatas %n dosieroj"), "'.' is an invalid file name." => "'.' ne estas valida dosiernomo.", -"File name cannot be empty." => "Dosiernomo devas ne malpleni.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nevalida nomo: “\\”, “/”, “<”, “>”, “:”, “\"”, “|”, “?” kaj “*” ne permesatas.", "Your storage is full, files can not be updated or synced anymore!" => "Via memoro plenas, ne plu eblas ĝisdatigi aŭ sinkronigi dosierojn!", "Your storage is almost full ({usedSpacePercent}%)" => "Via memoro preskaŭ plenas ({usedSpacePercent}%)", "Your download is being prepared. This might take some time if the files are big." => "Via elŝuto pretiĝatas. Ĉi tio povas daŭri iom da tempo se la dosieroj grandas.", +"Error moving file" => "Eraris movo de dosiero", +"Error" => "Eraro", "Name" => "Nomo", "Size" => "Grando", "Modified" => "Modifita", +"%s could not be renamed" => "%s ne povis alinomiĝi", "Upload" => "Alŝuti", "File handling" => "Dosieradministro", "Maximum upload size" => "Maksimuma alŝutogrando", @@ -52,14 +67,14 @@ $TRANSLATIONS = array( "Save" => "Konservi", "New" => "Nova", "Text file" => "Tekstodosiero", +"New folder" => "Nova dosierujo", "Folder" => "Dosierujo", "From link" => "El ligilo", "Deleted files" => "Forigitaj dosieroj", "Cancel upload" => "Nuligi alŝuton", -"You don’t have write permissions here." => "Vi ne havas permeson skribi ĉi tie.", +"You don’t have permission to upload or create files here" => "Vi ne havas permeson alŝuti aŭ krei dosierojn ĉi tie", "Nothing in here. Upload something!" => "Nenio estas ĉi tie. Alŝutu ion!", "Download" => "Elŝuti", -"Unshare" => "Malkunhavigi", "Delete" => "Forigi", "Upload too large" => "Alŝuto tro larĝa", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "La dosieroj, kiujn vi provas alŝuti, transpasas la maksimuman grandon por dosieralŝutoj en ĉi tiu servilo.", diff --git a/apps/files/l10n/es.php b/apps/files/l10n/es.php index 90d760587d9..bfbb80e8962 100644 --- a/apps/files/l10n/es.php +++ b/apps/files/l10n/es.php @@ -1,75 +1,95 @@ <?php $TRANSLATIONS = array( -"Could not move %s - File with this name already exists" => "No se pudo mover %s - Un archivo con ese nombre ya existe.", +"Could not move %s - File with this name already exists" => "No se pudo mover %s - Ya existe un archivo con ese nombre.", "Could not move %s" => "No se pudo mover %s", +"File name cannot be empty." => "El nombre de archivo no puede estar vacío.", +"File name must not contain \"/\". Please choose a different name." => "El nombre del archivo, NO puede contener el simbolo\"/\", por favor elija un nombre diferente.", +"The name %s is already used in the folder %s. Please choose a different name." => "El nombre %s ya está en uso por la carpeta %s. Por favor elija uno diferente.", +"Not a valid source" => "No es un origen válido", +"Server is not allowed to open URLs, please check the server configuration" => "El servidor no puede acceder URLs; revise la configuración del servidor.", +"Error while downloading %s to %s" => "Error mientras se descargaba %s a %s", +"Error when creating the file" => "Error al crear el archivo", +"Folder name cannot be empty." => "El nombre de la carpeta no puede estar vacío.", +"Folder name must not contain \"/\". Please choose a different name." => "El nombre de la carpeta, NO puede contener el simbolo\"/\", por favor elija un nombre diferente.", +"Error when creating the folder" => "Error al crear la carpeta.", "Unable to set upload directory." => "Incapaz de crear directorio de subida.", "Invalid Token" => "Token Inválido", "No file was uploaded. Unknown error" => "No se subió ningún archivo. Error desconocido", -"There is no error, the file uploaded with success" => "No hay ningún error, el archivo se ha subido con éxito", -"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "El archivo subido sobrepasa la directiva upload_max_filesize en php.ini", -"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "El archivo subido sobrepasa la directiva MAX_FILE_SIZE especificada en el formulario HTML", +"There is no error, the file uploaded with success" => "No hubo ningún problema, el archivo se subió con éxito", +"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "El archivo subido sobrepasa la directiva 'upload_max_filesize' en php.ini:", +"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "El archivo subido sobrepasa la directiva 'MAX_FILE_SIZE' especificada en el formulario HTML", "The uploaded file was only partially uploaded" => "El archivo subido fue sólo subido parcialmente", "No file was uploaded" => "No se subió ningún archivo", "Missing a temporary folder" => "Falta la carpeta temporal", "Failed to write to disk" => "Falló al escribir al disco", "Not enough storage available" => "No hay suficiente espacio disponible", +"Upload failed. Could not get file info." => "Actualización fallida. No se pudo obtener información del archivo.", +"Upload failed. Could not find uploaded file" => "Actualización fallida. No se pudo encontrar el archivo subido", "Invalid directory." => "Directorio inválido.", "Files" => "Archivos", +"Unable to upload {filename} as it is a directory or has 0 bytes" => "No ha sido posible subir {filename} porque es un directorio o tiene 0 bytes", "Not enough space available" => "No hay suficiente espacio disponible", "Upload cancelled." => "Subida cancelada.", -"File upload is in progress. Leaving the page now will cancel the upload." => "La subida del archivo está en proceso. Si sale de la página ahora cancelará la subida.", -"URL cannot be empty." => "La URL no puede estar vacía.", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Nombre de carpeta invalido. El uso de \"Shared\" está reservado por ownCloud", -"Error" => "Error", +"Could not get result from server." => "No se pudo obtener respuesta del servidor.", +"File upload is in progress. Leaving the page now will cancel the upload." => "La subida del archivo está en proceso. Si sale de la página ahora, la subida será cancelada.", +"URL cannot be empty" => "La dirección URL no puede estar vacía", +"In the home folder 'Shared' is a reserved filename" => "En la carpeta de inicio, 'Shared' es un nombre reservado", +"{new_name} already exists" => "{new_name} ya existe", +"Could not create file" => "No se pudo crear el archivo", +"Could not create folder" => "No se pudo crear la carpeta", +"Error fetching URL" => "Error al descargar URL.", "Share" => "Compartir", "Delete permanently" => "Eliminar permanentemente", "Rename" => "Renombrar", "Pending" => "Pendiente", -"{new_name} already exists" => "{new_name} ya existe", -"replace" => "reemplazar", -"suggest name" => "sugerir nombre", -"cancel" => "cancelar", +"Could not rename file" => "No se pudo renombrar el archivo", "replaced {new_name} with {old_name}" => "reemplazado {new_name} con {old_name}", "undo" => "deshacer", -"_%n folder_::_%n folders_" => array("","%n carpetas"), -"_%n file_::_%n files_" => array("","%n archivos"), +"Error deleting file." => "Error borrando el archivo.", +"_%n folder_::_%n folders_" => array("%n carpeta","%n carpetas"), +"_%n file_::_%n files_" => array("%n archivo","%n archivos"), "{dirs} and {files}" => "{dirs} y {files}", "_Uploading %n file_::_Uploading %n files_" => array("Subiendo %n archivo","Subiendo %n archivos"), "'.' is an invalid file name." => "'.' no es un nombre de archivo válido.", -"File name cannot be empty." => "El nombre de archivo no puede estar vacío.", -"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nombre Invalido, \"\\\", \"/\", \"<\", \">\", \":\", \"\", \"|\" \"?\" y \"*\" no están permitidos ", -"Your storage is full, files can not be updated or synced anymore!" => "Su almacenamiento está lleno, ¡no se pueden actualizar o sincronizar más!", +"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nombre inválido, los caracteres \"\\\", \"/\", \"<\", \">\", \":\", \"\", \"|\" \"?\" y \"*\" no están permitidos ", +"Your storage is full, files can not be updated or synced anymore!" => "Su almacenamiento está lleno, ¡los archivos no se actualizarán ni sincronizarán más!", "Your storage is almost full ({usedSpacePercent}%)" => "Su almacenamiento está casi lleno ({usedSpacePercent}%)", +"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "La app de crifrado está habilitada pero tus claves no han sido inicializadas, por favor, cierra la sesión y vuelva a iniciarla de nuevo.", +"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "La clave privada no es válida para la app de cifrado. Por favor, actualiza la contraseña de tu clave privada en tus ajustes personales para recuperar el acceso a tus archivos cifrados.", "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "El cifrado ha sido deshabilitado pero tus archivos permanecen cifrados. Por favor, ve a tus ajustes personales para descifrar tus archivos.", -"Your download is being prepared. This might take some time if the files are big." => "Su descarga está siendo preparada. Esto puede tardar algún tiempo si los archivos son grandes.", +"Your download is being prepared. This might take some time if the files are big." => "Su descarga está siendo preparada. Esto podría tardar algo de tiempo si los archivos son grandes.", +"Error moving file" => "Error moviendo archivo", +"Error" => "Error", "Name" => "Nombre", "Size" => "Tamaño", "Modified" => "Modificado", -"%s could not be renamed" => "%s no se pudo renombrar", +"Invalid folder name. Usage of 'Shared' is reserved." => "Nombre de carpeta inválido. El uso de \"Shared\" esta reservado.", +"%s could not be renamed" => "%s no pudo ser renombrado", "Upload" => "Subir", -"File handling" => "Manejo de archivos", +"File handling" => "Administración de archivos", "Maximum upload size" => "Tamaño máximo de subida", "max. possible: " => "máx. posible:", "Needed for multi-file and folder downloads." => "Necesario para multi-archivo y descarga de carpetas", "Enable ZIP-download" => "Habilitar descarga en ZIP", -"0 is unlimited" => "0 es ilimitado", +"0 is unlimited" => "0 significa ilimitado", "Maximum input size for ZIP files" => "Tamaño máximo para archivos ZIP de entrada", "Save" => "Guardar", "New" => "Nuevo", +"New text file" => "Nuevo archivo de texto", "Text file" => "Archivo de texto", +"New folder" => "Nueva carpeta", "Folder" => "Carpeta", "From link" => "Desde enlace", "Deleted files" => "Archivos eliminados", "Cancel upload" => "Cancelar subida", -"You don’t have write permissions here." => "No tiene permisos de escritura aquí.", +"You don’t have permission to upload or create files here" => "No tienes permisos para subir o crear archivos aquí.", "Nothing in here. Upload something!" => "No hay nada aquí. ¡Suba algo!", "Download" => "Descargar", -"Unshare" => "Dejar de compartir", "Delete" => "Eliminar", "Upload too large" => "Subida demasido grande", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Los archivos que estás intentando subir sobrepasan el tamaño máximo permitido en este servidor.", "Files are being scanned, please wait." => "Los archivos están siendo escaneados, por favor espere.", "Current scanning" => "Escaneo actual", -"Upgrading filesystem cache..." => "Actualizando caché del sistema de archivos" +"Upgrading filesystem cache..." => "Actualizando caché del sistema de archivos..." ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files/l10n/es_AR.php b/apps/files/l10n/es_AR.php index be16f3f99ae..78d6388cd9b 100644 --- a/apps/files/l10n/es_AR.php +++ b/apps/files/l10n/es_AR.php @@ -2,6 +2,7 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "No se pudo mover %s - Un archivo con este nombre ya existe", "Could not move %s" => "No se pudo mover %s ", +"File name cannot be empty." => "El nombre del archivo no puede quedar vacío.", "Unable to set upload directory." => "No fue posible crear el directorio de subida.", "Invalid Token" => "Token Inválido", "No file was uploaded. Unknown error" => "El archivo no fue subido. Error desconocido", @@ -18,17 +19,11 @@ $TRANSLATIONS = array( "Not enough space available" => "No hay suficiente espacio disponible", "Upload cancelled." => "La subida fue cancelada", "File upload is in progress. Leaving the page now will cancel the upload." => "La subida del archivo está en proceso. Si salís de la página ahora, la subida se cancelará.", -"URL cannot be empty." => "La URL no puede estar vacía", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Nombre de directorio inválido. El uso de \"Shared\" está reservado por ownCloud", -"Error" => "Error", +"{new_name} already exists" => "{new_name} ya existe", "Share" => "Compartir", "Delete permanently" => "Borrar permanentemente", "Rename" => "Cambiar nombre", "Pending" => "Pendientes", -"{new_name} already exists" => "{new_name} ya existe", -"replace" => "reemplazar", -"suggest name" => "sugerir nombre", -"cancel" => "cancelar", "replaced {new_name} with {old_name}" => "se reemplazó {new_name} con {old_name}", "undo" => "deshacer", "_%n folder_::_%n folders_" => array("%n carpeta","%n carpetas"), @@ -36,12 +31,12 @@ $TRANSLATIONS = array( "{dirs} and {files}" => "{carpetas} y {archivos}", "_Uploading %n file_::_Uploading %n files_" => array("Subiendo %n archivo","Subiendo %n archivos"), "'.' is an invalid file name." => "'.' es un nombre de archivo inválido.", -"File name cannot be empty." => "El nombre del archivo no puede quedar vacío.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nombre invalido, '\\', '/', '<', '>', ':', '\"', '|', '?' y '*' no están permitidos.", "Your storage is full, files can not be updated or synced anymore!" => "El almacenamiento está lleno, los archivos no se pueden seguir actualizando ni sincronizando", "Your storage is almost full ({usedSpacePercent}%)" => "El almacenamiento está casi lleno ({usedSpacePercent}%)", "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "El proceso de cifrado se ha desactivado, pero los archivos aún están encriptados. Por favor, vaya a la configuración personal para descifrar los archivos.", "Your download is being prepared. This might take some time if the files are big." => "Tu descarga se está preparando. Esto puede demorar si los archivos son muy grandes.", +"Error" => "Error", "Name" => "Nombre", "Size" => "Tamaño", "Modified" => "Modificado", @@ -57,14 +52,13 @@ $TRANSLATIONS = array( "Save" => "Guardar", "New" => "Nuevo", "Text file" => "Archivo de texto", +"New folder" => "Nueva Carpeta", "Folder" => "Carpeta", "From link" => "Desde enlace", "Deleted files" => "Archivos borrados", "Cancel upload" => "Cancelar subida", -"You don’t have write permissions here." => "No tenés permisos de escritura acá.", "Nothing in here. Upload something!" => "No hay nada. ¡Subí contenido!", "Download" => "Descargar", -"Unshare" => "Dejar de compartir", "Delete" => "Borrar", "Upload too large" => "El tamaño del archivo que querés subir es demasiado grande", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Los archivos que intentás subir sobrepasan el tamaño máximo ", diff --git a/apps/files/l10n/es_CL.php b/apps/files/l10n/es_CL.php new file mode 100644 index 00000000000..6f97758878f --- /dev/null +++ b/apps/files/l10n/es_CL.php @@ -0,0 +1,9 @@ +<?php +$TRANSLATIONS = array( +"Files" => "Archivos", +"_%n folder_::_%n folders_" => array("",""), +"_%n file_::_%n files_" => array("",""), +"_Uploading %n file_::_Uploading %n files_" => array("",""), +"Upload" => "Subir" +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files/l10n/es_MX.php b/apps/files/l10n/es_MX.php index 0157af093e9..0b7571defc7 100644 --- a/apps/files/l10n/es_MX.php +++ b/apps/files/l10n/es_MX.php @@ -1,7 +1,95 @@ <?php $TRANSLATIONS = array( -"_%n folder_::_%n folders_" => array("",""), -"_%n file_::_%n files_" => array("",""), -"_Uploading %n file_::_Uploading %n files_" => array("","") +"Could not move %s - File with this name already exists" => "No se pudo mover %s - Ya existe un archivo con ese nombre.", +"Could not move %s" => "No se pudo mover %s", +"File name cannot be empty." => "El nombre de archivo no puede estar vacío.", +"File name must not contain \"/\". Please choose a different name." => "El nombre del archivo, NO puede contener el simbolo\"/\", por favor elija un nombre diferente.", +"The name %s is already used in the folder %s. Please choose a different name." => "El nombre %s ya está en uso por la carpeta %s. Por favor elija uno diferente.", +"Not a valid source" => "No es un origen válido", +"Server is not allowed to open URLs, please check the server configuration" => "El servidor no puede acceder URLs; revise la configuración del servidor.", +"Error while downloading %s to %s" => "Error mientras se descargaba %s a %s", +"Error when creating the file" => "Error al crear el archivo", +"Folder name cannot be empty." => "El nombre de la carpeta no puede estar vacío.", +"Folder name must not contain \"/\". Please choose a different name." => "El nombre de la carpeta, NO puede contener el simbolo\"/\", por favor elija un nombre diferente.", +"Error when creating the folder" => "Error al crear la carpeta.", +"Unable to set upload directory." => "Incapaz de crear directorio de subida.", +"Invalid Token" => "Token Inválido", +"No file was uploaded. Unknown error" => "No se subió ningún archivo. Error desconocido", +"There is no error, the file uploaded with success" => "No hubo ningún problema, el archivo se subió con éxito", +"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "El archivo subido sobrepasa la directiva 'upload_max_filesize' en php.ini:", +"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "El archivo subido sobrepasa la directiva 'MAX_FILE_SIZE' especificada en el formulario HTML", +"The uploaded file was only partially uploaded" => "El archivo subido fue sólo subido parcialmente", +"No file was uploaded" => "No se subió ningún archivo", +"Missing a temporary folder" => "Falta la carpeta temporal", +"Failed to write to disk" => "Falló al escribir al disco", +"Not enough storage available" => "No hay suficiente espacio disponible", +"Upload failed. Could not get file info." => "Actualización fallida. No se pudo obtener información del archivo.", +"Upload failed. Could not find uploaded file" => "Actualización fallida. No se pudo encontrar el archivo subido", +"Invalid directory." => "Directorio inválido.", +"Files" => "Archivos", +"Unable to upload {filename} as it is a directory or has 0 bytes" => "No ha sido posible subir {filename} porque es un directorio o tiene 0 bytes", +"Not enough space available" => "No hay suficiente espacio disponible", +"Upload cancelled." => "Subida cancelada.", +"Could not get result from server." => "No se pudo obtener respuesta del servidor.", +"File upload is in progress. Leaving the page now will cancel the upload." => "La subida del archivo está en proceso. Si sale de la página ahora, la subida será cancelada.", +"URL cannot be empty" => "La dirección URL no puede estar vacía", +"In the home folder 'Shared' is a reserved filename" => "En la carpeta de inicio, 'Shared' es un nombre reservado", +"{new_name} already exists" => "{new_name} ya existe", +"Could not create file" => "No se pudo crear el archivo", +"Could not create folder" => "No se pudo crear la carpeta", +"Error fetching URL" => "Error al descargar URL.", +"Share" => "Compartir", +"Delete permanently" => "Eliminar permanentemente", +"Rename" => "Renombrar", +"Pending" => "Pendiente", +"Could not rename file" => "No se pudo renombrar el archivo", +"replaced {new_name} with {old_name}" => "reemplazado {new_name} con {old_name}", +"undo" => "deshacer", +"Error deleting file." => "Error borrando el archivo.", +"_%n folder_::_%n folders_" => array("%n carpeta","%n carpetas"), +"_%n file_::_%n files_" => array("%n archivo","%n archivos"), +"{dirs} and {files}" => "{dirs} y {files}", +"_Uploading %n file_::_Uploading %n files_" => array("Subiendo %n archivo","Subiendo %n archivos"), +"'.' is an invalid file name." => "'.' no es un nombre de archivo válido.", +"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nombre inválido, los caracteres \"\\\", \"/\", \"<\", \">\", \":\", \"\", \"|\" \"?\" y \"*\" no están permitidos ", +"Your storage is full, files can not be updated or synced anymore!" => "Su almacenamiento está lleno, ¡los archivos no se actualizarán ni sincronizarán más!", +"Your storage is almost full ({usedSpacePercent}%)" => "Su almacenamiento está casi lleno ({usedSpacePercent}%)", +"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "La aplicación de crifrado está habilitada pero tus claves no han sido inicializadas, por favor, cierra la sesión y vuelva a iniciarla de nuevo.", +"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "La clave privada no es válida para la aplicación de cifrado. Por favor, actualiza la contraseña de tu clave privada en tus ajustes personales para recuperar el acceso a tus archivos cifrados.", +"Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "El cifrado ha sido deshabilitado pero tus archivos permanecen cifrados. Por favor, ve a tus ajustes personales para descifrar tus archivos.", +"Your download is being prepared. This might take some time if the files are big." => "Su descarga está siendo preparada. Esto podría tardar algo de tiempo si los archivos son grandes.", +"Error moving file" => "Error moviendo archivo", +"Error" => "Error", +"Name" => "Nombre", +"Size" => "Tamaño", +"Modified" => "Modificado", +"Invalid folder name. Usage of 'Shared' is reserved." => "Nombre de carpeta inválido. El uso de \"Shared\" esta reservado.", +"%s could not be renamed" => "%s no pudo ser renombrado", +"Upload" => "Subir", +"File handling" => "Administración de archivos", +"Maximum upload size" => "Tamaño máximo de subida", +"max. possible: " => "máx. posible:", +"Needed for multi-file and folder downloads." => "Necesario para multi-archivo y descarga de carpetas", +"Enable ZIP-download" => "Habilitar descarga en ZIP", +"0 is unlimited" => "0 significa ilimitado", +"Maximum input size for ZIP files" => "Tamaño máximo para archivos ZIP de entrada", +"Save" => "Guardar", +"New" => "Nuevo", +"New text file" => "Nuevo archivo de texto", +"Text file" => "Archivo de texto", +"New folder" => "Nueva carpeta", +"Folder" => "Carpeta", +"From link" => "Desde enlace", +"Deleted files" => "Archivos eliminados", +"Cancel upload" => "Cancelar subida", +"You don’t have permission to upload or create files here" => "No tienes permisos para subir o crear archivos aquí.", +"Nothing in here. Upload something!" => "No hay nada aquí. ¡Suba algo!", +"Download" => "Descargar", +"Delete" => "Eliminar", +"Upload too large" => "Subida demasido grande", +"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Los archivos que estás intentando subir sobrepasan el tamaño máximo permitido en este servidor.", +"Files are being scanned, please wait." => "Los archivos están siendo escaneados, por favor espere.", +"Current scanning" => "Escaneo actual", +"Upgrading filesystem cache..." => "Actualizando caché del sistema de archivos..." ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files/l10n/et_EE.php b/apps/files/l10n/et_EE.php index 9f674b27e63..fd031527738 100644 --- a/apps/files/l10n/et_EE.php +++ b/apps/files/l10n/et_EE.php @@ -2,6 +2,16 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "Ei saa liigutada faili %s - samanimeline fail on juba olemas", "Could not move %s" => "%s liigutamine ebaõnnestus", +"File name cannot be empty." => "Faili nimi ei saa olla tühi.", +"File name must not contain \"/\". Please choose a different name." => "Faili nimi ei tohi sisaldada \"/\". Palun vali mõni teine nimi.", +"The name %s is already used in the folder %s. Please choose a different name." => "Nimi %s on juba kasutusel kataloogis %s. Palun vali mõni teine nimi.", +"Not a valid source" => "Pole korrektne lähteallikas", +"Server is not allowed to open URLs, please check the server configuration" => "Server ei võimalda URL-ide avamist, palun kontrolli serveri seadistust", +"Error while downloading %s to %s" => "Viga %s allalaadimisel %s", +"Error when creating the file" => "Viga faili loomisel", +"Folder name cannot be empty." => "Kataloogi nimi ei saa olla tühi.", +"Folder name must not contain \"/\". Please choose a different name." => "Kataloogi nimi ei tohi sisaldada \"/\". Palun vali mõni teine nimi.", +"Error when creating the folder" => "Viga kataloogi loomisel", "Unable to set upload directory." => "Üleslaadimiste kausta määramine ebaõnnestus.", "Invalid Token" => "Vigane kontrollkood", "No file was uploaded. Unknown error" => "Ühtegi faili ei laetud üles. Tundmatu viga", @@ -13,38 +23,47 @@ $TRANSLATIONS = array( "Missing a temporary folder" => "Ajutiste failide kaust puudub", "Failed to write to disk" => "Kettale kirjutamine ebaõnnestus", "Not enough storage available" => "Saadaval pole piisavalt ruumi", +"Upload failed. Could not get file info." => "Üleslaadimine ebaõnnestus. Faili info hankimine ebaõnnestus.", +"Upload failed. Could not find uploaded file" => "Üleslaadimine ebaõnnestus. Üleslaetud faili ei leitud", "Invalid directory." => "Vigane kaust.", "Files" => "Failid", +"Unable to upload {filename} as it is a directory or has 0 bytes" => "Ei saa üles laadida {filename}, kuna see on kataloog või selle suurus on 0 baiti", "Not enough space available" => "Pole piisavalt ruumi", "Upload cancelled." => "Üleslaadimine tühistati.", +"Could not get result from server." => "Serverist ei saadud tulemusi", "File upload is in progress. Leaving the page now will cancel the upload." => "Faili üleslaadimine on töös. Lehelt lahkumine katkestab selle üleslaadimise.", -"URL cannot be empty." => "URL ei saa olla tühi.", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Vigane kausta nimi. 'Shared' kasutamine on reserveeritud ownCloud poolt.", -"Error" => "Viga", +"URL cannot be empty" => "URL ei saa olla tühi", +"In the home folder 'Shared' is a reserved filename" => "Kodukataloogis 'Shared' on reserveeritud failinimi", +"{new_name} already exists" => "{new_name} on juba olemas", +"Could not create file" => "Ei suuda luua faili", +"Could not create folder" => "Ei suuda luua kataloogi", +"Error fetching URL" => "Viga URL-i haaramisel", "Share" => "Jaga", "Delete permanently" => "Kustuta jäädavalt", "Rename" => "Nimeta ümber", "Pending" => "Ootel", -"{new_name} already exists" => "{new_name} on juba olemas", -"replace" => "asenda", -"suggest name" => "soovita nime", -"cancel" => "loobu", +"Could not rename file" => "Ei suuda faili ümber nimetada", "replaced {new_name} with {old_name}" => "asendas nime {old_name} nimega {new_name}", "undo" => "tagasi", +"Error deleting file." => "Viga faili kustutamisel.", "_%n folder_::_%n folders_" => array("%n kataloog","%n kataloogi"), "_%n file_::_%n files_" => array("%n fail","%n faili"), "{dirs} and {files}" => "{dirs} ja {files}", "_Uploading %n file_::_Uploading %n files_" => array("Laadin üles %n faili","Laadin üles %n faili"), "'.' is an invalid file name." => "'.' on vigane failinimi.", -"File name cannot be empty." => "Faili nimi ei saa olla tühi.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Vigane nimi, '\\', '/', '<', '>', ':', '\"', '|', '?' ja '*' pole lubatud.", "Your storage is full, files can not be updated or synced anymore!" => "Sinu andmemaht on täis! Faile ei uuendata ega sünkroniseerita!", "Your storage is almost full ({usedSpacePercent}%)" => "Su andmemaht on peaaegu täis ({usedSpacePercent}%)", +"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "Krüpteerimisrakend on lubatud, kuid võtmeid pole lähtestatud. Palun logi välja ning uuesti sisse.", +"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "Vigane Krüpteerimisrakendi privaatvõti . Palun uuenda oma privaatse võtme parool oma personaasete seadete all taastamaks ligipääsu oma krüpteeritud failidele.", "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Krüpteering on keelatud, kuid sinu failid on endiselt krüpteeritud. Palun vaata oma personaalseid seadeid oma failide dekrüpteerimiseks.", "Your download is being prepared. This might take some time if the files are big." => "Valmistatakse allalaadimist. See võib võtta veidi aega, kui on tegu suurte failidega. ", +"Error moving file" => "Viga faili eemaldamisel", +"Error" => "Viga", "Name" => "Nimi", "Size" => "Suurus", "Modified" => "Muudetud", +"Invalid folder name. Usage of 'Shared' is reserved." => "Vigane kausta nimi. Nime 'Shared' kasutamine on reserveeritud.", "%s could not be renamed" => "%s ümbernimetamine ebaõnnestus", "Upload" => "Lae üles", "File handling" => "Failide käsitlemine", @@ -56,15 +75,16 @@ $TRANSLATIONS = array( "Maximum input size for ZIP files" => "Maksimaalne ZIP-faili sisestatava faili suurus", "Save" => "Salvesta", "New" => "Uus", +"New text file" => "Uus tekstifail", "Text file" => "Tekstifail", +"New folder" => "Uus kaust", "Folder" => "Kaust", "From link" => "Allikast", "Deleted files" => "Kustutatud failid", "Cancel upload" => "Tühista üleslaadimine", -"You don’t have write permissions here." => "Siin puudvad sul kirjutamisõigused.", +"You don’t have permission to upload or create files here" => "Sul puuduvad õigused siia failide üleslaadimiseks või tekitamiseks", "Nothing in here. Upload something!" => "Siin pole midagi. Lae midagi üles!", "Download" => "Lae alla", -"Unshare" => "Lõpeta jagamine", "Delete" => "Kustuta", "Upload too large" => "Üleslaadimine on liiga suur", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Failid, mida sa proovid üles laadida, ületab serveri poolt üleslaetavatele failidele määratud maksimaalse suuruse.", diff --git a/apps/files/l10n/eu.php b/apps/files/l10n/eu.php index 33ea47d5f04..5df480c2bc3 100644 --- a/apps/files/l10n/eu.php +++ b/apps/files/l10n/eu.php @@ -2,6 +2,15 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "Ezin da %s mugitu - Izen hau duen fitxategia dagoeneko existitzen da", "Could not move %s" => "Ezin dira fitxategiak mugitu %s", +"File name cannot be empty." => "Fitxategi izena ezin da hutsa izan.", +"File name must not contain \"/\". Please choose a different name." => "Fitxategi izenak ezin du \"/\" izan. Mesedez hautatu beste izen bat.", +"The name %s is already used in the folder %s. Please choose a different name." => "%s izena dagoeneko erabilita dago %s karpetan. Mesdez hautatu izen ezberdina.", +"Not a valid source" => "Ez da jatorri baliogarria", +"Error while downloading %s to %s" => "Errorea %s %sra deskargatzerakoan", +"Error when creating the file" => "Errorea fitxategia sortzerakoan", +"Folder name cannot be empty." => "Karpeta izena ezin da hutsa izan.", +"Folder name must not contain \"/\". Please choose a different name." => "Karpeta izenak ezin du \"/\" izan. Mesedez hautatu beste izen bat.", +"Error when creating the folder" => "Errorea karpeta sortzerakoan", "Unable to set upload directory." => "Ezin da igoera direktorioa ezarri.", "Invalid Token" => "Lekuko baliogabea", "No file was uploaded. Unknown error" => "Ez da fitxategirik igo. Errore ezezaguna", @@ -13,37 +22,46 @@ $TRANSLATIONS = array( "Missing a temporary folder" => "Aldi bateko karpeta falta da", "Failed to write to disk" => "Errore bat izan da diskoan idazterakoan", "Not enough storage available" => "Ez dago behar aina leku erabilgarri,", +"Upload failed. Could not get file info." => "Igoerak huts egin du. Ezin izan da fitxategiaren informazioa eskuratu.", +"Upload failed. Could not find uploaded file" => "Igoerak huts egin du. Ezin izan da igotako fitxategia aurkitu", "Invalid directory." => "Baliogabeko karpeta.", "Files" => "Fitxategiak", +"Unable to upload {filename} as it is a directory or has 0 bytes" => "Ezin da {filename} igo karpeta bat delako edo 0 byte dituelako", "Not enough space available" => "Ez dago leku nahikorik.", "Upload cancelled." => "Igoera ezeztatuta", +"Could not get result from server." => "Ezin da zerbitzaritik emaitzik lortu", "File upload is in progress. Leaving the page now will cancel the upload." => "Fitxategien igoera martxan da. Orria orain uzteak igoera ezeztatutko du.", -"URL cannot be empty." => "URLa ezin da hutsik egon.", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Karpeta izne baliogabea. \"Shared\" karpeta erabilpena OwnCloudentzat erreserbaturik dago.", -"Error" => "Errorea", +"URL cannot be empty" => "URLa ezin da hutsik egon", +"In the home folder 'Shared' is a reserved filename" => "Etxeko (home) karpetan 'Shared' erreserbatutako fitxategi izena da", +"{new_name} already exists" => "{new_name} dagoeneko existitzen da", +"Could not create file" => "Ezin izan da fitxategia sortu", +"Could not create folder" => "Ezin izan da karpeta sortu", "Share" => "Elkarbanatu", "Delete permanently" => "Ezabatu betirako", "Rename" => "Berrizendatu", "Pending" => "Zain", -"{new_name} already exists" => "{new_name} dagoeneko existitzen da", -"replace" => "ordeztu", -"suggest name" => "aholkatu izena", -"cancel" => "ezeztatu", +"Could not rename file" => "Ezin izan da fitxategia berrizendatu", "replaced {new_name} with {old_name}" => " {new_name}-k {old_name} ordezkatu du", "undo" => "desegin", +"Error deleting file." => "Errorea fitxategia ezabatzerakoan.", "_%n folder_::_%n folders_" => array("karpeta %n","%n karpeta"), "_%n file_::_%n files_" => array("fitxategi %n","%n fitxategi"), +"{dirs} and {files}" => "{dirs} eta {files}", "_Uploading %n file_::_Uploading %n files_" => array("Fitxategi %n igotzen","%n fitxategi igotzen"), "'.' is an invalid file name." => "'.' ez da fitxategi izen baliogarria.", -"File name cannot be empty." => "Fitxategi izena ezin da hutsa izan.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "IZen aliogabea, '\\', '/', '<', '>', ':', '\"', '|', '?' eta '*' ez daude baimenduta.", "Your storage is full, files can not be updated or synced anymore!" => "Zure biltegiratzea beterik dago, ezingo duzu aurrerantzean fitxategirik igo edo sinkronizatu!", "Your storage is almost full ({usedSpacePercent}%)" => "Zure biltegiratzea nahiko beterik dago (%{usedSpacePercent})", +"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "Enkriptazio aplikazioa gaituta dago baina zure gakoak ez daude konfiguratuta, mesedez saioa bukatu eta berriro hasi", +"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "Enkriptazio aplikaziorako gako pribatu okerra. Mesedez eguneratu zure gako pribatuaren pasahitza zure ezarpen pertsonaletan zure enkriptatuko fitxategietarako sarrera berreskuratzeko.", "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Enkriptazioa desgaitua izan da baina zure fitxategiak oraindik enkriptatuta daude. Mesedez jo zure ezarpen pertsonaletara zure fitxategiak dekodifikatzeko.", "Your download is being prepared. This might take some time if the files are big." => "Zure deskarga prestatu egin behar da. Denbora bat har lezake fitxategiak handiak badira. ", +"Error moving file" => "Errorea fitxategia mugitzean", +"Error" => "Errorea", "Name" => "Izena", "Size" => "Tamaina", "Modified" => "Aldatuta", +"Invalid folder name. Usage of 'Shared' is reserved." => "Baliogabeako karpeta izena. 'Shared' izena erreserbatuta dago.", "%s could not be renamed" => "%s ezin da berrizendatu", "Upload" => "Igo", "File handling" => "Fitxategien kudeaketa", @@ -55,15 +73,16 @@ $TRANSLATIONS = array( "Maximum input size for ZIP files" => "ZIP fitxategien gehienezko tamaina", "Save" => "Gorde", "New" => "Berria", +"New text file" => "Testu fitxategi berria", "Text file" => "Testu fitxategia", +"New folder" => "Karpeta berria", "Folder" => "Karpeta", "From link" => "Estekatik", "Deleted files" => "Ezabatutako fitxategiak", "Cancel upload" => "Ezeztatu igoera", -"You don’t have write permissions here." => "Ez duzu hemen idazteko baimenik.", +"You don’t have permission to upload or create files here" => "Ez duzu fitxategiak hona igotzeko edo hemen sortzeko baimenik", "Nothing in here. Upload something!" => "Ez dago ezer. Igo zerbait!", "Download" => "Deskargatu", -"Unshare" => "Ez elkarbanatu", "Delete" => "Ezabatu", "Upload too large" => "Igoera handiegia da", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Igotzen saiatzen ari zaren fitxategiak zerbitzari honek igotzeko onartzen duena baino handiagoak dira.", diff --git a/apps/files/l10n/fa.php b/apps/files/l10n/fa.php index 46d7cfe73ef..4f3257bc075 100644 --- a/apps/files/l10n/fa.php +++ b/apps/files/l10n/fa.php @@ -2,6 +2,7 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "%s نمی تواند حرکت کند - در حال حاضر پرونده با این نام وجود دارد. ", "Could not move %s" => "%s نمی تواند حرکت کند ", +"File name cannot be empty." => "نام پرونده نمی تواند خالی باشد.", "Unable to set upload directory." => "قادر به تنظیم پوشه آپلود نمی باشد.", "Invalid Token" => "رمز نامعتبر", "No file was uploaded. Unknown error" => "هیچ فایلی آپلود نشد.خطای ناشناس", @@ -18,28 +19,22 @@ $TRANSLATIONS = array( "Not enough space available" => "فضای کافی در دسترس نیست", "Upload cancelled." => "بار گذاری لغو شد", "File upload is in progress. Leaving the page now will cancel the upload." => "آپلودکردن پرونده در حال پیشرفت است. در صورت خروج از صفحه آپلود لغو میگردد. ", -"URL cannot be empty." => "URL نمی تواند خالی باشد.", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "نام پوشه نامعتبر است. استفاده از 'به اشتراک گذاشته شده' متعلق به ownCloud میباشد.", -"Error" => "خطا", +"{new_name} already exists" => "{نام _جدید} در حال حاضر وجود دارد.", "Share" => "اشتراکگذاری", "Delete permanently" => "حذف قطعی", "Rename" => "تغییرنام", "Pending" => "در انتظار", -"{new_name} already exists" => "{نام _جدید} در حال حاضر وجود دارد.", -"replace" => "جایگزین", -"suggest name" => "پیشنهاد نام", -"cancel" => "لغو", "replaced {new_name} with {old_name}" => "{نام_جدید} با { نام_قدیمی} جایگزین شد.", "undo" => "بازگشت", "_%n folder_::_%n folders_" => array(""), "_%n file_::_%n files_" => array(""), "_Uploading %n file_::_Uploading %n files_" => array(""), "'.' is an invalid file name." => "'.' یک نام پرونده نامعتبر است.", -"File name cannot be empty." => "نام پرونده نمی تواند خالی باشد.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "نام نامعتبر ، '\\', '/', '<', '>', ':', '\"', '|', '?' و '*' مجاز نمی باشند.", "Your storage is full, files can not be updated or synced anymore!" => "فضای ذخیره ی شما کاملا پر است، بیش از این فایلها بهنگام یا همگام سازی نمی توانند بشوند!", "Your storage is almost full ({usedSpacePercent}%)" => "فضای ذخیره ی شما تقریبا پر است ({usedSpacePercent}%)", "Your download is being prepared. This might take some time if the files are big." => "دانلود شما در حال آماده شدن است. در صورتیکه پرونده ها بزرگ باشند ممکن است مدتی طول بکشد.", +"Error" => "خطا", "Name" => "نام", "Size" => "اندازه", "Modified" => "تاریخ", @@ -55,14 +50,13 @@ $TRANSLATIONS = array( "Save" => "ذخیره", "New" => "جدید", "Text file" => "فایل متنی", +"New folder" => "پوشه جدید", "Folder" => "پوشه", "From link" => "از پیوند", "Deleted files" => "فایل های حذف شده", "Cancel upload" => "متوقف کردن بار گذاری", -"You don’t have write permissions here." => "شما اجازه ی نوشتن در اینجا را ندارید", "Nothing in here. Upload something!" => "اینجا هیچ چیز نیست.", "Download" => "دانلود", -"Unshare" => "لغو اشتراک", "Delete" => "حذف", "Upload too large" => "سایز فایل برای آپلود زیاد است(م.تنظیمات در php.ini)", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "فایلها بیش از حد تعیین شده در این سرور هستند\nمترجم:با تغییر فایل php,ini میتوان این محدودیت را برطرف کرد", diff --git a/apps/files/l10n/fi_FI.php b/apps/files/l10n/fi_FI.php index 5345bad902b..d1241b77da0 100644 --- a/apps/files/l10n/fi_FI.php +++ b/apps/files/l10n/fi_FI.php @@ -2,15 +2,26 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "Kohteen %s siirto ei onnistunut - Tiedosto samalla nimellä on jo olemassa", "Could not move %s" => "Kohteen %s siirto ei onnistunut", +"File name cannot be empty." => "Tiedoston nimi ei voi olla tyhjä.", +"File name must not contain \"/\". Please choose a different name." => "Tiedoston nimessä ei saa olla merkkiä \"/\". Valitse toinen nimi.", +"The name %s is already used in the folder %s. Please choose a different name." => "Nimi %s on jo käytössä kansiossa %s. Valitse toinen nimi.", +"Not a valid source" => "Virheellinen lähde", +"Server is not allowed to open URLs, please check the server configuration" => "Palvelimen ei ole lupa avata verkko-osoitteita. Tarkista palvelimen asetukset", +"Error while downloading %s to %s" => "Virhe ladatessa kohdetta %s sijaintiin %s", +"Error when creating the file" => "Virhe tiedostoa luotaessa", +"Folder name cannot be empty." => "Kansion nimi ei voi olla tyhjä.", +"Folder name must not contain \"/\". Please choose a different name." => "Kansion nimessä ei saa olla merkkiä \"/\". Valitse toinen nimi.", +"Error when creating the folder" => "Virhe kansiota luotaessa", "No file was uploaded. Unknown error" => "Tiedostoa ei lähetetty. Tuntematon virhe", "There is no error, the file uploaded with success" => "Ei virheitä, tiedosto lähetettiin onnistuneesti", "The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Lähetetyn tiedoston koko ylittää php.ini-tiedoston upload_max_filesize-säännön:", -"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Ladattavan tiedoston maksimikoko ylittää MAX_FILE_SIZE dirketiivin, joka on määritelty HTML-lomakkeessa", +"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Lähetettävän tiedoston enimmäiskoko ylittää HTML-lomakkeessa määritellyn MAX_FILE_SIZE-säännön", "The uploaded file was only partially uploaded" => "Tiedoston lähetys onnistui vain osittain", "No file was uploaded" => "Yhtäkään tiedostoa ei lähetetty", "Missing a temporary folder" => "Tilapäiskansio puuttuu", "Failed to write to disk" => "Levylle kirjoitus epäonnistui", "Not enough storage available" => "Tallennustilaa ei ole riittävästi käytettävissä", +"Upload failed. Could not find uploaded file" => "Lähetys epäonnistui. Lähettävää tiedostoa ei löydetty.", "Invalid directory." => "Virheellinen kansio.", "Files" => "Tiedostot", "Unable to upload {filename} as it is a directory or has 0 bytes" => "Kohdetta {filename} ei voi lähettää, koska se on joko kansio tai sen koko on 0 tavua", @@ -18,31 +29,35 @@ $TRANSLATIONS = array( "Upload cancelled." => "Lähetys peruttu.", "Could not get result from server." => "Tuloksien saaminen palvelimelta ei onnistunut.", "File upload is in progress. Leaving the page now will cancel the upload." => "Tiedoston lähetys on meneillään. Sivulta poistuminen nyt peruu tiedoston lähetyksen.", -"URL cannot be empty." => "Verkko-osoite ei voi olla tyhjä", -"Error" => "Virhe", +"URL cannot be empty" => "Osoite ei voi olla tyhjä", +"{new_name} already exists" => "{new_name} on jo olemassa", +"Could not create file" => "Tiedoston luominen epäonnistui", +"Could not create folder" => "Kansion luominen epäonnistui", +"Error fetching URL" => "Virhe noutaessa verkko-osoitetta", "Share" => "Jaa", "Delete permanently" => "Poista pysyvästi", "Rename" => "Nimeä uudelleen", "Pending" => "Odottaa", -"{new_name} already exists" => "{new_name} on jo olemassa", -"replace" => "korvaa", -"suggest name" => "ehdota nimeä", -"cancel" => "peru", +"Could not rename file" => "Tiedoston nimeäminen uudelleen epäonnistui", "undo" => "kumoa", +"Error deleting file." => "Virhe tiedostoa poistaessa.", "_%n folder_::_%n folders_" => array("%n kansio","%n kansiota"), "_%n file_::_%n files_" => array("%n tiedosto","%n tiedostoa"), "{dirs} and {files}" => "{dirs} ja {files}", "_Uploading %n file_::_Uploading %n files_" => array("Lähetetään %n tiedosto","Lähetetään %n tiedostoa"), "'.' is an invalid file name." => "'.' on virheellinen nimi tiedostolle.", -"File name cannot be empty." => "Tiedoston nimi ei voi olla tyhjä.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Virheellinen nimi, merkit '\\', '/', '<', '>', ':', '\"', '|', '?' ja '*' eivät ole sallittuja.", "Your storage is full, files can not be updated or synced anymore!" => "Tallennustila on loppu, tiedostoja ei voi enää päivittää tai synkronoida!", "Your storage is almost full ({usedSpacePercent}%)" => "Tallennustila on melkein loppu ({usedSpacePercent}%)", +"Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Salaus poistettiin käytöstä, mutta tiedostosi ovat edelleen salattuina. Siirry henkilökohtaisiin asetuksiin avataksesi tiedostojesi salauksen.", "Your download is being prepared. This might take some time if the files are big." => "Lataustasi valmistellaan. Tämä saattaa kestää hetken, jos tiedostot ovat suuria kooltaan.", "Error moving file" => "Virhe tiedostoa siirrettäessä", +"Error" => "Virhe", "Name" => "Nimi", "Size" => "Koko", "Modified" => "Muokattu", +"Invalid folder name. Usage of 'Shared' is reserved." => "Virheellinen kansion nimi. 'Shared':n käyttö on varattu.", +"%s could not be renamed" => "kohteen %s nimeäminen uudelleen epäonnistui", "Upload" => "Lähetä", "File handling" => "Tiedostonhallinta", "Maximum upload size" => "Lähetettävän tiedoston suurin sallittu koko", @@ -53,15 +68,16 @@ $TRANSLATIONS = array( "Maximum input size for ZIP files" => "ZIP-tiedostojen enimmäiskoko", "Save" => "Tallenna", "New" => "Uusi", +"New text file" => "Uusi tekstitiedosto", "Text file" => "Tekstitiedosto", +"New folder" => "Uusi kansio", "Folder" => "Kansio", "From link" => "Linkistä", "Deleted files" => "Poistetut tiedostot", "Cancel upload" => "Peru lähetys", -"You don’t have write permissions here." => "Tunnuksellasi ei ole kirjoitusoikeuksia tänne.", +"You don’t have permission to upload or create files here" => "Käyttöoikeutesi eivät riitä tiedostojen lähettämiseen tai kansioiden luomiseen tähän sijaintiin", "Nothing in here. Upload something!" => "Täällä ei ole mitään. Lähetä tänne jotakin!", "Download" => "Lataa", -"Unshare" => "Peru jakaminen", "Delete" => "Poista", "Upload too large" => "Lähetettävä tiedosto on liian suuri", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Lähetettäväksi valitsemasi tiedostot ylittävät palvelimen salliman tiedostokoon rajan.", diff --git a/apps/files/l10n/fr.php b/apps/files/l10n/fr.php index 03505a2a269..73b89434778 100644 --- a/apps/files/l10n/fr.php +++ b/apps/files/l10n/fr.php @@ -2,6 +2,16 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "Impossible de déplacer %s - Un fichier possédant ce nom existe déjà", "Could not move %s" => "Impossible de déplacer %s", +"File name cannot be empty." => "Le nom de fichier ne peut être vide.", +"File name must not contain \"/\". Please choose a different name." => "Le nom de fichier ne doit pas contenir \"/\". Merci de choisir un nom différent.", +"The name %s is already used in the folder %s. Please choose a different name." => "Le nom %s est déjà utilisé dans le dossier %s. Merci de choisir un nom différent.", +"Not a valid source" => "La source n'est pas valide", +"Server is not allowed to open URLs, please check the server configuration" => "Le serveur n'est pas autorisé à ouvrir des URL, veuillez vérifier la configuration du serveur", +"Error while downloading %s to %s" => "Erreur pendant le téléchargement de %s à %s", +"Error when creating the file" => "Erreur pendant la création du fichier", +"Folder name cannot be empty." => "Le nom de dossier ne peux pas être vide.", +"Folder name must not contain \"/\". Please choose a different name." => "Le nom de dossier ne doit pas contenir \"/\". Merci de choisir un nom différent.", +"Error when creating the folder" => "Erreur pendant la création du dossier", "Unable to set upload directory." => "Impossible de définir le dossier pour l'upload, charger.", "Invalid Token" => "Jeton non valide", "No file was uploaded. Unknown error" => "Aucun fichier n'a été envoyé. Erreur inconnue", @@ -22,34 +32,38 @@ $TRANSLATIONS = array( "Upload cancelled." => "Envoi annulé.", "Could not get result from server." => "Ne peut recevoir les résultats du serveur.", "File upload is in progress. Leaving the page now will cancel the upload." => "L'envoi du fichier est en cours. Quitter cette page maintenant annulera l'envoi du fichier.", -"URL cannot be empty." => "L'URL ne peut-être vide", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Nom de dossier invalide. L'utilisation du mot 'Shared' est réservée à Owncloud", -"Error" => "Erreur", +"URL cannot be empty" => "L'URL ne peut pas être vide", +"In the home folder 'Shared' is a reserved filename" => "Dans le dossier home, 'Partagé' est un nom de fichier réservé", +"{new_name} already exists" => "{new_name} existe déjà", +"Could not create file" => "Impossible de créer le fichier", +"Could not create folder" => "Impossible de créer le dossier", +"Error fetching URL" => "Erreur d'accès à l'URL", "Share" => "Partager", "Delete permanently" => "Supprimer de façon définitive", "Rename" => "Renommer", "Pending" => "En attente", -"{new_name} already exists" => "{new_name} existe déjà", -"replace" => "remplacer", -"suggest name" => "Suggérer un nom", -"cancel" => "annuler", +"Could not rename file" => "Impossible de renommer le fichier", "replaced {new_name} with {old_name}" => "{new_name} a été remplacé par {old_name}", "undo" => "annuler", +"Error deleting file." => "Erreur pendant la suppression du fichier.", "_%n folder_::_%n folders_" => array("%n dossier","%n dossiers"), "_%n file_::_%n files_" => array("%n fichier","%n fichiers"), -"{dirs} and {files}" => "{dir} et {files}", +"{dirs} and {files}" => "{dirs} et {files}", "_Uploading %n file_::_Uploading %n files_" => array("Téléversement de %n fichier","Téléversement de %n fichiers"), "'.' is an invalid file name." => "'.' n'est pas un nom de fichier valide.", -"File name cannot be empty." => "Le nom de fichier ne peut être vide.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nom invalide, les caractères '\\', '/', '<', '>', ':', '\"', '|', '?' et '*' ne sont pas autorisés.", "Your storage is full, files can not be updated or synced anymore!" => "Votre espage de stockage est plein, les fichiers ne peuvent plus être téléversés ou synchronisés !", "Your storage is almost full ({usedSpacePercent}%)" => "Votre espace de stockage est presque plein ({usedSpacePercent}%)", +"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "L'application de chiffrement est activée mais vos clés ne sont pas initialisées, veuillez vous déconnecter et ensuite vous reconnecter.", +"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "Votre clef privée pour l'application de chiffrement est invalide ! Veuillez mettre à jour le mot de passe de votre clef privée dans vos paramètres personnels pour récupérer l'accès à vos fichiers chiffrés.", "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Le chiffrement était désactivé mais vos fichiers sont toujours chiffrés. Veuillez vous rendre sur vos Paramètres personnels pour déchiffrer vos fichiers.", "Your download is being prepared. This might take some time if the files are big." => "Votre téléchargement est cours de préparation. Ceci peut nécessiter un certain temps si les fichiers sont volumineux.", "Error moving file" => "Erreur lors du déplacement du fichier", +"Error" => "Erreur", "Name" => "Nom", "Size" => "Taille", "Modified" => "Modifié", +"Invalid folder name. Usage of 'Shared' is reserved." => "Nom de dossier invalide. L'utilisation du mot 'Shared' est réservée.", "%s could not be renamed" => "%s ne peut être renommé", "Upload" => "Envoyer", "File handling" => "Gestion des fichiers", @@ -61,15 +75,16 @@ $TRANSLATIONS = array( "Maximum input size for ZIP files" => "Taille maximale pour les fichiers ZIP", "Save" => "Sauvegarder", "New" => "Nouveau", +"New text file" => "Nouveau fichier texte", "Text file" => "Fichier texte", +"New folder" => "Nouveau dossier", "Folder" => "Dossier", "From link" => "Depuis le lien", "Deleted files" => "Fichiers supprimés", "Cancel upload" => "Annuler l'envoi", -"You don’t have write permissions here." => "Vous n'avez pas le droit d'écriture ici.", +"You don’t have permission to upload or create files here" => "Vous n'avez pas la permission de téléverser ou de créer des fichiers ici", "Nothing in here. Upload something!" => "Il n'y a rien ici ! Envoyez donc quelque chose :)", "Download" => "Télécharger", -"Unshare" => "Ne plus partager", "Delete" => "Supprimer", "Upload too large" => "Téléversement trop volumineux", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Les fichiers que vous essayez d'envoyer dépassent la taille maximale permise par ce serveur.", diff --git a/apps/files/l10n/fr_CA.php b/apps/files/l10n/fr_CA.php new file mode 100644 index 00000000000..3c711e6b78a --- /dev/null +++ b/apps/files/l10n/fr_CA.php @@ -0,0 +1,7 @@ +<?php +$TRANSLATIONS = array( +"_%n folder_::_%n folders_" => array("",""), +"_%n file_::_%n files_" => array("",""), +"_Uploading %n file_::_Uploading %n files_" => array("","") +); +$PLURAL_FORMS = "nplurals=2; plural=(n > 1);"; diff --git a/apps/files/l10n/gl.php b/apps/files/l10n/gl.php index 2766478650a..1d22691d93c 100644 --- a/apps/files/l10n/gl.php +++ b/apps/files/l10n/gl.php @@ -1,7 +1,17 @@ <?php $TRANSLATIONS = array( -"Could not move %s - File with this name already exists" => "Non se moveu %s - Xa existe un ficheiro con ese nome.", +"Could not move %s - File with this name already exists" => "Non foi posíbel mover %s; Xa existe un ficheiro con ese nome.", "Could not move %s" => "Non foi posíbel mover %s", +"File name cannot be empty." => "O nome de ficheiro non pode estar baleiro", +"File name must not contain \"/\". Please choose a different name." => "O nome do ficheiro non pode conter «/». Escolla outro nome.", +"The name %s is already used in the folder %s. Please choose a different name." => "Xa existe o nome %s no cartafol %s. Escolla outro nome.", +"Not a valid source" => "Esta orixe non é correcta", +"Server is not allowed to open URLs, please check the server configuration" => "O servidor non ten permisos para abrir os enderezos URL, comprobe a configuración do servidor", +"Error while downloading %s to %s" => "Produciuse un erro ao descargar %s en %s", +"Error when creating the file" => "Produciuse un erro ao crear o ficheiro", +"Folder name cannot be empty." => "O nome de cartafol non pode estar baleiro.", +"Folder name must not contain \"/\". Please choose a different name." => "O nome do cartafol non pode conter «/». Escolla outro nome.", +"Error when creating the folder" => "Produciuse un erro ao crear o cartafol", "Unable to set upload directory." => "Non é posíbel configurar o directorio de envíos.", "Invalid Token" => "Marca incorrecta", "No file was uploaded. Unknown error" => "Non se enviou ningún ficheiro. Produciuse un erro descoñecido.", @@ -22,34 +32,38 @@ $TRANSLATIONS = array( "Upload cancelled." => "Envío cancelado.", "Could not get result from server." => "Non foi posíbel obter o resultado do servidor.", "File upload is in progress. Leaving the page now will cancel the upload." => "O envío do ficheiro está en proceso. Saír agora da páxina cancelará o envío.", -"URL cannot be empty." => "O URL non pode quedar baleiro.", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Nome de cartafol incorrecto. O uso de «Compartido» e «Shared» está reservado para o ownClod", -"Error" => "Erro", +"URL cannot be empty" => "O URL non pode quedar en branco.", +"In the home folder 'Shared' is a reserved filename" => "«Shared» dentro do cartafol persoal é un nome reservado", +"{new_name} already exists" => "Xa existe un {new_name}", +"Could not create file" => "Non foi posíbel crear o ficheiro", +"Could not create folder" => "Non foi posíbel crear o cartafol", +"Error fetching URL" => "Produciuse un erro ao obter o URL", "Share" => "Compartir", "Delete permanently" => "Eliminar permanentemente", "Rename" => "Renomear", "Pending" => "Pendentes", -"{new_name} already exists" => "Xa existe un {new_name}", -"replace" => "substituír", -"suggest name" => "suxerir nome", -"cancel" => "cancelar", +"Could not rename file" => "Non foi posíbel renomear o ficheiro", "replaced {new_name} with {old_name}" => "substituír {new_name} por {old_name}", "undo" => "desfacer", +"Error deleting file." => "Produciuse un erro ao eliminar o ficheiro.", "_%n folder_::_%n folders_" => array("%n cartafol","%n cartafoles"), "_%n file_::_%n files_" => array("%n ficheiro","%n ficheiros"), "{dirs} and {files}" => "{dirs} e {files}", "_Uploading %n file_::_Uploading %n files_" => array("Cargando %n ficheiro","Cargando %n ficheiros"), "'.' is an invalid file name." => "«.» é un nome de ficheiro incorrecto", -"File name cannot be empty." => "O nome de ficheiro non pode estar baleiro", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nome incorrecto, non se permite «\\», «/», «<», «>», «:», «\"», «|», «?» e «*».", "Your storage is full, files can not be updated or synced anymore!" => "O seu espazo de almacenamento está cheo, non é posíbel actualizar ou sincronizar máis os ficheiros!", "Your storage is almost full ({usedSpacePercent}%)" => "O seu espazo de almacenamento está case cheo ({usedSpacePercent}%)", +"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "O aplicativo de cifrado está activado, mais as chaves non foron inicializadas, saia da sesión e volva a acceder de novo", +"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "A chave privada para o aplicativo de cifrado non é correcta. Actualice o contrasinal da súa chave privada nos seus axustes persoais para recuperar o acceso aos seus ficheiros cifrados.", "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "O cifrado foi desactivado, mais os ficheiros están cifrados. Vaia á configuración persoal para descifrar os ficheiros.", "Your download is being prepared. This might take some time if the files are big." => "Está a prepararse a súa descarga. Isto pode levar bastante tempo se os ficheiros son grandes.", "Error moving file" => "Produciuse un erro ao mover o ficheiro", +"Error" => "Erro", "Name" => "Nome", "Size" => "Tamaño", "Modified" => "Modificado", +"Invalid folder name. Usage of 'Shared' is reserved." => "Nome de cartafol non válido. O uso de «Shared» está reservado.", "%s could not be renamed" => "%s non pode cambiar de nome", "Upload" => "Enviar", "File handling" => "Manexo de ficheiro", @@ -61,15 +75,16 @@ $TRANSLATIONS = array( "Maximum input size for ZIP files" => "Tamaño máximo de descarga para os ficheiros ZIP", "Save" => "Gardar", "New" => "Novo", +"New text file" => "Ficheiro novo de texto", "Text file" => "Ficheiro de texto", +"New folder" => "Novo cartafol", "Folder" => "Cartafol", "From link" => "Desde a ligazón", "Deleted files" => "Ficheiros eliminados", "Cancel upload" => "Cancelar o envío", -"You don’t have write permissions here." => "Non ten permisos para escribir aquí.", +"You don’t have permission to upload or create files here" => "Non ten permisos para enviar ou crear ficheiros aquí.", "Nothing in here. Upload something!" => "Aquí non hai nada. Envíe algo.", "Download" => "Descargar", -"Unshare" => "Deixar de compartir", "Delete" => "Eliminar", "Upload too large" => "Envío demasiado grande", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Os ficheiros que tenta enviar exceden do tamaño máximo permitido neste servidor", diff --git a/apps/files/l10n/he.php b/apps/files/l10n/he.php index bc7ecdb0716..0cdb178254e 100644 --- a/apps/files/l10n/he.php +++ b/apps/files/l10n/he.php @@ -2,6 +2,7 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "לא ניתן להעביר את %s - קובץ בשם הזה כבר קיים", "Could not move %s" => "לא ניתן להעביר את %s", +"File name cannot be empty." => "שם קובץ אינו יכול להיות ריק", "No file was uploaded. Unknown error" => "לא הועלה קובץ. טעות בלתי מזוהה.", "There is no error, the file uploaded with success" => "לא התרחשה שגיאה, הקובץ הועלה בהצלחה", "The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "הקבצים שנשלחו חורגים מהגודל שצוין בהגדרה upload_max_filesize שבקובץ php.ini:", @@ -11,26 +12,25 @@ $TRANSLATIONS = array( "Missing a temporary folder" => "תקיה זמנית חסרה", "Failed to write to disk" => "הכתיבה לכונן נכשלה", "Not enough storage available" => "אין די שטח פנוי באחסון", +"Upload failed. Could not get file info." => "העלאה נכשלה. לא ניתן להשיג את פרטי הקובץ.", "Invalid directory." => "תיקייה שגויה.", "Files" => "קבצים", "Upload cancelled." => "ההעלאה בוטלה.", +"Could not get result from server." => "לא ניתן לגשת לתוצאות מהשרת.", "File upload is in progress. Leaving the page now will cancel the upload." => "מתבצעת כעת העלאת קבצים. עזיבה של העמוד תבטל את ההעלאה.", -"URL cannot be empty." => "קישור אינו יכול להיות ריק.", -"Error" => "שגיאה", +"{new_name} already exists" => "{new_name} כבר קיים", "Share" => "שתף", "Delete permanently" => "מחק לצמיתות", "Rename" => "שינוי שם", "Pending" => "ממתין", -"{new_name} already exists" => "{new_name} כבר קיים", -"replace" => "החלפה", -"suggest name" => "הצעת שם", -"cancel" => "ביטול", "replaced {new_name} with {old_name}" => "{new_name} הוחלף ב־{old_name}", "undo" => "ביטול", "_%n folder_::_%n folders_" => array("",""), "_%n file_::_%n files_" => array("",""), "_Uploading %n file_::_Uploading %n files_" => array("",""), "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "השם שגוי, אסור להשתמש בתווים '\\', '/', '<', '>', ':', '\"', '|', '?' ו־'*'.", +"Your storage is almost full ({usedSpacePercent}%)" => "שטח האחסון שלך כמעט מלא ({usedSpacePercent}%)", +"Error" => "שגיאה", "Name" => "שם", "Size" => "גודל", "Modified" => "זמן שינוי", @@ -47,10 +47,10 @@ $TRANSLATIONS = array( "Text file" => "קובץ טקסט", "Folder" => "תיקייה", "From link" => "מקישור", +"Deleted files" => "קבצים שנמחקו", "Cancel upload" => "ביטול ההעלאה", "Nothing in here. Upload something!" => "אין כאן שום דבר. אולי ברצונך להעלות משהו?", "Download" => "הורדה", -"Unshare" => "הסר שיתוף", "Delete" => "מחיקה", "Upload too large" => "העלאה גדולה מידי", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "הקבצים שניסית להעלות חרגו מהגודל המקסימלי להעלאת קבצים על שרת זה.", diff --git a/apps/files/l10n/hi.php b/apps/files/l10n/hi.php index 549c928320d..ae01bfc47e1 100644 --- a/apps/files/l10n/hi.php +++ b/apps/files/l10n/hi.php @@ -1,10 +1,10 @@ <?php $TRANSLATIONS = array( -"Error" => "त्रुटि", "Share" => "साझा करें", "_%n folder_::_%n folders_" => array("",""), "_%n file_::_%n files_" => array("",""), "_Uploading %n file_::_Uploading %n files_" => array("",""), +"Error" => "त्रुटि", "Upload" => "अपलोड ", "Save" => "सहेजें" ); diff --git a/apps/files/l10n/hr.php b/apps/files/l10n/hr.php index 60f1da84409..5048a15c8bb 100644 --- a/apps/files/l10n/hr.php +++ b/apps/files/l10n/hr.php @@ -9,17 +9,14 @@ $TRANSLATIONS = array( "Files" => "Datoteke", "Upload cancelled." => "Slanje poništeno.", "File upload is in progress. Leaving the page now will cancel the upload." => "Učitavanje datoteke. Napuštanjem stranice će prekinuti učitavanje.", -"Error" => "Greška", "Share" => "Podijeli", "Rename" => "Promjeni ime", "Pending" => "U tijeku", -"replace" => "zamjeni", -"suggest name" => "predloži ime", -"cancel" => "odustani", "undo" => "vrati", "_%n folder_::_%n folders_" => array("","",""), "_%n file_::_%n files_" => array("","",""), "_Uploading %n file_::_Uploading %n files_" => array("","",""), +"Error" => "Greška", "Name" => "Ime", "Size" => "Veličina", "Modified" => "Zadnja promjena", @@ -38,7 +35,6 @@ $TRANSLATIONS = array( "Cancel upload" => "Prekini upload", "Nothing in here. Upload something!" => "Nema ničega u ovoj mapi. Pošalji nešto!", "Download" => "Preuzimanje", -"Unshare" => "Makni djeljenje", "Delete" => "Obriši", "Upload too large" => "Prijenos je preobiman", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Datoteke koje pokušavate prenijeti prelaze maksimalnu veličinu za prijenos datoteka na ovom poslužitelju.", diff --git a/apps/files/l10n/hu_HU.php b/apps/files/l10n/hu_HU.php index 4dd6a13d320..22c3926ed1c 100644 --- a/apps/files/l10n/hu_HU.php +++ b/apps/files/l10n/hu_HU.php @@ -2,6 +2,16 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "%s áthelyezése nem sikerült - már létezik másik fájl ezzel a névvel", "Could not move %s" => "Nem sikerült %s áthelyezése", +"File name cannot be empty." => "A fájlnév nem lehet semmi.", +"File name must not contain \"/\". Please choose a different name." => "Az állomány neve nem tartalmazhatja a \"/\" karaktert. Kérem válasszon másik nevet!", +"The name %s is already used in the folder %s. Please choose a different name." => "A %s név már létezik a %s mappában. Kérem válasszon másik nevet!", +"Not a valid source" => "A kiinduló állomány érvénytelen", +"Server is not allowed to open URLs, please check the server configuration" => "A kiszolgálón nincs engedélyezve URL-ek megnyitása, kérem ellenőrizze a beállításokat", +"Error while downloading %s to %s" => "Hiba történt miközben %s-t letöltöttük %s-be", +"Error when creating the file" => "Hiba történt az állomány létrehozásakor", +"Folder name cannot be empty." => "A mappa neve nem maradhat kitöltetlenül", +"Folder name must not contain \"/\". Please choose a different name." => "A mappa neve nem tartalmazhatja a \"/\" karaktert. Kérem válasszon másik nevet!", +"Error when creating the folder" => "Hiba történt a mappa létrehozásakor", "Unable to set upload directory." => "Nem található a mappa, ahova feltölteni szeretne.", "Invalid Token" => "Hibás mappacím", "No file was uploaded. Unknown error" => "Nem történt feltöltés. Ismeretlen hiba", @@ -22,34 +32,38 @@ $TRANSLATIONS = array( "Upload cancelled." => "A feltöltést megszakítottuk.", "Could not get result from server." => "A kiszolgálótól nem kapható meg az eredmény.", "File upload is in progress. Leaving the page now will cancel the upload." => "Fájlfeltöltés van folyamatban. Az oldal elhagyása megszakítja a feltöltést.", -"URL cannot be empty." => "Az URL nem lehet semmi.", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Érvénytelen mappanév. A 'Shared' az ownCloud számára fenntartott elnevezés", -"Error" => "Hiba", +"URL cannot be empty" => "Az URL-cím nem maradhat kitöltetlenül", +"In the home folder 'Shared' is a reserved filename" => "A kiindulási mappában a 'Shared' egy belső használatra fenntartott név", +"{new_name} already exists" => "{new_name} már létezik", +"Could not create file" => "Az állomány nem hozható létre", +"Could not create folder" => "A mappa nem hozható létre", +"Error fetching URL" => "A megadott URL-ről nem sikerül adatokat kapni", "Share" => "Megosztás", "Delete permanently" => "Végleges törlés", "Rename" => "Átnevezés", "Pending" => "Folyamatban", -"{new_name} already exists" => "{new_name} már létezik", -"replace" => "írjuk fölül", -"suggest name" => "legyen más neve", -"cancel" => "mégse", +"Could not rename file" => "Az állomány nem nevezhető át", "replaced {new_name} with {old_name}" => "{new_name} fájlt kicseréltük ezzel: {old_name}", "undo" => "visszavonás", +"Error deleting file." => "Hiba a file törlése közben.", "_%n folder_::_%n folders_" => array("%n mappa","%n mappa"), "_%n file_::_%n files_" => array("%n állomány","%n állomány"), "{dirs} and {files}" => "{dirs} és {files}", "_Uploading %n file_::_Uploading %n files_" => array("%n állomány feltöltése","%n állomány feltöltése"), "'.' is an invalid file name." => "'.' fájlnév érvénytelen.", -"File name cannot be empty." => "A fájlnév nem lehet semmi.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Érvénytelen elnevezés. Ezek a karakterek nem használhatók: '\\', '/', '<', '>', ':', '\"', '|', '?' és '*'", "Your storage is full, files can not be updated or synced anymore!" => "A tároló tele van, a fájlok nem frissíthetőek vagy szinkronizálhatóak a jövőben.", "Your storage is almost full ({usedSpacePercent}%)" => "A tároló majdnem tele van ({usedSpacePercent}%)", +"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "Az állományok titkosítása engedélyezve van, de az Ön titkos kulcsai nincsenek beállítva. Ezért kérjük, hogy jelentkezzen ki, és lépjen be újra!", +"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "Az állományok titkosításához használt titkos kulcsa érvénytelen. Kérjük frissítse a titkos kulcs jelszót a személyes beállításokban, hogy ismét hozzáférjen a titkosított állományaihoz!", "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "A titkosítási funkciót kikapcsolták, de az Ön állományai még mindig titkosított állapotban vannak. A személyes beállításoknál tudja a titkosítást feloldani.", "Your download is being prepared. This might take some time if the files are big." => "Készül a letöltendő állomány. Ez eltarthat egy ideig, ha nagyok a fájlok.", "Error moving file" => "Az állomány áthelyezése nem sikerült.", +"Error" => "Hiba", "Name" => "Név", "Size" => "Méret", "Modified" => "Módosítva", +"Invalid folder name. Usage of 'Shared' is reserved." => "Érvénytelen mappanév. A 'Shared' a rendszer számára fenntartott elnevezés.", "%s could not be renamed" => "%s átnevezése nem sikerült", "Upload" => "Feltöltés", "File handling" => "Fájlkezelés", @@ -61,15 +75,16 @@ $TRANSLATIONS = array( "Maximum input size for ZIP files" => "ZIP-fájlok maximális kiindulási mérete", "Save" => "Mentés", "New" => "Új", +"New text file" => "Új szöveges file", "Text file" => "Szövegfájl", +"New folder" => "Új mappa", "Folder" => "Mappa", "From link" => "Feltöltés linkről", "Deleted files" => "Törölt fájlok", "Cancel upload" => "A feltöltés megszakítása", -"You don’t have write permissions here." => "Itt nincs írásjoga.", +"You don’t have permission to upload or create files here" => "Önnek nincs jogosultsága ahhoz, hogy ide állományokat töltsön föl, vagy itt újakat hozzon létre", "Nothing in here. Upload something!" => "Itt nincs semmi. Töltsön fel valamit!", "Download" => "Letöltés", -"Unshare" => "A megosztás visszavonása", "Delete" => "Törlés", "Upload too large" => "A feltöltés túl nagy", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "A feltöltendő állományok mérete meghaladja a kiszolgálón megengedett maximális méretet.", diff --git a/apps/files/l10n/ia.php b/apps/files/l10n/ia.php index 1560687f6c4..82fd2e658d7 100644 --- a/apps/files/l10n/ia.php +++ b/apps/files/l10n/ia.php @@ -4,11 +4,11 @@ $TRANSLATIONS = array( "No file was uploaded" => "Nulle file esseva incargate.", "Missing a temporary folder" => "Manca un dossier temporari", "Files" => "Files", -"Error" => "Error", "Share" => "Compartir", "_%n folder_::_%n folders_" => array("",""), "_%n file_::_%n files_" => array("",""), "_Uploading %n file_::_Uploading %n files_" => array("",""), +"Error" => "Error", "Name" => "Nomine", "Size" => "Dimension", "Modified" => "Modificate", diff --git a/apps/files/l10n/id.php b/apps/files/l10n/id.php index c8b3194eb6b..4e254ff6f60 100644 --- a/apps/files/l10n/id.php +++ b/apps/files/l10n/id.php @@ -2,6 +2,17 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "Tidak dapat memindahkan %s - Berkas dengan nama ini sudah ada", "Could not move %s" => "Tidak dapat memindahkan %s", +"File name cannot be empty." => "Nama berkas tidak boleh kosong.", +"File name must not contain \"/\". Please choose a different name." => "Nama berkas tidak boleh mengandung \"/\". Silakan pilih nama yang berbeda.", +"The name %s is already used in the folder %s. Please choose a different name." => "Nama %s sudah digunakan dalam folder %s. Silakan pilih nama yang berbeda.", +"Not a valid source" => "Sumber tidak sah", +"Error while downloading %s to %s" => "Galat saat mengunduh %s ke %s", +"Error when creating the file" => "Galat saat membuat berkas", +"Folder name cannot be empty." => "Nama folder tidak bolh kosong.", +"Folder name must not contain \"/\". Please choose a different name." => "Nama folder tidak boleh mengandung \"/\". Silakan pilih nama yang berbeda.", +"Error when creating the folder" => "Galat saat membuat folder", +"Unable to set upload directory." => "Tidak dapat mengatur folder unggah", +"Invalid Token" => "Token tidak sah", "No file was uploaded. Unknown error" => "Tidak ada berkas yang diunggah. Galat tidak dikenal.", "There is no error, the file uploaded with success" => "Tidak ada galat, berkas sukses diunggah", "The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Berkas yang diunggah melampaui direktif upload_max_filesize pada php.ini", @@ -11,35 +22,47 @@ $TRANSLATIONS = array( "Missing a temporary folder" => "Folder sementara tidak ada", "Failed to write to disk" => "Gagal menulis ke disk", "Not enough storage available" => "Ruang penyimpanan tidak mencukupi", +"Upload failed. Could not get file info." => "Unggah gagal. Tidak mendapatkan informasi berkas.", +"Upload failed. Could not find uploaded file" => "Unggah gagal. Tidak menemukan berkas yang akan diunggah", "Invalid directory." => "Direktori tidak valid.", "Files" => "Berkas", +"Unable to upload {filename} as it is a directory or has 0 bytes" => "Tidak dapat mengunggah {filename} karena ini sebuah direktori atau memiliki ukuran 0 byte", "Not enough space available" => "Ruang penyimpanan tidak mencukupi", "Upload cancelled." => "Pengunggahan dibatalkan.", +"Could not get result from server." => "Tidak mendapatkan hasil dari server.", "File upload is in progress. Leaving the page now will cancel the upload." => "Berkas sedang diunggah. Meninggalkan halaman ini akan membatalkan proses.", -"URL cannot be empty." => "URL tidak boleh kosong", -"Error" => "Galat", +"URL cannot be empty" => "URL tidak boleh kosong", +"In the home folder 'Shared' is a reserved filename" => "Pada folder home, 'Shared' adalah nama berkas yang sudah digunakan", +"{new_name} already exists" => "{new_name} sudah ada", +"Could not create file" => "Tidak dapat membuat berkas", +"Could not create folder" => "Tidak dapat membuat folder", "Share" => "Bagikan", "Delete permanently" => "Hapus secara permanen", "Rename" => "Ubah nama", "Pending" => "Menunggu", -"{new_name} already exists" => "{new_name} sudah ada", -"replace" => "ganti", -"suggest name" => "sarankan nama", -"cancel" => "batalkan", +"Could not rename file" => "Tidak dapat mengubah nama berkas", "replaced {new_name} with {old_name}" => "mengganti {new_name} dengan {old_name}", "undo" => "urungkan", -"_%n folder_::_%n folders_" => array(""), -"_%n file_::_%n files_" => array(""), -"_Uploading %n file_::_Uploading %n files_" => array(""), +"Error deleting file." => "Galat saat menghapus berkas.", +"_%n folder_::_%n folders_" => array("%n folder"), +"_%n file_::_%n files_" => array("%n berkas"), +"{dirs} and {files}" => "{dirs} dan {files}", +"_Uploading %n file_::_Uploading %n files_" => array("Mengunggah %n berkas"), "'.' is an invalid file name." => "'.' bukan nama berkas yang valid.", -"File name cannot be empty." => "Nama berkas tidak boleh kosong.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nama tidak valid, karakter '\\', '/', '<', '>', ':', '\"', '|', '?' dan '*' tidak diizinkan.", "Your storage is full, files can not be updated or synced anymore!" => "Ruang penyimpanan Anda penuh, berkas tidak dapat diperbarui atau disinkronkan lagi!", "Your storage is almost full ({usedSpacePercent}%)" => "Ruang penyimpanan hampir penuh ({usedSpacePercent}%)", +"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "Aplikasi Enskripsi telah diaktifkan tetapi kunci tidak diinisialisasi, silakan log-out dan log-in lagi", +"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "Kunci privat tidak sah untuk Aplikasi Enskripsi. Silakan perbarui sandi kunci privat anda pada pengaturan pribadi untuk memulihkan akses ke berkas anda yang dienskripsi.", +"Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Enskripi telah dinonaktifkan tetapi berkas anda tetap dienskripsi. Silakan menuju ke pengaturan pribadi untuk deskrip berkas anda.", "Your download is being prepared. This might take some time if the files are big." => "Unduhan Anda sedang disiapkan. Prosesnya dapat berlangsung agak lama jika ukuran berkasnya besar.", +"Error moving file" => "Galat saat memindahkan berkas", +"Error" => "Galat", "Name" => "Nama", "Size" => "Ukuran", "Modified" => "Dimodifikasi", +"Invalid folder name. Usage of 'Shared' is reserved." => "Nama folder tidak sah. Menggunakan 'Shared' sudah digunakan.", +"%s could not be renamed" => "%s tidak dapat diubah nama", "Upload" => "Unggah", "File handling" => "Penanganan berkas", "Maximum upload size" => "Ukuran pengunggahan maksimum", @@ -50,15 +73,16 @@ $TRANSLATIONS = array( "Maximum input size for ZIP files" => "Ukuran masukan maksimum untuk berkas ZIP", "Save" => "Simpan", "New" => "Baru", +"New text file" => "Berkas teks baru", "Text file" => "Berkas teks", +"New folder" => "Map baru", "Folder" => "Folder", "From link" => "Dari tautan", "Deleted files" => "Berkas yang dihapus", "Cancel upload" => "Batal pengunggahan", -"You don’t have write permissions here." => "Anda tidak memiliki izin menulis di sini.", +"You don’t have permission to upload or create files here" => "Anda tidak memiliki akses untuk mengunggah atau membuat berkas disini", "Nothing in here. Upload something!" => "Tidak ada apa-apa di sini. Unggah sesuatu!", "Download" => "Unduh", -"Unshare" => "Batalkan berbagi", "Delete" => "Hapus", "Upload too large" => "Yang diunggah terlalu besar", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Berkas yang dicoba untuk diunggah melebihi ukuran maksimum pengunggahan berkas di server ini.", diff --git a/apps/files/l10n/is.php b/apps/files/l10n/is.php index ef493418206..5c5cc7d5d73 100644 --- a/apps/files/l10n/is.php +++ b/apps/files/l10n/is.php @@ -2,6 +2,7 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "Gat ekki fært %s - Skrá með þessu nafni er þegar til", "Could not move %s" => "Gat ekki fært %s", +"File name cannot be empty." => "Nafn skráar má ekki vera tómt", "No file was uploaded. Unknown error" => "Engin skrá var send inn. Óþekkt villa.", "There is no error, the file uploaded with success" => "Engin villa, innsending heppnaðist", "The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Innsend skrá er stærri en upload_max stillingin í php.ini:", @@ -15,23 +16,18 @@ $TRANSLATIONS = array( "Not enough space available" => "Ekki nægt pláss tiltækt", "Upload cancelled." => "Hætt við innsendingu.", "File upload is in progress. Leaving the page now will cancel the upload." => "Innsending í gangi. Ef þú ferð af þessari síðu mun innsending misheppnast.", -"URL cannot be empty." => "Vefslóð má ekki vera tóm.", -"Error" => "Villa", +"{new_name} already exists" => "{new_name} er þegar til", "Share" => "Deila", "Rename" => "Endurskýra", "Pending" => "Bíður", -"{new_name} already exists" => "{new_name} er þegar til", -"replace" => "yfirskrifa", -"suggest name" => "stinga upp á nafni", -"cancel" => "hætta við", "replaced {new_name} with {old_name}" => "yfirskrifaði {new_name} með {old_name}", "undo" => "afturkalla", "_%n folder_::_%n folders_" => array("",""), "_%n file_::_%n files_" => array("",""), "_Uploading %n file_::_Uploading %n files_" => array("",""), "'.' is an invalid file name." => "'.' er ekki leyfilegt nafn.", -"File name cannot be empty." => "Nafn skráar má ekki vera tómt", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Ógilt nafn, táknin '\\', '/', '<', '>', ':', '\"', '|', '?' og '*' eru ekki leyfð.", +"Error" => "Villa", "Name" => "Nafn", "Size" => "Stærð", "Modified" => "Breytt", @@ -51,7 +47,6 @@ $TRANSLATIONS = array( "Cancel upload" => "Hætta við innsendingu", "Nothing in here. Upload something!" => "Ekkert hér. Settu eitthvað inn!", "Download" => "Niðurhal", -"Unshare" => "Hætta deilingu", "Delete" => "Eyða", "Upload too large" => "Innsend skrá er of stór", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Skrárnar sem þú ert að senda inn eru stærri en hámarks innsendingarstærð á þessum netþjóni.", diff --git a/apps/files/l10n/it.php b/apps/files/l10n/it.php index 44b4e341956..2a10e9977f4 100644 --- a/apps/files/l10n/it.php +++ b/apps/files/l10n/it.php @@ -2,6 +2,16 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "Impossibile spostare %s - un file con questo nome esiste già", "Could not move %s" => "Impossibile spostare %s", +"File name cannot be empty." => "Il nome del file non può essere vuoto.", +"File name must not contain \"/\". Please choose a different name." => "Il nome del file non può contenere il carattere \"/\". Scegli un nome diverso.", +"The name %s is already used in the folder %s. Please choose a different name." => "Il nome %s è attualmente in uso nella cartella %s. Scegli un nome diverso.", +"Not a valid source" => "Non è una sorgente valida", +"Server is not allowed to open URLs, please check the server configuration" => "Al server non è permesso aprire URL, controlla la configurazione del server", +"Error while downloading %s to %s" => "Errore durante lo scaricamento di %s su %s", +"Error when creating the file" => "Errore durante la creazione del file", +"Folder name cannot be empty." => "Il nome della cartella non può essere vuoto.", +"Folder name must not contain \"/\". Please choose a different name." => "Il nome della cartella non può contenere il carattere \"/\". Scegli un nome diverso.", +"Error when creating the folder" => "Errore durante la creazione della cartella", "Unable to set upload directory." => "Impossibile impostare una cartella di caricamento.", "Invalid Token" => "Token non valido", "No file was uploaded. Unknown error" => "Nessun file è stato inviato. Errore sconosciuto", @@ -22,34 +32,38 @@ $TRANSLATIONS = array( "Upload cancelled." => "Invio annullato", "Could not get result from server." => "Impossibile ottenere il risultato dal server.", "File upload is in progress. Leaving the page now will cancel the upload." => "Caricamento del file in corso. La chiusura della pagina annullerà il caricamento.", -"URL cannot be empty." => "L'URL non può essere vuoto.", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Nome della cartella non valido. L'uso di 'Shared' è riservato a ownCloud", -"Error" => "Errore", +"URL cannot be empty" => "L'URL non può essere vuoto.", +"In the home folder 'Shared' is a reserved filename" => "Nella cartella home 'Shared' è un nome riservato", +"{new_name} already exists" => "{new_name} esiste già", +"Could not create file" => "Impossibile creare il file", +"Could not create folder" => "Impossibile creare la cartella", +"Error fetching URL" => "Errore durante il recupero dello URL", "Share" => "Condividi", "Delete permanently" => "Elimina definitivamente", "Rename" => "Rinomina", "Pending" => "In corso", -"{new_name} already exists" => "{new_name} esiste già", -"replace" => "sostituisci", -"suggest name" => "suggerisci nome", -"cancel" => "annulla", +"Could not rename file" => "Impossibile rinominare il file", "replaced {new_name} with {old_name}" => "sostituito {new_name} con {old_name}", "undo" => "annulla", +"Error deleting file." => "Errore durante l'eliminazione del file.", "_%n folder_::_%n folders_" => array("%n cartella","%n cartelle"), "_%n file_::_%n files_" => array("%n file","%n file"), "{dirs} and {files}" => "{dirs} e {files}", "_Uploading %n file_::_Uploading %n files_" => array("Caricamento di %n file in corso","Caricamento di %n file in corso"), "'.' is an invalid file name." => "'.' non è un nome file valido.", -"File name cannot be empty." => "Il nome del file non può essere vuoto.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nome non valido, '\\', '/', '<', '>', ':', '\"', '|', '?' e '*' non sono consentiti.", "Your storage is full, files can not be updated or synced anymore!" => "Lo spazio di archiviazione è pieno, i file non possono essere più aggiornati o sincronizzati!", "Your storage is almost full ({usedSpacePercent}%)" => "Lo spazio di archiviazione è quasi pieno ({usedSpacePercent}%)", +"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "L'applicazione di cifratura è abilitata, ma le chiavi non sono state inizializzate, disconnettiti ed effettua nuovamente l'accesso", +"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "Chiave privata non valida per l'applicazione di cifratura. Aggiorna la password della chiave privata nelle impostazioni personali per ripristinare l'accesso ai tuoi file cifrati.", "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "La cifratura è stata disabilitata ma i tuoi file sono ancora cifrati. Vai nelle impostazioni personali per decifrare i file.", "Your download is being prepared. This might take some time if the files are big." => "Il tuo scaricamento è in fase di preparazione. Ciò potrebbe richiedere del tempo se i file sono grandi.", "Error moving file" => "Errore durante lo spostamento del file", +"Error" => "Errore", "Name" => "Nome", "Size" => "Dimensione", "Modified" => "Modificato", +"Invalid folder name. Usage of 'Shared' is reserved." => "Nome della cartella non valido. L'uso di 'Shared' è riservato.", "%s could not be renamed" => "%s non può essere rinominato", "Upload" => "Carica", "File handling" => "Gestione file", @@ -61,15 +75,16 @@ $TRANSLATIONS = array( "Maximum input size for ZIP files" => "Dimensione massima per i file ZIP", "Save" => "Salva", "New" => "Nuovo", +"New text file" => "Nuovo file di testo", "Text file" => "File di testo", +"New folder" => "Nuova cartella", "Folder" => "Cartella", "From link" => "Da collegamento", "Deleted files" => "File eliminati", "Cancel upload" => "Annulla invio", -"You don’t have write permissions here." => "Qui non hai i permessi di scrittura.", +"You don’t have permission to upload or create files here" => "Qui non hai i permessi di caricare o creare file", "Nothing in here. Upload something!" => "Non c'è niente qui. Carica qualcosa!", "Download" => "Scarica", -"Unshare" => "Rimuovi condivisione", "Delete" => "Elimina", "Upload too large" => "Caricamento troppo grande", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "I file che stai provando a caricare superano la dimensione massima consentita su questo server.", diff --git a/apps/files/l10n/ja_JP.php b/apps/files/l10n/ja_JP.php index 07ee96f1eb6..8019b825d3c 100644 --- a/apps/files/l10n/ja_JP.php +++ b/apps/files/l10n/ja_JP.php @@ -2,6 +2,16 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "%s を移動できませんでした ― この名前のファイルはすでに存在します", "Could not move %s" => "%s を移動できませんでした", +"File name cannot be empty." => "ファイル名を空にすることはできません。", +"File name must not contain \"/\". Please choose a different name." => "ファイル名には \"/\" を含めることはできません。別の名前を選択してください。", +"The name %s is already used in the folder %s. Please choose a different name." => "%s はフォルダ %s ないですでに使われています。別の名前を選択してください。", +"Not a valid source" => "有効なソースではありません", +"Server is not allowed to open URLs, please check the server configuration" => "サーバーは、URLを開くことは許されません。サーバーの設定をチェックしてください。", +"Error while downloading %s to %s" => "%s から %s へのダウンロードエラー", +"Error when creating the file" => "ファイルの生成エラー", +"Folder name cannot be empty." => "フォルダ名は空にできません", +"Folder name must not contain \"/\". Please choose a different name." => "フォルダ名には \"/\" を含めることはできません。別の名前を選択してください。", +"Error when creating the folder" => "フォルダの生成エラー", "Unable to set upload directory." => "アップロードディレクトリを設定出来ません。", "Invalid Token" => "無効なトークン", "No file was uploaded. Unknown error" => "ファイルは何もアップロードされていません。不明なエラー", @@ -22,34 +32,38 @@ $TRANSLATIONS = array( "Upload cancelled." => "アップロードはキャンセルされました。", "Could not get result from server." => "サーバから結果を取得できませんでした。", "File upload is in progress. Leaving the page now will cancel the upload." => "ファイル転送を実行中です。今このページから移動するとアップロードが中止されます。", -"URL cannot be empty." => "URLは空にできません。", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "無効なフォルダ名です。'Shared' の利用はownCloudで予約済みです", -"Error" => "エラー", +"URL cannot be empty" => "URL は空にできません", +"In the home folder 'Shared' is a reserved filename" => "ホームフォルダでは、'Shared' はシステムが使用する予約済みのファイル名です", +"{new_name} already exists" => "{new_name} はすでに存在しています", +"Could not create file" => "ファイルを作成できませんでした", +"Could not create folder" => "フォルダを作成できませんでした", +"Error fetching URL" => "URL取得エラー", "Share" => "共有", "Delete permanently" => "完全に削除する", "Rename" => "名前の変更", "Pending" => "中断", -"{new_name} already exists" => "{new_name} はすでに存在しています", -"replace" => "置き換え", -"suggest name" => "推奨名称", -"cancel" => "キャンセル", +"Could not rename file" => "ファイルの名前変更ができませんでした", "replaced {new_name} with {old_name}" => "{old_name} を {new_name} に置換", "undo" => "元に戻す", -"_%n folder_::_%n folders_" => array("%n個のフォルダ"), -"_%n file_::_%n files_" => array("%n個のファイル"), +"Error deleting file." => "ファイルの削除エラー。", +"_%n folder_::_%n folders_" => array("%n 個のフォルダ"), +"_%n file_::_%n files_" => array("%n 個のファイル"), "{dirs} and {files}" => "{dirs} と {files}", "_Uploading %n file_::_Uploading %n files_" => array("%n 個のファイルをアップロード中"), "'.' is an invalid file name." => "'.' は無効なファイル名です。", -"File name cannot be empty." => "ファイル名を空にすることはできません。", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "無効な名前、'\\', '/', '<', '>', ':', '\"', '|', '?', '*' は使用できません。", "Your storage is full, files can not be updated or synced anymore!" => "あなたのストレージは一杯です。ファイルの更新と同期はもうできません!", "Your storage is almost full ({usedSpacePercent}%)" => "あなたのストレージはほぼ一杯です({usedSpacePercent}%)", +"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "暗号化アプリは有効ですが、あなたの暗号化キーは初期化されていません。ログアウトした後に、再度ログインしてください", +"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "暗号化アプリの無効なプライベートキーです。あなたの暗号化されたファイルへアクセスするために、個人設定からプライベートキーのパスワードを更新してください。", "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "暗号化の機能は無効化されましたが、ファイルはすでに暗号化されています。個人設定からファイルを複合を行ってください。", "Your download is being prepared. This might take some time if the files are big." => "ダウンロードの準備中です。ファイルサイズが大きい場合は少し時間がかかるかもしれません。", "Error moving file" => "ファイルの移動エラー", +"Error" => "エラー", "Name" => "名前", "Size" => "サイズ", -"Modified" => "変更", +"Modified" => "更新日時", +"Invalid folder name. Usage of 'Shared' is reserved." => "無効なフォルダ名。「Shared」の利用は予約されています。", "%s could not be renamed" => "%sの名前を変更できませんでした", "Upload" => "アップロード", "File handling" => "ファイル操作", @@ -61,15 +75,16 @@ $TRANSLATIONS = array( "Maximum input size for ZIP files" => "ZIPファイルへの最大入力サイズ", "Save" => "保存", "New" => "新規作成", +"New text file" => "新規のテキストファイル作成", "Text file" => "テキストファイル", +"New folder" => "新しいフォルダ", "Folder" => "フォルダ", "From link" => "リンク", -"Deleted files" => "削除ファイル", +"Deleted files" => "ゴミ箱", "Cancel upload" => "アップロードをキャンセル", -"You don’t have write permissions here." => "あなたには書き込み権限がありません。", +"You don’t have permission to upload or create files here" => "ここにファイルをアップロードもしくは作成する権限がありません", "Nothing in here. Upload something!" => "ここには何もありません。何かアップロードしてください。", "Download" => "ダウンロード", -"Unshare" => "共有解除", "Delete" => "削除", "Upload too large" => "アップロードには大きすぎます。", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "アップロードしようとしているファイルは、サーバで規定された最大サイズを超えています。", diff --git a/apps/files/l10n/ka_GE.php b/apps/files/l10n/ka_GE.php index b9313957714..eafa0c083f7 100644 --- a/apps/files/l10n/ka_GE.php +++ b/apps/files/l10n/ka_GE.php @@ -2,6 +2,7 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "%s –ის გადატანა ვერ მოხერხდა – ფაილი ამ სახელით უკვე არსებობს", "Could not move %s" => "%s –ის გადატანა ვერ მოხერხდა", +"File name cannot be empty." => "ფაილის სახელი არ შეიძლება იყოს ცარიელი.", "No file was uploaded. Unknown error" => "ფაილი არ აიტვირთა. უცნობი შეცდომა", "There is no error, the file uploaded with success" => "ჭოცდომა არ დაფიქსირდა, ფაილი წარმატებით აიტვირთა", "The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "ატვირთული ფაილი აჭარბებს upload_max_filesize დირექტივას php.ini ფაილში", @@ -16,27 +17,22 @@ $TRANSLATIONS = array( "Not enough space available" => "საკმარისი ადგილი არ არის", "Upload cancelled." => "ატვირთვა შეჩერებულ იქნა.", "File upload is in progress. Leaving the page now will cancel the upload." => "მიმდინარეობს ფაილის ატვირთვა. სხვა გვერდზე გადასვლა გამოიწვევს ატვირთვის შეჩერებას", -"URL cannot be empty." => "URL არ შეიძლება იყოს ცარიელი.", -"Error" => "შეცდომა", +"{new_name} already exists" => "{new_name} უკვე არსებობს", "Share" => "გაზიარება", "Delete permanently" => "სრულად წაშლა", "Rename" => "გადარქმევა", "Pending" => "მოცდის რეჟიმში", -"{new_name} already exists" => "{new_name} უკვე არსებობს", -"replace" => "შეცვლა", -"suggest name" => "სახელის შემოთავაზება", -"cancel" => "უარყოფა", "replaced {new_name} with {old_name}" => "{new_name} შეცვლილია {old_name}–ით", "undo" => "დაბრუნება", "_%n folder_::_%n folders_" => array(""), "_%n file_::_%n files_" => array(""), "_Uploading %n file_::_Uploading %n files_" => array(""), "'.' is an invalid file name." => "'.' არის დაუშვებელი ფაილის სახელი.", -"File name cannot be empty." => "ფაილის სახელი არ შეიძლება იყოს ცარიელი.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "არადაშვებადი სახელი, '\\', '/', '<', '>', ':', '\"', '|', '?' და '*' არ არის დაიშვებული.", "Your storage is full, files can not be updated or synced anymore!" => "თქვენი საცავი გადაივსო. ფაილების განახლება და სინქრონიზირება ვერ მოხერხდება!", "Your storage is almost full ({usedSpacePercent}%)" => "თქვენი საცავი თითქმის გადაივსო ({usedSpacePercent}%)", "Your download is being prepared. This might take some time if the files are big." => "გადმოწერის მოთხოვნა მუშავდება. ის მოითხოვს გარკვეულ დროს რაგდან ფაილები არის დიდი ზომის.", +"Error" => "შეცდომა", "Name" => "სახელი", "Size" => "ზომა", "Modified" => "შეცვლილია", @@ -51,14 +47,13 @@ $TRANSLATIONS = array( "Save" => "შენახვა", "New" => "ახალი", "Text file" => "ტექსტური ფაილი", +"New folder" => "ახალი ფოლდერი", "Folder" => "საქაღალდე", "From link" => "მისამართიდან", "Deleted files" => "წაშლილი ფაილები", "Cancel upload" => "ატვირთვის გაუქმება", -"You don’t have write permissions here." => "თქვენ არ გაქვთ ჩაწერის უფლება აქ.", "Nothing in here. Upload something!" => "აქ არაფერი არ არის. ატვირთე რამე!", "Download" => "ჩამოტვირთვა", -"Unshare" => "გაუზიარებადი", "Delete" => "წაშლა", "Upload too large" => "ასატვირთი ფაილი ძალიან დიდია", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "ფაილის ზომა რომლის ატვირთვასაც თქვენ აპირებთ, აჭარბებს სერვერზე დაშვებულ მაქსიმუმს.", diff --git a/apps/files/l10n/km.php b/apps/files/l10n/km.php index 70ab6572ba4..9733358d628 100644 --- a/apps/files/l10n/km.php +++ b/apps/files/l10n/km.php @@ -2,6 +2,7 @@ $TRANSLATIONS = array( "_%n folder_::_%n folders_" => array(""), "_%n file_::_%n files_" => array(""), -"_Uploading %n file_::_Uploading %n files_" => array("") +"_Uploading %n file_::_Uploading %n files_" => array(""), +"Delete" => "លុប" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/files/l10n/ko.php b/apps/files/l10n/ko.php index 0174f8d0d21..35a9f2fb85c 100644 --- a/apps/files/l10n/ko.php +++ b/apps/files/l10n/ko.php @@ -1,10 +1,20 @@ <?php $TRANSLATIONS = array( -"Could not move %s - File with this name already exists" => "%s 항목을 이동시키지 못하였음 - 파일 이름이 이미 존재함", -"Could not move %s" => "%s 항목을 이딩시키지 못하였음", -"Unable to set upload directory." => "업로드 디렉터리를 정할수 없습니다", +"Could not move %s - File with this name already exists" => "항목 %s을(를) 이동시킬 수 없음 - 같은 이름의 파일이 이미 존재함", +"Could not move %s" => "항목 %s을(를) 이동시킬 수 없음", +"File name cannot be empty." => "파일 이름이 비어 있을 수 없습니다.", +"File name must not contain \"/\". Please choose a different name." => "파일 이름에는 \"/\"가 들어갈 수 없습니다. 다른 이름을 사용하십시오.", +"The name %s is already used in the folder %s. Please choose a different name." => "이름 %s이(가) 폴더 %s에서 이미 사용 중입니다. 다른 이름을 사용하십시오.", +"Not a valid source" => "올바르지 않은 원본", +"Server is not allowed to open URLs, please check the server configuration" => "서버에서 URL을 열 수 없습니다. 서버 설정을 확인하십시오", +"Error while downloading %s to %s" => "%s을(를) %s(으)로 다운로드하는 중 오류 발생", +"Error when creating the file" => "파일 생성 중 오류 발생", +"Folder name cannot be empty." => "폴더 이름이 비어있을 수 없습니다.", +"Folder name must not contain \"/\". Please choose a different name." => "폴더 이름에는 \"/\"가 들어갈 수 없습니다. 다른 이름을 사용하십시오.", +"Error when creating the folder" => "폴더 생성 중 오류 발생", +"Unable to set upload directory." => "업로드 디렉터리를 설정할 수 없습니다.", "Invalid Token" => "잘못된 토큰", -"No file was uploaded. Unknown error" => "파일이 업로드되지 않았습니다. 알 수 없는 오류입니다", +"No file was uploaded. Unknown error" => "파일이 업로드 되지 않았습니다. 알 수 없는 오류입니다", "There is no error, the file uploaded with success" => "파일 업로드에 성공하였습니다.", "The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "업로드한 파일이 php.ini의 upload_max_filesize보다 큽니다:", "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "업로드한 파일 크기가 HTML 폼의 MAX_FILE_SIZE보다 큼", @@ -13,44 +23,48 @@ $TRANSLATIONS = array( "Missing a temporary folder" => "임시 폴더가 없음", "Failed to write to disk" => "디스크에 쓰지 못했습니다", "Not enough storage available" => "저장소가 용량이 충분하지 않습니다.", -"Upload failed. Could not get file info." => "업로드에 실패했습니다. 파일 정보를 가져올수 없습니다.", -"Upload failed. Could not find uploaded file" => "업로드에 실패했습니다. 업로드할 파일을 찾을수 없습니다", +"Upload failed. Could not get file info." => "업로드에 실패했습니다. 파일 정보를 가져올 수 없습니다.", +"Upload failed. Could not find uploaded file" => "업로드에 실패했습니다. 업로드할 파일을 찾을 수 없습니다", "Invalid directory." => "올바르지 않은 디렉터리입니다.", "Files" => "파일", -"Unable to upload {filename} as it is a directory or has 0 bytes" => "{filename}을 업로드 할수 없습니다. 폴더이거나 0 바이트 파일입니다.", +"Unable to upload {filename} as it is a directory or has 0 bytes" => "{filename}을(를) 업로드할 수 없습니다. 폴더이거나 0 바이트 파일입니다.", "Not enough space available" => "여유 공간이 부족합니다", "Upload cancelled." => "업로드가 취소되었습니다.", -"Could not get result from server." => "서버에서 결과를 가져올수 없습니다.", +"Could not get result from server." => "서버에서 결과를 가져올 수 없습니다.", "File upload is in progress. Leaving the page now will cancel the upload." => "파일 업로드가 진행 중입니다. 이 페이지를 벗어나면 업로드가 취소됩니다.", -"URL cannot be empty." => "URL을 입력해야 합니다.", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "유효하지 않은 폴더명입니다. \"Shared\" 이름의 사용은 OwnCloud 가 이미 예약하고 있습니다.", -"Error" => "오류", +"URL cannot be empty" => "URL이 비어있을 수 없음", +"In the home folder 'Shared' is a reserved filename" => "'공유됨'은 홈 폴더의 예약된 파일 이름임", +"{new_name} already exists" => "{new_name}이(가) 이미 존재함", +"Could not create file" => "파일을 만들 수 없음", +"Could not create folder" => "폴더를 만들 수 없음", +"Error fetching URL" => "URL을 가져올 수 없음", "Share" => "공유", -"Delete permanently" => "영원히 삭제", +"Delete permanently" => "영구히 삭제", "Rename" => "이름 바꾸기", "Pending" => "대기 중", -"{new_name} already exists" => "{new_name}이(가) 이미 존재함", -"replace" => "바꾸기", -"suggest name" => "이름 제안", -"cancel" => "취소", +"Could not rename file" => "이름을 변경할 수 없음", "replaced {new_name} with {old_name}" => "{old_name}이(가) {new_name}(으)로 대체됨", -"undo" => "되돌리기", -"_%n folder_::_%n folders_" => array("폴더 %n"), -"_%n file_::_%n files_" => array("파일 %n 개"), +"undo" => "실행 취소", +"Error deleting file." => "파일 삭제 오류.", +"_%n folder_::_%n folders_" => array("폴더 %n개"), +"_%n file_::_%n files_" => array("파일 %n개"), "{dirs} and {files}" => "{dirs} 그리고 {files}", -"_Uploading %n file_::_Uploading %n files_" => array("%n 개의 파일을 업로드중"), -"'.' is an invalid file name." => "'.' 는 올바르지 않은 파일 이름 입니다.", -"File name cannot be empty." => "파일 이름이 비어 있을 수 없습니다.", +"_Uploading %n file_::_Uploading %n files_" => array("파일 %n개 업로드 중"), +"'.' is an invalid file name." => "'.' 는 올바르지 않은 파일 이름입니다.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "폴더 이름이 올바르지 않습니다. 이름에 문자 '\\', '/', '<', '>', ':', '\"', '|', '? ', '*'는 사용할 수 없습니다.", "Your storage is full, files can not be updated or synced anymore!" => "저장 공간이 가득 찼습니다. 파일을 업데이트하거나 동기화할 수 없습니다!", "Your storage is almost full ({usedSpacePercent}%)" => "저장 공간이 거의 가득 찼습니다 ({usedSpacePercent}%)", -"Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "암호화는 해제되어 있지만, 파일은 아직 암호화 되어 있습니다. 개인 설저에 가셔서 암호를 해제하십시오", -"Your download is being prepared. This might take some time if the files are big." => "다운로드가 준비 중입니다. 파일 크기가 크다면 시간이 오래 걸릴 수도 있습니다.", +"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "암호화 앱이 활성화되어 있지만 키가 초기화되지 않았습니다. 로그아웃한 후 다시 로그인하십시오", +"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "암호화 앱의 개인 키가 잘못되었습니다. 암호화된 파일에 다시 접근하려면 개인 설정에서 개인 키 암호를 업데이트해야 합니다.", +"Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "암호화는 해제되어 있지만, 파일은 아직 암호화되어 있습니다. 개인 설정에서 파일을 복호화하십시오.", +"Your download is being prepared. This might take some time if the files are big." => "다운로드 준비 중입니다. 파일 크기가 크면 시간이 오래 걸릴 수도 있습니다.", "Error moving file" => "파일 이동 오류", +"Error" => "오류", "Name" => "이름", "Size" => "크기", "Modified" => "수정됨", -"%s could not be renamed" => "%s 의 이름을 변경할수 없습니다", +"Invalid folder name. Usage of 'Shared' is reserved." => "폴더 이름이 잘못되었습니다. '공유됨'은 예약된 폴더 이름입니다.", +"%s could not be renamed" => "%s의 이름을 변경할 수 없습니다", "Upload" => "업로드", "File handling" => "파일 처리", "Maximum upload size" => "최대 업로드 크기", @@ -61,15 +75,16 @@ $TRANSLATIONS = array( "Maximum input size for ZIP files" => "ZIP 파일 최대 크기", "Save" => "저장", "New" => "새로 만들기", +"New text file" => "새 텍스트 파일", "Text file" => "텍스트 파일", +"New folder" => "새 폴더", "Folder" => "폴더", "From link" => "링크에서", -"Deleted files" => "파일 삭제됨", +"Deleted files" => "삭제된 파일", "Cancel upload" => "업로드 취소", -"You don’t have write permissions here." => "당신은 여기에 쓰기를 할 수 있는 권한이 없습니다.", +"You don’t have permission to upload or create files here" => "여기에 파일을 업로드하거나 만들 권한이 없습니다", "Nothing in here. Upload something!" => "내용이 없습니다. 업로드할 수 있습니다!", "Download" => "다운로드", -"Unshare" => "공유 해제", "Delete" => "삭제", "Upload too large" => "업로드한 파일이 너무 큼", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "이 파일이 서버에서 허용하는 최대 업로드 가능 용량보다 큽니다.", diff --git a/apps/files/l10n/ku_IQ.php b/apps/files/l10n/ku_IQ.php index d98848a71f0..f04e9ec44df 100644 --- a/apps/files/l10n/ku_IQ.php +++ b/apps/files/l10n/ku_IQ.php @@ -1,11 +1,10 @@ <?php $TRANSLATIONS = array( -"URL cannot be empty." => "ناونیشانی بهستهر نابێت بهتاڵ بێت.", -"Error" => "ههڵه", "Share" => "هاوبەشی کردن", "_%n folder_::_%n folders_" => array("",""), "_%n file_::_%n files_" => array("",""), "_Uploading %n file_::_Uploading %n files_" => array("",""), +"Error" => "ههڵه", "Name" => "ناو", "Upload" => "بارکردن", "Save" => "پاشکهوتکردن", diff --git a/apps/files/l10n/lb.php b/apps/files/l10n/lb.php index cd68b2b9ad2..822ca7e2d02 100644 --- a/apps/files/l10n/lb.php +++ b/apps/files/l10n/lb.php @@ -9,14 +9,13 @@ $TRANSLATIONS = array( "Files" => "Dateien", "Upload cancelled." => "Upload ofgebrach.", "File upload is in progress. Leaving the page now will cancel the upload." => "File Upload am gaang. Wann's de des Säit verléiss gëtt den Upload ofgebrach.", -"Error" => "Fehler", "Share" => "Deelen", -"replace" => "ersetzen", -"cancel" => "ofbriechen", +"Rename" => "Ëm-benennen", "undo" => "réckgängeg man", "_%n folder_::_%n folders_" => array("",""), "_%n file_::_%n files_" => array("",""), "_Uploading %n file_::_Uploading %n files_" => array("",""), +"Error" => "Fehler", "Name" => "Numm", "Size" => "Gréisst", "Modified" => "Geännert", @@ -35,7 +34,6 @@ $TRANSLATIONS = array( "Cancel upload" => "Upload ofbriechen", "Nothing in here. Upload something!" => "Hei ass näischt. Lued eppes rop!", "Download" => "Download", -"Unshare" => "Net méi deelen", "Delete" => "Läschen", "Upload too large" => "Upload ze grouss", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Déi Dateien déi Dir probéiert erop ze lueden sinn méi grouss wei déi Maximal Gréisst déi op dësem Server erlaabt ass.", diff --git a/apps/files/l10n/lt_LT.php b/apps/files/l10n/lt_LT.php index d064b0c6523..d9023658631 100644 --- a/apps/files/l10n/lt_LT.php +++ b/apps/files/l10n/lt_LT.php @@ -2,6 +2,15 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "Nepavyko perkelti %s - failas su tokiu pavadinimu jau egzistuoja", "Could not move %s" => "Nepavyko perkelti %s", +"File name cannot be empty." => "Failo pavadinimas negali būti tuščias.", +"File name must not contain \"/\". Please choose a different name." => "Failo pavadinime negali būti simbolio \"/\". Prašome pasirinkti kitokį pavadinimą.", +"The name %s is already used in the folder %s. Please choose a different name." => "Pavadinimas %s jau naudojamas aplanke %s. Prašome pasirinkti kitokį pavadinimą.", +"Not a valid source" => "Netinkamas šaltinis", +"Error while downloading %s to %s" => "Klaida siunčiant %s į %s", +"Error when creating the file" => "Klaida kuriant failą", +"Folder name cannot be empty." => "Aplanko pavadinimas negali būti tuščias.", +"Folder name must not contain \"/\". Please choose a different name." => "Aplanko pavadinime negali būti simbolio \"/\". Prašome pasirinkti kitokį pavadinimą.", +"Error when creating the folder" => "Klaida kuriant aplanką", "Unable to set upload directory." => "Nepavyksta nustatyti įkėlimų katalogo.", "Invalid Token" => "Netinkamas ženklas", "No file was uploaded. Unknown error" => "Failai nebuvo įkelti dėl nežinomos priežasties", @@ -22,31 +31,32 @@ $TRANSLATIONS = array( "Upload cancelled." => "Įkėlimas atšauktas.", "Could not get result from server." => "Nepavyko gauti rezultato iš serverio.", "File upload is in progress. Leaving the page now will cancel the upload." => "Failo įkėlimas pradėtas. Jei paliksite šį puslapį, įkėlimas nutrūks.", -"URL cannot be empty." => "URL negali būti tuščias.", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Negalimas aplanko pavadinimas. 'Shared' pavadinimas yra rezervuotas ownCloud", -"Error" => "Klaida", +"URL cannot be empty" => "URL negali būti tuščias.", +"{new_name} already exists" => "{new_name} jau egzistuoja", +"Could not create file" => "Neįmanoma sukurti failo", +"Could not create folder" => "Neįmanoma sukurti aplanko", "Share" => "Dalintis", "Delete permanently" => "Ištrinti negrįžtamai", "Rename" => "Pervadinti", "Pending" => "Laukiantis", -"{new_name} already exists" => "{new_name} jau egzistuoja", -"replace" => "pakeisti", -"suggest name" => "pasiūlyti pavadinimą", -"cancel" => "atšaukti", +"Could not rename file" => "Neįmanoma pervadinti failo", "replaced {new_name} with {old_name}" => "pakeiskite {new_name} į {old_name}", "undo" => "anuliuoti", +"Error deleting file." => "Klaida trinant failą.", "_%n folder_::_%n folders_" => array("%n aplankas","%n aplankai","%n aplankų"), "_%n file_::_%n files_" => array("%n failas","%n failai","%n failų"), "{dirs} and {files}" => "{dirs} ir {files}", "_Uploading %n file_::_Uploading %n files_" => array("Įkeliamas %n failas","Įkeliami %n failai","Įkeliama %n failų"), "'.' is an invalid file name." => "'.' yra neleidžiamas failo pavadinime.", -"File name cannot be empty." => "Failo pavadinimas negali būti tuščias.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Neleistinas pavadinimas, '\\', '/', '<', '>', ':', '\"', '|', '?' ir '*' yra neleidžiami.", "Your storage is full, files can not be updated or synced anymore!" => "Jūsų visa vieta serveryje užimta", "Your storage is almost full ({usedSpacePercent}%)" => "Jūsų vieta serveryje beveik visa užimta ({usedSpacePercent}%)", +"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "Šifravimo programa įjungta, bet Jūsų raktai nėra pritaikyti. Prašome atsijungti ir vėl prisijungti", +"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "Netinkamas privatus raktas Šifravimo programai. Prašome atnaujinti savo privataus rakto slaptažodį asmeniniuose nustatymuose, kad atkurti prieigą prie šifruotų failų.", "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Šifravimas buvo išjungtas, bet Jūsų failai vis dar užšifruoti. Prašome eiti į asmeninius nustatymus ir iššifruoti savo failus.", "Your download is being prepared. This might take some time if the files are big." => "Jūsų atsisiuntimas yra paruošiamas. tai gali užtrukti jei atsisiunčiamas didelis failas.", "Error moving file" => "Klaida perkeliant failą", +"Error" => "Klaida", "Name" => "Pavadinimas", "Size" => "Dydis", "Modified" => "Pakeista", @@ -62,14 +72,14 @@ $TRANSLATIONS = array( "Save" => "Išsaugoti", "New" => "Naujas", "Text file" => "Teksto failas", +"New folder" => "Naujas aplankas", "Folder" => "Katalogas", "From link" => "Iš nuorodos", "Deleted files" => "Ištrinti failai", "Cancel upload" => "Atšaukti siuntimą", -"You don’t have write permissions here." => "Jūs neturite rašymo leidimo.", +"You don’t have permission to upload or create files here" => "Jūs neturite leidimo čia įkelti arba kurti failus", "Nothing in here. Upload something!" => "Čia tuščia. Įkelkite ką nors!", "Download" => "Atsisiųsti", -"Unshare" => "Nebesidalinti", "Delete" => "Ištrinti", "Upload too large" => "Įkėlimui failas per didelis", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Bandomų įkelti failų dydis viršija maksimalų, kuris leidžiamas šiame serveryje", diff --git a/apps/files/l10n/lv.php b/apps/files/l10n/lv.php index cefaea62818..7f8975b2940 100644 --- a/apps/files/l10n/lv.php +++ b/apps/files/l10n/lv.php @@ -2,6 +2,7 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "Nevarēja pārvietot %s — jau eksistē datne ar tādu nosaukumu", "Could not move %s" => "Nevarēja pārvietot %s", +"File name cannot be empty." => "Datnes nosaukums nevar būt tukšs.", "Unable to set upload directory." => "Nevar uzstādīt augšupielādes mapi.", "Invalid Token" => "Nepareiza pilnvara", "No file was uploaded. Unknown error" => "Netika augšupielādēta neviena datne. Nezināma kļūda", @@ -18,29 +19,23 @@ $TRANSLATIONS = array( "Not enough space available" => "Nepietiek brīvas vietas", "Upload cancelled." => "Augšupielāde ir atcelta.", "File upload is in progress. Leaving the page now will cancel the upload." => "Notiek augšupielāde. Pametot lapu tagad, tiks atcelta augšupielāde.", -"URL cannot be empty." => "URL nevar būt tukšs.", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Kļūdains mapes nosaukums. 'Shared' lietošana ir rezervēta no ownCloud", -"Error" => "Kļūda", +"{new_name} already exists" => "{new_name} jau eksistē", "Share" => "Dalīties", "Delete permanently" => "Dzēst pavisam", "Rename" => "Pārsaukt", "Pending" => "Gaida savu kārtu", -"{new_name} already exists" => "{new_name} jau eksistē", -"replace" => "aizvietot", -"suggest name" => "ieteiktais nosaukums", -"cancel" => "atcelt", "replaced {new_name} with {old_name}" => "aizvietoja {new_name} ar {old_name}", "undo" => "atsaukt", "_%n folder_::_%n folders_" => array("%n mapes","%n mape","%n mapes"), "_%n file_::_%n files_" => array("%n faili","%n fails","%n faili"), "_Uploading %n file_::_Uploading %n files_" => array("%n","Augšupielāde %n failu","Augšupielāde %n failus"), "'.' is an invalid file name." => "'.' ir nederīgs datnes nosaukums.", -"File name cannot be empty." => "Datnes nosaukums nevar būt tukšs.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nederīgs nosaukums, nav atļauti '\\', '/', '<', '>', ':', '\"', '|', '?' un '*'.", "Your storage is full, files can not be updated or synced anymore!" => "Jūsu krātuve ir pilna, datnes vairs nevar augšupielādēt vai sinhronizēt!", "Your storage is almost full ({usedSpacePercent}%)" => "Jūsu krātuve ir gandrīz pilna ({usedSpacePercent}%)", "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Šifrēšana tika atslēgta, tomēr jūsu faili joprojām ir šifrēti. Atšifrēt failus var Personiskajos uzstādījumos.", "Your download is being prepared. This might take some time if the files are big." => "Tiek sagatavota lejupielāde. Tas var aizņemt kādu laiciņu, ja datnes ir lielas.", +"Error" => "Kļūda", "Name" => "Nosaukums", "Size" => "Izmērs", "Modified" => "Mainīts", @@ -56,14 +51,13 @@ $TRANSLATIONS = array( "Save" => "Saglabāt", "New" => "Jauna", "Text file" => "Teksta datne", +"New folder" => "Jauna mape", "Folder" => "Mape", "From link" => "No saites", "Deleted files" => "Dzēstās datnes", "Cancel upload" => "Atcelt augšupielādi", -"You don’t have write permissions here." => "Jums nav tiesību šeit rakstīt.", "Nothing in here. Upload something!" => "Te vēl nekas nav. Rīkojies, sāc augšupielādēt!", "Download" => "Lejupielādēt", -"Unshare" => "Pārtraukt dalīšanos", "Delete" => "Dzēst", "Upload too large" => "Datne ir par lielu, lai to augšupielādētu", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Augšupielādējamās datnes pārsniedz servera pieļaujamo datņu augšupielādes apjomu", diff --git a/apps/files/l10n/mk.php b/apps/files/l10n/mk.php index 2306db6921a..fadf5efc07b 100644 --- a/apps/files/l10n/mk.php +++ b/apps/files/l10n/mk.php @@ -1,5 +1,16 @@ <?php $TRANSLATIONS = array( +"Could not move %s - File with this name already exists" => "Не можам да го преместам %s - Датотека со такво име веќе постои", +"Could not move %s" => "Не можам да ги префрлам %s", +"File name cannot be empty." => "Името на датотеката не може да биде празно.", +"Not a valid source" => "Не е валиден извор", +"Error while downloading %s to %s" => "Грешка додека преземам %s to %s", +"Error when creating the file" => "Грешка при креирање на датотека", +"Folder name cannot be empty." => "Името на папката не може да биде празно.", +"Folder name must not contain \"/\". Please choose a different name." => "Името на папката не смее да содржи \"/\". Одберете друго име.", +"Error when creating the folder" => "Грешка при креирање на папка", +"Unable to set upload directory." => "Не може да се постави папката за префрлање на податоци.", +"Invalid Token" => "Грешен токен", "No file was uploaded. Unknown error" => "Ниту еден фајл не се вчита. Непозната грешка", "There is no error, the file uploaded with success" => "Датотеката беше успешно подигната.", "The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Подигнатата датотека ја надминува upload_max_filesize директивата во php.ini:", @@ -8,27 +19,41 @@ $TRANSLATIONS = array( "No file was uploaded" => "Не беше подигната датотека.", "Missing a temporary folder" => "Недостасува привремена папка", "Failed to write to disk" => "Неуспеав да запишам на диск", +"Not enough storage available" => "Нема доволно слободен сториџ", +"Upload failed. Could not find uploaded file" => "Префрлањето е неуспешно. Не можам да го најдам префрлената датотека.", +"Invalid directory." => "Погрешна папка.", "Files" => "Датотеки", +"Not enough space available" => "Немате доволно дисков простор", "Upload cancelled." => "Преземањето е прекинато.", +"Could not get result from server." => "Не можам да добијам резултат од серверот.", "File upload is in progress. Leaving the page now will cancel the upload." => "Подигање на датотека е во тек. Напуштење на страницата ќе го прекине.", -"URL cannot be empty." => "Адресата неможе да биде празна.", -"Error" => "Грешка", +"URL cannot be empty" => "URL-то не може да биде празно", +"In the home folder 'Shared' is a reserved filename" => "Во домашната папка, 'Shared' е резервирано има на датотека/папка", +"{new_name} already exists" => "{new_name} веќе постои", +"Could not create file" => "Не множам да креирам датотека", +"Could not create folder" => "Не можам да креирам папка", "Share" => "Сподели", +"Delete permanently" => "Трајно избришани", "Rename" => "Преименувај", "Pending" => "Чека", -"{new_name} already exists" => "{new_name} веќе постои", -"replace" => "замени", -"suggest name" => "предложи име", -"cancel" => "откажи", +"Could not rename file" => "Не можам да ја преименувам датотеката", "replaced {new_name} with {old_name}" => "заменета {new_name} со {old_name}", "undo" => "врати", "_%n folder_::_%n folders_" => array("",""), "_%n file_::_%n files_" => array("",""), +"{dirs} and {files}" => "{dirs} и {files}", "_Uploading %n file_::_Uploading %n files_" => array("",""), +"'.' is an invalid file name." => "'.' е грешно име за датотека.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Неправилно име. , '\\', '/', '<', '>', ':', '\"', '|', '?' и '*' не се дозволени.", +"Your storage is full, files can not be updated or synced anymore!" => "Вашиот сториџ е полн, датотеките веќе не можат да се освежуваат или синхронизираат!", +"Your storage is almost full ({usedSpacePercent}%)" => "Вашиот сториџ е скоро полн ({usedSpacePercent}%)", +"Your download is being prepared. This might take some time if the files are big." => "Вашето преземање се подготвува. Ова може да потрае до колку датотеките се големи.", +"Error moving file" => "Грешка при префрлање на датотека", +"Error" => "Грешка", "Name" => "Име", "Size" => "Големина", "Modified" => "Променето", +"%s could not be renamed" => "%s не може да биде преименуван", "Upload" => "Подигни", "File handling" => "Ракување со датотеки", "Maximum upload size" => "Максимална големина за подигање", @@ -42,14 +67,15 @@ $TRANSLATIONS = array( "Text file" => "Текстуална датотека", "Folder" => "Папка", "From link" => "Од врска", +"Deleted files" => "Избришани датотеки", "Cancel upload" => "Откажи прикачување", "Nothing in here. Upload something!" => "Тука нема ништо. Снимете нешто!", "Download" => "Преземи", -"Unshare" => "Не споделувај", "Delete" => "Избриши", "Upload too large" => "Фајлот кој се вчитува е преголем", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Датотеките кои се обидувате да ги подигнете ја надминуваат максималната големина за подигнување датотеки на овој сервер.", "Files are being scanned, please wait." => "Се скенираат датотеки, ве молам почекајте.", -"Current scanning" => "Моментално скенирам" +"Current scanning" => "Моментално скенирам", +"Upgrading filesystem cache..." => "Го надградувам кешот на фјал системот..." ); $PLURAL_FORMS = "nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;"; diff --git a/apps/files/l10n/ms_MY.php b/apps/files/l10n/ms_MY.php index 61bbf81cd8a..0a7a50abb1a 100644 --- a/apps/files/l10n/ms_MY.php +++ b/apps/files/l10n/ms_MY.php @@ -9,14 +9,13 @@ $TRANSLATIONS = array( "Failed to write to disk" => "Gagal untuk disimpan", "Files" => "Fail-fail", "Upload cancelled." => "Muatnaik dibatalkan.", -"Error" => "Ralat", "Share" => "Kongsi", +"Rename" => "Namakan", "Pending" => "Dalam proses", -"replace" => "ganti", -"cancel" => "Batal", "_%n folder_::_%n folders_" => array(""), "_%n file_::_%n files_" => array(""), "_Uploading %n file_::_Uploading %n files_" => array(""), +"Error" => "Ralat", "Name" => "Nama", "Size" => "Saiz", "Modified" => "Dimodifikasi", diff --git a/apps/files/l10n/nb_NO.php b/apps/files/l10n/nb_NO.php index 8fda251a2bc..ebd7ef38998 100644 --- a/apps/files/l10n/nb_NO.php +++ b/apps/files/l10n/nb_NO.php @@ -2,6 +2,7 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "Kan ikke flytte %s - En fil med samme navn finnes allerede", "Could not move %s" => "Kunne ikke flytte %s", +"File name cannot be empty." => "Filnavn kan ikke være tomt.", "Unable to set upload directory." => "Kunne ikke sette opplastingskatalog.", "Invalid Token" => "Ugyldig nøkkel", "No file was uploaded. Unknown error" => "Ingen filer ble lastet opp. Ukjent feil.", @@ -18,28 +19,22 @@ $TRANSLATIONS = array( "Not enough space available" => "Ikke nok lagringsplass", "Upload cancelled." => "Opplasting avbrutt.", "File upload is in progress. Leaving the page now will cancel the upload." => "Filopplasting pågår. Forlater du siden nå avbrytes opplastingen.", -"URL cannot be empty." => "URL-en kan ikke være tom.", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Ugyldig mappenavn. Bruk av \"Shared\" er reservert av ownCloud.", -"Error" => "Feil", +"{new_name} already exists" => "{new_name} finnes allerede", "Share" => "Del", "Delete permanently" => "Slett permanent", "Rename" => "Gi nytt navn", "Pending" => "Ventende", -"{new_name} already exists" => "{new_name} finnes allerede", -"replace" => "erstatt", -"suggest name" => "foreslå navn", -"cancel" => "avbryt", "replaced {new_name} with {old_name}" => "erstattet {new_name} med {old_name}", "undo" => "angre", "_%n folder_::_%n folders_" => array("%n mappe","%n mapper"), "_%n file_::_%n files_" => array("%n fil","%n filer"), "_Uploading %n file_::_Uploading %n files_" => array("Laster opp %n fil","Laster opp %n filer"), "'.' is an invalid file name." => "'.' er et ugyldig filnavn.", -"File name cannot be empty." => "Filnavn kan ikke være tomt.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Ugyldig navn, '\\', '/', '<', '>', ':', '\"', '|', '?' og '*' er ikke tillatt.", "Your storage is full, files can not be updated or synced anymore!" => "Lagringsplass er oppbrukt, filer kan ikke lenger oppdateres eller synkroniseres!", "Your storage is almost full ({usedSpacePercent}%)" => "Lagringsplass er nesten brukt opp ([usedSpacePercent}%)", "Your download is being prepared. This might take some time if the files are big." => "Nedlastingen din klargjøres. Hvis filene er store kan dette ta litt tid.", +"Error" => "Feil", "Name" => "Navn", "Size" => "Størrelse", "Modified" => "Endret", @@ -55,14 +50,13 @@ $TRANSLATIONS = array( "Save" => "Lagre", "New" => "Ny", "Text file" => "Tekstfil", +"New folder" => "Ny mappe", "Folder" => "Mappe", "From link" => "Fra link", "Deleted files" => "Slettet filer", "Cancel upload" => "Avbryt opplasting", -"You don’t have write permissions here." => "Du har ikke skrivetilgang her.", "Nothing in here. Upload something!" => "Ingenting her. Last opp noe!", "Download" => "Last ned", -"Unshare" => "Avslutt deling", "Delete" => "Slett", "Upload too large" => "Filen er for stor", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Filene du prøver å laste opp er for store for å laste opp til denne serveren.", diff --git a/apps/files/l10n/nds.php b/apps/files/l10n/nds.php new file mode 100644 index 00000000000..0157af093e9 --- /dev/null +++ b/apps/files/l10n/nds.php @@ -0,0 +1,7 @@ +<?php +$TRANSLATIONS = array( +"_%n folder_::_%n folders_" => array("",""), +"_%n file_::_%n files_" => array("",""), +"_Uploading %n file_::_Uploading %n files_" => array("","") +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files/l10n/nl.php b/apps/files/l10n/nl.php index 65ad5265237..a391e25b952 100644 --- a/apps/files/l10n/nl.php +++ b/apps/files/l10n/nl.php @@ -2,6 +2,16 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "Kon %s niet verplaatsen - Er bestaat al een bestand met deze naam", "Could not move %s" => "Kon %s niet verplaatsen", +"File name cannot be empty." => "Bestandsnaam kan niet leeg zijn.", +"File name must not contain \"/\". Please choose a different name." => "De bestandsnaam mag geen \"/\" bevatten. Kies een andere naam.", +"The name %s is already used in the folder %s. Please choose a different name." => "De naam %s bestaat al in map %s. Kies een andere naam.", +"Not a valid source" => "Geen geldige bron", +"Server is not allowed to open URLs, please check the server configuration" => "Server mag geen URS's openen, controleer de server configuratie", +"Error while downloading %s to %s" => "Fout bij downloaden %s naar %s", +"Error when creating the file" => "Fout bij creëren bestand", +"Folder name cannot be empty." => "Mapnaam mag niet leeg zijn.", +"Folder name must not contain \"/\". Please choose a different name." => "De mapnaam mag geen \"/\" bevatten. Kies een andere naam.", +"Error when creating the folder" => "Fout bij aanmaken map", "Unable to set upload directory." => "Kan upload map niet instellen.", "Invalid Token" => "Ongeldig Token", "No file was uploaded. Unknown error" => "Er was geen bestand geladen. Onbekende fout", @@ -13,38 +23,47 @@ $TRANSLATIONS = array( "Missing a temporary folder" => "Er ontbreekt een tijdelijke map", "Failed to write to disk" => "Schrijven naar schijf mislukt", "Not enough storage available" => "Niet genoeg opslagruimte beschikbaar", +"Upload failed. Could not get file info." => "Upload mislukt, Kon geen bestandsinfo krijgen.", +"Upload failed. Could not find uploaded file" => "Upload mislukt. Kon ge-uploade bestand niet vinden", "Invalid directory." => "Ongeldige directory.", "Files" => "Bestanden", +"Unable to upload {filename} as it is a directory or has 0 bytes" => "Kan {filename} niet uploaden omdat het een map is of 0 bytes groot is", "Not enough space available" => "Niet genoeg ruimte beschikbaar", "Upload cancelled." => "Uploaden geannuleerd.", +"Could not get result from server." => "Kon het resultaat van de server niet terugkrijgen.", "File upload is in progress. Leaving the page now will cancel the upload." => "Bestandsupload is bezig. Wanneer de pagina nu verlaten wordt, stopt de upload.", -"URL cannot be empty." => "URL kan niet leeg zijn.", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Ongeldige mapnaam. Gebruik van 'Gedeeld' is voorbehouden aan Owncloud zelf", -"Error" => "Fout", +"URL cannot be empty" => "URL mag niet leeg zijn", +"In the home folder 'Shared' is a reserved filename" => "in de home map 'Shared' is een gereserveerde bestandsnaam", +"{new_name} already exists" => "{new_name} bestaat al", +"Could not create file" => "Kon bestand niet creëren", +"Could not create folder" => "Kon niet creëren map", +"Error fetching URL" => "Fout bij ophalen URL", "Share" => "Delen", "Delete permanently" => "Verwijder definitief", "Rename" => "Hernoem", "Pending" => "In behandeling", -"{new_name} already exists" => "{new_name} bestaat al", -"replace" => "vervang", -"suggest name" => "Stel een naam voor", -"cancel" => "annuleren", +"Could not rename file" => "Kon niet hernoemen bestand", "replaced {new_name} with {old_name}" => "verving {new_name} met {old_name}", "undo" => "ongedaan maken", +"Error deleting file." => "Fout bij verwijderen bestand.", "_%n folder_::_%n folders_" => array("","%n mappen"), "_%n file_::_%n files_" => array("","%n bestanden"), "{dirs} and {files}" => "{dirs} en {files}", "_Uploading %n file_::_Uploading %n files_" => array("%n bestand aan het uploaden","%n bestanden aan het uploaden"), "'.' is an invalid file name." => "'.' is een ongeldige bestandsnaam.", -"File name cannot be empty." => "Bestandsnaam kan niet leeg zijn.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Onjuiste naam; '\\', '/', '<', '>', ':', '\"', '|', '?' en '*' zijn niet toegestaan.", "Your storage is full, files can not be updated or synced anymore!" => "Uw opslagruimte zit vol, Bestanden kunnen niet meer worden ge-upload of gesynchroniseerd!", "Your storage is almost full ({usedSpacePercent}%)" => "Uw opslagruimte zit bijna vol ({usedSpacePercent}%)", +"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "Crypto app is geactiveerd, maar uw sleutels werden niet geïnitialiseerd. Log uit en log daarna opnieuw in.", +"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "Ongeldige privésleutel voor crypto app. Werk het privésleutel wachtwoord bij in uw persoonlijke instellingen om opnieuw toegang te krijgen tot uw versleutelde bestanden.", "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Encryptie is uitgeschakeld maar uw bestanden zijn nog steeds versleuteld. Ga naar uw persoonlijke instellingen om uw bestanden te decoderen.", "Your download is being prepared. This might take some time if the files are big." => "Uw download wordt voorbereid. Dit kan enige tijd duren bij grote bestanden.", +"Error moving file" => "Fout bij verplaatsen bestand", +"Error" => "Fout", "Name" => "Naam", "Size" => "Grootte", "Modified" => "Aangepast", +"Invalid folder name. Usage of 'Shared' is reserved." => "Ongeldige mapnaam. Gebruik van 'Shared' is gereserveerd.", "%s could not be renamed" => "%s kon niet worden hernoemd", "Upload" => "Uploaden", "File handling" => "Bestand", @@ -56,15 +75,16 @@ $TRANSLATIONS = array( "Maximum input size for ZIP files" => "Maximale grootte voor ZIP bestanden", "Save" => "Bewaren", "New" => "Nieuw", +"New text file" => "Nieuw tekstbestand", "Text file" => "Tekstbestand", +"New folder" => "Nieuwe map", "Folder" => "Map", "From link" => "Vanaf link", "Deleted files" => "Verwijderde bestanden", "Cancel upload" => "Upload afbreken", -"You don’t have write permissions here." => "U hebt hier geen schrijfpermissies.", +"You don’t have permission to upload or create files here" => "U hebt geen toestemming om hier te uploaden of bestanden te maken", "Nothing in here. Upload something!" => "Er bevindt zich hier niets. Upload een bestand!", "Download" => "Downloaden", -"Unshare" => "Stop met delen", "Delete" => "Verwijder", "Upload too large" => "Upload is te groot", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "De bestanden die u probeert te uploaden zijn groter dan de maximaal toegestane bestandsgrootte voor deze server.", diff --git a/apps/files/l10n/nn_NO.php b/apps/files/l10n/nn_NO.php index e29b1d3ad36..a5e6e737eae 100644 --- a/apps/files/l10n/nn_NO.php +++ b/apps/files/l10n/nn_NO.php @@ -2,6 +2,7 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "Klarte ikkje flytta %s – det finst allereie ei fil med dette namnet", "Could not move %s" => "Klarte ikkje flytta %s", +"File name cannot be empty." => "Filnamnet kan ikkje vera tomt.", "Unable to set upload directory." => "Klarte ikkje å endra opplastingsmappa.", "Invalid Token" => "Ugyldig token", "No file was uploaded. Unknown error" => "Ingen filer lasta opp. Ukjend feil", @@ -22,17 +23,11 @@ $TRANSLATIONS = array( "Upload cancelled." => "Opplasting avbroten.", "Could not get result from server." => "Klarte ikkje å henta resultat frå tenaren.", "File upload is in progress. Leaving the page now will cancel the upload." => "Fila lastar no opp. Viss du forlèt sida no vil opplastinga verta avbroten.", -"URL cannot be empty." => "Nettadressa kan ikkje vera tom.", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Ugyldig mappenamn. Mappa «Shared» er reservert av ownCloud", -"Error" => "Feil", +"{new_name} already exists" => "{new_name} finst allereie", "Share" => "Del", "Delete permanently" => "Slett for godt", "Rename" => "Endra namn", "Pending" => "Under vegs", -"{new_name} already exists" => "{new_name} finst allereie", -"replace" => "byt ut", -"suggest name" => "føreslå namn", -"cancel" => "avbryt", "replaced {new_name} with {old_name}" => "bytte ut {new_name} med {old_name}", "undo" => "angre", "_%n folder_::_%n folders_" => array("%n mappe","%n mapper"), @@ -40,13 +35,13 @@ $TRANSLATIONS = array( "{dirs} and {files}" => "{dirs} og {files}", "_Uploading %n file_::_Uploading %n files_" => array("Lastar opp %n fil","Lastar opp %n filer"), "'.' is an invalid file name." => "«.» er eit ugyldig filnamn.", -"File name cannot be empty." => "Filnamnet kan ikkje vera tomt.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Ugyldig namn, «\\», «/», «<», «>», «:», «\"», «|», «?» og «*» er ikkje tillate.", "Your storage is full, files can not be updated or synced anymore!" => "Lagringa di er full, kan ikkje lenger oppdatera eller synkronisera!", "Your storage is almost full ({usedSpacePercent}%)" => "Lagringa di er nesten full ({usedSpacePercent} %)", "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Kryptering er skrudd av, men filene dine er enno krypterte. Du kan dekryptera filene i personlege innstillingar.", "Your download is being prepared. This might take some time if the files are big." => "Gjer klar nedlastinga di. Dette kan ta ei stund viss filene er store.", "Error moving file" => "Feil ved flytting av fil", +"Error" => "Feil", "Name" => "Namn", "Size" => "Storleik", "Modified" => "Endra", @@ -66,10 +61,8 @@ $TRANSLATIONS = array( "From link" => "Frå lenkje", "Deleted files" => "Sletta filer", "Cancel upload" => "Avbryt opplasting", -"You don’t have write permissions here." => "Du har ikkje skriverettar her.", "Nothing in here. Upload something!" => "Ingenting her. Last noko opp!", "Download" => "Last ned", -"Unshare" => "Udel", "Delete" => "Slett", "Upload too large" => "For stor opplasting", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Filene du prøver å lasta opp er større enn maksgrensa til denne tenaren.", diff --git a/apps/files/l10n/oc.php b/apps/files/l10n/oc.php index a6d8f91458e..eb1a9038b08 100644 --- a/apps/files/l10n/oc.php +++ b/apps/files/l10n/oc.php @@ -9,17 +9,14 @@ $TRANSLATIONS = array( "Files" => "Fichièrs", "Upload cancelled." => "Amontcargar anullat.", "File upload is in progress. Leaving the page now will cancel the upload." => "Un amontcargar es a se far. Daissar aquesta pagina ara tamparà lo cargament. ", -"Error" => "Error", "Share" => "Parteja", "Rename" => "Torna nomenar", "Pending" => "Al esperar", -"replace" => "remplaça", -"suggest name" => "nom prepausat", -"cancel" => "anulla", "undo" => "defar", "_%n folder_::_%n folders_" => array("",""), "_%n file_::_%n files_" => array("",""), "_Uploading %n file_::_Uploading %n files_" => array("",""), +"Error" => "Error", "Name" => "Nom", "Size" => "Talha", "Modified" => "Modificat", @@ -38,7 +35,6 @@ $TRANSLATIONS = array( "Cancel upload" => " Anulla l'amontcargar", "Nothing in here. Upload something!" => "Pas res dedins. Amontcarga qualquaren", "Download" => "Avalcarga", -"Unshare" => "Pas partejador", "Delete" => "Escafa", "Upload too large" => "Amontcargament tròp gròs", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Los fichièrs que sias a amontcargar son tròp pesucs per la talha maxi pel servidor.", diff --git a/apps/files/l10n/pa.php b/apps/files/l10n/pa.php index d8c50f2d1bc..63fcbe12dda 100644 --- a/apps/files/l10n/pa.php +++ b/apps/files/l10n/pa.php @@ -1,13 +1,13 @@ <?php $TRANSLATIONS = array( "Files" => "ਫਾਇਲਾਂ", -"Error" => "ਗਲਤੀ", "Share" => "ਸਾਂਝਾ ਕਰੋ", "Rename" => "ਨਾਂ ਬਦਲੋ", "undo" => "ਵਾਪਸ", "_%n folder_::_%n folders_" => array("",""), "_%n file_::_%n files_" => array("",""), "_Uploading %n file_::_Uploading %n files_" => array("",""), +"Error" => "ਗਲਤੀ", "Upload" => "ਅੱਪਲੋਡ", "Cancel upload" => "ਅੱਪਲੋਡ ਰੱਦ ਕਰੋ", "Download" => "ਡਾਊਨਲੋਡ", diff --git a/apps/files/l10n/pl.php b/apps/files/l10n/pl.php index 50a247d2e0f..031bd508700 100644 --- a/apps/files/l10n/pl.php +++ b/apps/files/l10n/pl.php @@ -2,6 +2,16 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "Nie można było przenieść %s - Plik o takiej nazwie już istnieje", "Could not move %s" => "Nie można było przenieść %s", +"File name cannot be empty." => "Nazwa pliku nie może być pusta.", +"File name must not contain \"/\". Please choose a different name." => "Nazwa pliku nie może zawierać \"/\". Proszę wybrać inną nazwę.", +"The name %s is already used in the folder %s. Please choose a different name." => "Nazwa %s jest już używana w folderze %s. Proszę wybrać inną nazwę.", +"Not a valid source" => "Niepoprawne źródło", +"Server is not allowed to open URLs, please check the server configuration" => "Serwer nie mógł otworzyć adresów URL, należy sprawdzić konfigurację serwera", +"Error while downloading %s to %s" => "Błąd podczas pobierania %s do %S", +"Error when creating the file" => "Błąd przy tworzeniu pliku", +"Folder name cannot be empty." => "Nazwa folderu nie może być pusta.", +"Folder name must not contain \"/\". Please choose a different name." => "Nazwa folderu nie może zawierać \"/\". Proszę wybrać inną nazwę.", +"Error when creating the folder" => "Błąd przy tworzeniu folderu", "Unable to set upload directory." => "Nie można ustawić katalog wczytywania.", "Invalid Token" => "Nieprawidłowy Token", "No file was uploaded. Unknown error" => "Żaden plik nie został załadowany. Nieznany błąd", @@ -22,34 +32,38 @@ $TRANSLATIONS = array( "Upload cancelled." => "Wczytywanie anulowane.", "Could not get result from server." => "Nie można uzyskać wyniku z serwera.", "File upload is in progress. Leaving the page now will cancel the upload." => "Wysyłanie pliku jest w toku. Jeśli opuścisz tę stronę, wysyłanie zostanie przerwane.", -"URL cannot be empty." => "URL nie może być pusty.", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Nieprawidłowa nazwa folderu. Wykorzystanie 'Shared' jest zarezerwowane przez ownCloud", -"Error" => "Błąd", +"URL cannot be empty" => "URL nie może być pusty", +"In the home folder 'Shared' is a reserved filename" => "W katalogu domowym \"Shared\" jest zarezerwowana nazwa pliku", +"{new_name} already exists" => "{new_name} już istnieje", +"Could not create file" => "Nie można utworzyć pliku", +"Could not create folder" => "Nie można utworzyć folderu", +"Error fetching URL" => "Błąd przy pobieraniu adresu URL", "Share" => "Udostępnij", "Delete permanently" => "Trwale usuń", "Rename" => "Zmień nazwę", "Pending" => "Oczekujące", -"{new_name} already exists" => "{new_name} już istnieje", -"replace" => "zastąp", -"suggest name" => "zasugeruj nazwę", -"cancel" => "anuluj", +"Could not rename file" => "Nie można zmienić nazwy pliku", "replaced {new_name} with {old_name}" => "zastąpiono {new_name} przez {old_name}", "undo" => "cofnij", +"Error deleting file." => "Błąd podczas usuwania pliku", "_%n folder_::_%n folders_" => array("%n katalog","%n katalogi","%n katalogów"), "_%n file_::_%n files_" => array("%n plik","%n pliki","%n plików"), -"{dirs} and {files}" => "{katalogi} and {pliki}", +"{dirs} and {files}" => "{dirs} and {files}", "_Uploading %n file_::_Uploading %n files_" => array("Wysyłanie %n pliku","Wysyłanie %n plików","Wysyłanie %n plików"), "'.' is an invalid file name." => "„.” jest nieprawidłową nazwą pliku.", -"File name cannot be empty." => "Nazwa pliku nie może być pusta.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nieprawidłowa nazwa. Znaki '\\', '/', '<', '>', ':', '\"', '|', '?' oraz '*' są niedozwolone.", "Your storage is full, files can not be updated or synced anymore!" => "Magazyn jest pełny. Pliki nie mogą zostać zaktualizowane lub zsynchronizowane!", "Your storage is almost full ({usedSpacePercent}%)" => "Twój magazyn jest prawie pełny ({usedSpacePercent}%)", +"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "Aplikacja szyfrująca jest aktywna, ale twoje klucze nie zostały zainicjowane, prosze wyloguj się i zaloguj ponownie.", +"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "Klucz prywatny nie jest poprawny! Może Twoje hasło zostało zmienione z zewnątrz. Można zaktualizować hasło klucza prywatnego w ustawieniach osobistych w celu odzyskania dostępu do plików", "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Szyfrowanie zostało wyłączone, ale nadal pliki są zaszyfrowane. Przejdź do ustawień osobistych i tam odszyfruj pliki.", "Your download is being prepared. This might take some time if the files are big." => "Pobieranie jest przygotowywane. Może to zająć trochę czasu jeśli pliki są duże.", "Error moving file" => "Błąd prz przenoszeniu pliku", +"Error" => "Błąd", "Name" => "Nazwa", "Size" => "Rozmiar", "Modified" => "Modyfikacja", +"Invalid folder name. Usage of 'Shared' is reserved." => "Niepoprawna nazwa folderu. Wykorzystanie \"Shared\" jest zarezerwowane.", "%s could not be renamed" => "%s nie można zmienić nazwy", "Upload" => "Wyślij", "File handling" => "Zarządzanie plikami", @@ -61,15 +75,16 @@ $TRANSLATIONS = array( "Maximum input size for ZIP files" => "Maksymalna wielkość pliku wejściowego ZIP ", "Save" => "Zapisz", "New" => "Nowy", +"New text file" => "Nowy plik tekstowy", "Text file" => "Plik tekstowy", +"New folder" => "Nowy folder", "Folder" => "Folder", "From link" => "Z odnośnika", "Deleted files" => "Pliki usunięte", "Cancel upload" => "Anuluj wysyłanie", -"You don’t have write permissions here." => "Nie masz uprawnień do zapisu w tym miejscu.", +"You don’t have permission to upload or create files here" => "Nie masz uprawnień do wczytywania lub tworzenia plików w tym miejscu", "Nothing in here. Upload something!" => "Pusto. Wyślij coś!", "Download" => "Pobierz", -"Unshare" => "Zatrzymaj współdzielenie", "Delete" => "Usuń", "Upload too large" => "Ładowany plik jest za duży", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Pliki, które próbujesz przesłać, przekraczają maksymalną dopuszczalną wielkość.", diff --git a/apps/files/l10n/pt_BR.php b/apps/files/l10n/pt_BR.php index cd960208565..f84dcfcd488 100644 --- a/apps/files/l10n/pt_BR.php +++ b/apps/files/l10n/pt_BR.php @@ -2,6 +2,16 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "Impossível mover %s - Um arquivo com este nome já existe", "Could not move %s" => "Impossível mover %s", +"File name cannot be empty." => "O nome do arquivo não pode estar vazio.", +"File name must not contain \"/\". Please choose a different name." => "O nome do arquivo não deve conter \"/\". Por favor, escolha um nome diferente.", +"The name %s is already used in the folder %s. Please choose a different name." => "O nome %s já é usado na pasta %s. Por favor, escolha um nome diferente.", +"Not a valid source" => "Não é uma fonte válida", +"Server is not allowed to open URLs, please check the server configuration" => "Não é permitido ao servidor abrir URLs, por favor verificar a configuração do servidor.", +"Error while downloading %s to %s" => "Erro ao baixar %s para %s", +"Error when creating the file" => "Erro ao criar o arquivo", +"Folder name cannot be empty." => "O nome da pasta não pode estar vazio.", +"Folder name must not contain \"/\". Please choose a different name." => "O nome da pasta não pode conter \"/\". Por favor, escolha um nome diferente.", +"Error when creating the folder" => "Erro ao criar a pasta", "Unable to set upload directory." => "Impossível configurar o diretório de upload", "Invalid Token" => "Token inválido", "No file was uploaded. Unknown error" => "Nenhum arquivo foi enviado. Erro desconhecido", @@ -22,34 +32,38 @@ $TRANSLATIONS = array( "Upload cancelled." => "Envio cancelado.", "Could not get result from server." => "Não foi possível obter o resultado do servidor.", "File upload is in progress. Leaving the page now will cancel the upload." => "Upload em andamento. Sair da página agora resultará no cancelamento do envio.", -"URL cannot be empty." => "URL não pode ficar em branco", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Nome de pasta inválido. O uso do nome 'Compartilhado' é reservado ao ownCloud", -"Error" => "Erro", +"URL cannot be empty" => "URL não pode estar vazia", +"In the home folder 'Shared' is a reserved filename" => "Na pasta home 'Shared- Compartilhada' é um nome reservado", +"{new_name} already exists" => "{new_name} já existe", +"Could not create file" => "Não foi possível criar o arquivo", +"Could not create folder" => "Não foi possível criar a pasta", +"Error fetching URL" => "Erro ao buscar URL", "Share" => "Compartilhar", "Delete permanently" => "Excluir permanentemente", "Rename" => "Renomear", "Pending" => "Pendente", -"{new_name} already exists" => "{new_name} já existe", -"replace" => "substituir", -"suggest name" => "sugerir nome", -"cancel" => "cancelar", +"Could not rename file" => "Não foi possível renomear o arquivo", "replaced {new_name} with {old_name}" => "Substituído {old_name} por {new_name} ", "undo" => "desfazer", +"Error deleting file." => "Erro eliminando o arquivo.", "_%n folder_::_%n folders_" => array("%n pasta","%n pastas"), "_%n file_::_%n files_" => array("%n arquivo","%n arquivos"), "{dirs} and {files}" => "{dirs} e {files}", "_Uploading %n file_::_Uploading %n files_" => array("Enviando %n arquivo","Enviando %n arquivos"), "'.' is an invalid file name." => "'.' é um nome de arquivo inválido.", -"File name cannot be empty." => "O nome do arquivo não pode estar vazio.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nome inválido, '\\', '/', '<', '>', ':', '\"', '|', '?' e '*' não são permitidos.", "Your storage is full, files can not be updated or synced anymore!" => "Seu armazenamento está cheio, arquivos não podem mais ser atualizados ou sincronizados!", "Your storage is almost full ({usedSpacePercent}%)" => "Seu armazenamento está quase cheio ({usedSpacePercent}%)", +"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "App de encriptação está ativado, mas as chaves não estão inicializadas, por favor log-out e faça login novamente", +"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "Chave do App de Encriptação é inválida. Por favor, atualize sua senha de chave privada em suas configurações pessoais para recuperar o acesso a seus arquivos criptografados.", "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Encriptação foi desabilitada mas seus arquivos continuam encriptados. Por favor vá a suas configurações pessoais para descriptar seus arquivos.", "Your download is being prepared. This might take some time if the files are big." => "Seu download está sendo preparado. Isto pode levar algum tempo se os arquivos forem grandes.", "Error moving file" => "Erro movendo o arquivo", +"Error" => "Erro", "Name" => "Nome", "Size" => "Tamanho", "Modified" => "Modificado", +"Invalid folder name. Usage of 'Shared' is reserved." => "Nome da pasta inválido. Uso de 'Shared' é reservado.", "%s could not be renamed" => "%s não pode ser renomeado", "Upload" => "Upload", "File handling" => "Tratamento de Arquivo", @@ -61,15 +75,16 @@ $TRANSLATIONS = array( "Maximum input size for ZIP files" => "Tamanho máximo para arquivo ZIP", "Save" => "Guardar", "New" => "Novo", +"New text file" => "Novo arquivo texto", "Text file" => "Arquivo texto", +"New folder" => "Nova pasta", "Folder" => "Pasta", "From link" => "Do link", "Deleted files" => "Arquivos apagados", "Cancel upload" => "Cancelar upload", -"You don’t have write permissions here." => "Você não possui permissão de escrita aqui.", +"You don’t have permission to upload or create files here" => "Você não tem permissão para carregar ou criar arquivos aqui", "Nothing in here. Upload something!" => "Nada aqui.Carrege alguma coisa!", "Download" => "Baixar", -"Unshare" => "Descompartilhar", "Delete" => "Excluir", "Upload too large" => "Upload muito grande", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Os arquivos que você está tentando carregar excedeu o tamanho máximo para arquivos no servidor.", diff --git a/apps/files/l10n/pt_PT.php b/apps/files/l10n/pt_PT.php index f6d61fc9873..4b9fade2e22 100644 --- a/apps/files/l10n/pt_PT.php +++ b/apps/files/l10n/pt_PT.php @@ -2,6 +2,7 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "Não foi possível mover o ficheiro %s - Já existe um ficheiro com esse nome", "Could not move %s" => "Não foi possível move o ficheiro %s", +"File name cannot be empty." => "O nome do ficheiro não pode estar vazio.", "Unable to set upload directory." => "Não foi possível criar o diretório de upload", "Invalid Token" => "Token inválido", "No file was uploaded. Unknown error" => "Nenhum ficheiro foi carregado. Erro desconhecido", @@ -13,22 +14,18 @@ $TRANSLATIONS = array( "Missing a temporary folder" => "Está a faltar a pasta temporária", "Failed to write to disk" => "Falhou a escrita no disco", "Not enough storage available" => "Não há espaço suficiente em disco", +"Upload failed. Could not get file info." => "O carregamento falhou. Não foi possível obter a informação do ficheiro.", "Invalid directory." => "Directório Inválido", "Files" => "Ficheiros", "Not enough space available" => "Espaço em disco insuficiente!", "Upload cancelled." => "Envio cancelado.", +"Could not get result from server." => "Não foi possível obter o resultado do servidor.", "File upload is in progress. Leaving the page now will cancel the upload." => "Envio de ficheiro em progresso. Irá cancelar o envio se sair da página agora.", -"URL cannot be empty." => "O URL não pode estar vazio.", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Nome da pasta inválido. Palavra 'Shared' é reservado pela ownCloud", -"Error" => "Erro", +"{new_name} already exists" => "O nome {new_name} já existe", "Share" => "Partilhar", "Delete permanently" => "Eliminar permanentemente", "Rename" => "Renomear", "Pending" => "Pendente", -"{new_name} already exists" => "O nome {new_name} já existe", -"replace" => "substituir", -"suggest name" => "sugira um nome", -"cancel" => "cancelar", "replaced {new_name} with {old_name}" => "substituido {new_name} por {old_name}", "undo" => "desfazer", "_%n folder_::_%n folders_" => array("%n pasta","%n pastas"), @@ -36,12 +33,13 @@ $TRANSLATIONS = array( "{dirs} and {files}" => "{dirs} e {files}", "_Uploading %n file_::_Uploading %n files_" => array("A carregar %n ficheiro","A carregar %n ficheiros"), "'.' is an invalid file name." => "'.' não é um nome de ficheiro válido!", -"File name cannot be empty." => "O nome do ficheiro não pode estar vazio.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nome Inválido, os caracteres '\\', '/', '<', '>', ':', '\"', '|', '?' e '*' não são permitidos.", "Your storage is full, files can not be updated or synced anymore!" => "O seu armazenamento está cheio, os ficheiros não podem ser sincronizados.", "Your storage is almost full ({usedSpacePercent}%)" => "O seu espaço de armazenamento está quase cheiro ({usedSpacePercent}%)", "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "A encriptação foi desactivada mas os seus ficheiros continuam encriptados. Por favor consulte as suas definições pessoais para desencriptar os ficheiros.", "Your download is being prepared. This might take some time if the files are big." => "O seu download está a ser preparado. Este processo pode demorar algum tempo se os ficheiros forem grandes.", +"Error moving file" => "Erro ao mover o ficheiro", +"Error" => "Erro", "Name" => "Nome", "Size" => "Tamanho", "Modified" => "Modificado", @@ -57,14 +55,13 @@ $TRANSLATIONS = array( "Save" => "Guardar", "New" => "Novo", "Text file" => "Ficheiro de texto", +"New folder" => "Nova Pasta", "Folder" => "Pasta", "From link" => "Da ligação", "Deleted files" => "Ficheiros eliminados", "Cancel upload" => "Cancelar envio", -"You don’t have write permissions here." => "Não tem permissões de escrita aqui.", "Nothing in here. Upload something!" => "Vazio. Envie alguma coisa!", "Download" => "Transferir", -"Unshare" => "Deixar de partilhar", "Delete" => "Eliminar", "Upload too large" => "Upload muito grande", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Os ficheiro que está a tentar enviar excedem o tamanho máximo de envio neste servidor.", diff --git a/apps/files/l10n/ro.php b/apps/files/l10n/ro.php index b1b9af45d38..933625d8d1e 100644 --- a/apps/files/l10n/ro.php +++ b/apps/files/l10n/ro.php @@ -2,6 +2,7 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "%s nu se poate muta - Fișierul cu acest nume există deja ", "Could not move %s" => "Nu s-a putut muta %s", +"File name cannot be empty." => "Numele fișierului nu poate rămâne gol.", "Unable to set upload directory." => "Imposibil de a seta directorul pentru incărcare.", "Invalid Token" => "Jeton Invalid", "No file was uploaded. Unknown error" => "Nici un fișier nu a fost încărcat. Eroare necunoscută", @@ -22,17 +23,11 @@ $TRANSLATIONS = array( "Upload cancelled." => "Încărcare anulată.", "Could not get result from server." => "Nu se poate obține rezultatul de la server.", "File upload is in progress. Leaving the page now will cancel the upload." => "Fișierul este în curs de încărcare. Părăsirea paginii va întrerupe încărcarea.", -"URL cannot be empty." => "Adresa URL nu poate fi golita", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Nume de dosar invalid. Utilizarea 'Shared' e rezervată de ownCloud", -"Error" => "Eroare", +"{new_name} already exists" => "{new_name} deja exista", "Share" => "a imparti", "Delete permanently" => "Stergere permanenta", "Rename" => "Redenumire", "Pending" => "in timpul", -"{new_name} already exists" => "{new_name} deja exista", -"replace" => "înlocuire", -"suggest name" => "sugerează nume", -"cancel" => "anulare", "replaced {new_name} with {old_name}" => "{new_name} inlocuit cu {old_name}", "undo" => "Anulează ultima acțiune", "_%n folder_::_%n folders_" => array("%n director","%n directoare","%n directoare"), @@ -40,13 +35,13 @@ $TRANSLATIONS = array( "{dirs} and {files}" => "{dirs} și {files}", "_Uploading %n file_::_Uploading %n files_" => array("Se încarcă %n fișier.","Se încarcă %n fișiere.","Se încarcă %n fișiere."), "'.' is an invalid file name." => "'.' este un nume invalid de fișier.", -"File name cannot be empty." => "Numele fișierului nu poate rămâne gol.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nume invalide, '\\', '/', '<', '>', ':', '\"', '|', '?' si '*' nu sunt permise.", "Your storage is full, files can not be updated or synced anymore!" => "Spatiul de stocare este plin, fisierele nu mai pot fi actualizate sau sincronizate", "Your storage is almost full ({usedSpacePercent}%)" => "Spatiul de stocare este aproape plin {spatiu folosit}%", "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "criptarea a fost disactivata dar fisierele sant inca criptate.va rog intrati in setarile personale pentru a decripta fisierele", "Your download is being prepared. This might take some time if the files are big." => "in curs de descarcare. Aceasta poate să dureze ceva timp dacă fișierele sunt mari.", "Error moving file" => "Eroare la mutarea fișierului", +"Error" => "Eroare", "Name" => "Nume", "Size" => "Dimensiune", "Modified" => "Modificat", @@ -66,10 +61,8 @@ $TRANSLATIONS = array( "From link" => "de la adresa", "Deleted files" => "Sterge fisierele", "Cancel upload" => "Anulează încărcarea", -"You don’t have write permissions here." => "Nu ai permisiunea de a scrie aici.", "Nothing in here. Upload something!" => "Nimic aici. Încarcă ceva!", "Download" => "Descarcă", -"Unshare" => "Anulare", "Delete" => "Șterge", "Upload too large" => "Fișierul încărcat este prea mare", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Fișierul care l-ai încărcat a depășită limita maximă admisă la încărcare pe acest server.", diff --git a/apps/files/l10n/ru.php b/apps/files/l10n/ru.php index 143a3379ad4..968da63aaca 100644 --- a/apps/files/l10n/ru.php +++ b/apps/files/l10n/ru.php @@ -2,6 +2,16 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "Невозможно переместить %s - файл с таким именем уже существует", "Could not move %s" => "Невозможно переместить %s", +"File name cannot be empty." => "Имя файла не может быть пустым.", +"File name must not contain \"/\". Please choose a different name." => "Имя файла не должно содержать символ \"/\". Пожалуйста, выберите другое имя.", +"The name %s is already used in the folder %s. Please choose a different name." => "Имя %s уже используется в папке %s. Пожалуйста выберите другое имя.", +"Not a valid source" => "Неправильный источник", +"Server is not allowed to open URLs, please check the server configuration" => "Сервер не позволяет открывать URL-адреса, пожалуйста, проверьте настройки сервера", +"Error while downloading %s to %s" => "Ошибка при загрузке %s в %s", +"Error when creating the file" => "Ошибка при создании файла", +"Folder name cannot be empty." => "Имя папки не может быть пустым.", +"Folder name must not contain \"/\". Please choose a different name." => "Имя папки не должно содержать символ \"/\". Пожалуйста, выберите другое имя.", +"Error when creating the folder" => "Ошибка при создании папки", "Unable to set upload directory." => "Не удалось установить каталог загрузки.", "Invalid Token" => "Недопустимый маркер", "No file was uploaded. Unknown error" => "Файл не был загружен. Неизвестная ошибка", @@ -22,34 +32,38 @@ $TRANSLATIONS = array( "Upload cancelled." => "Загрузка отменена.", "Could not get result from server." => "Не получен ответ от сервера", "File upload is in progress. Leaving the page now will cancel the upload." => "Файл в процессе загрузки. Покинув страницу вы прервёте загрузку.", -"URL cannot be empty." => "Ссылка не может быть пустой.", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Неправильное имя каталога. Имя 'Shared' зарезервировано.", -"Error" => "Ошибка", +"URL cannot be empty" => "Ссылка не может быть пустой.", +"In the home folder 'Shared' is a reserved filename" => "В домашней папке 'Shared' зарезервированное имя файла", +"{new_name} already exists" => "{new_name} уже существует", +"Could not create file" => "Не удалось создать файл", +"Could not create folder" => "Не удалось создать папку", +"Error fetching URL" => "Ошибка получения URL", "Share" => "Открыть доступ", "Delete permanently" => "Удалено навсегда", "Rename" => "Переименовать", "Pending" => "Ожидание", -"{new_name} already exists" => "{new_name} уже существует", -"replace" => "заменить", -"suggest name" => "предложить название", -"cancel" => "отмена", +"Could not rename file" => "Не удалось переименовать файл", "replaced {new_name} with {old_name}" => "заменено {new_name} на {old_name}", "undo" => "отмена", +"Error deleting file." => "Ошибка при удалении файла.", "_%n folder_::_%n folders_" => array("%n папка","%n папки","%n папок"), "_%n file_::_%n files_" => array("%n файл","%n файла","%n файлов"), "{dirs} and {files}" => "{dirs} и {files}", "_Uploading %n file_::_Uploading %n files_" => array("Закачка %n файла","Закачка %n файлов","Закачка %n файлов"), "'.' is an invalid file name." => "'.' - неправильное имя файла.", -"File name cannot be empty." => "Имя файла не может быть пустым.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Неправильное имя, '\\', '/', '<', '>', ':', '\"', '|', '?' и '*' недопустимы.", "Your storage is full, files can not be updated or synced anymore!" => "Ваше дисковое пространство полностью заполнено, произведите очистку перед загрузкой новых файлов.", "Your storage is almost full ({usedSpacePercent}%)" => "Ваше хранилище почти заполнено ({usedSpacePercent}%)", +"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "Приложение для шифрования активно, но ваши ключи не инициализированы, пожалуйста, перелогиньтесь", +"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "Неверный приватный ключ для приложения шифрования. Пожалуйста, обноваите ваш приватный ключ в персональных настройках чтобы восстановить доступ к вашим зашифрованным файлам.", "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Шифрование было отключено, но ваши файлы все еще зашифрованы. Пожалуйста, зайдите на страницу персональных настроек для того, чтобы расшифровать ваши файлы.", "Your download is being prepared. This might take some time if the files are big." => "Загрузка началась. Это может потребовать много времени, если файл большого размера.", "Error moving file" => "Ошибка при перемещении файла", +"Error" => "Ошибка", "Name" => "Имя", "Size" => "Размер", "Modified" => "Изменён", +"Invalid folder name. Usage of 'Shared' is reserved." => "Неправильное имя каталога. Имя 'Shared' зарезервировано.", "%s could not be renamed" => "%s не может быть переименован", "Upload" => "Загрузка", "File handling" => "Управление файлами", @@ -61,15 +75,16 @@ $TRANSLATIONS = array( "Maximum input size for ZIP files" => "Максимальный исходный размер для ZIP файлов", "Save" => "Сохранить", "New" => "Новый", +"New text file" => "Новый текстовый файл", "Text file" => "Текстовый файл", +"New folder" => "Новая папка", "Folder" => "Папка", "From link" => "Из ссылки", "Deleted files" => "Удалённые файлы", "Cancel upload" => "Отмена загрузки", -"You don’t have write permissions here." => "У вас нет разрешений на запись здесь.", +"You don’t have permission to upload or create files here" => "У вас недостаточно прав для загрузки или создания файлов отсюда.", "Nothing in here. Upload something!" => "Здесь ничего нет. Загрузите что-нибудь!", "Download" => "Скачать", -"Unshare" => "Закрыть общий доступ", "Delete" => "Удалить", "Upload too large" => "Файл слишком велик", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Файлы, которые вы пытаетесь загрузить, превышают лимит для файлов на этом сервере.", diff --git a/apps/files/l10n/si_LK.php b/apps/files/l10n/si_LK.php index 7d24370a092..44decfef1b0 100644 --- a/apps/files/l10n/si_LK.php +++ b/apps/files/l10n/si_LK.php @@ -10,17 +10,13 @@ $TRANSLATIONS = array( "Files" => "ගොනු", "Upload cancelled." => "උඩුගත කිරීම අත් හරින්න ලදී", "File upload is in progress. Leaving the page now will cancel the upload." => "උඩුගතකිරීමක් සිදුවේ. පිටුව හැර යාමෙන් එය නැවතෙනු ඇත", -"URL cannot be empty." => "යොමුව හිස් විය නොහැක", -"Error" => "දෝෂයක්", "Share" => "බෙදා හදා ගන්න", "Rename" => "නැවත නම් කරන්න", -"replace" => "ප්රතිස්ථාපනය කරන්න", -"suggest name" => "නමක් යෝජනා කරන්න", -"cancel" => "අත් හරින්න", "undo" => "නිෂ්ප්රභ කරන්න", "_%n folder_::_%n folders_" => array("",""), "_%n file_::_%n files_" => array("",""), "_Uploading %n file_::_Uploading %n files_" => array("",""), +"Error" => "දෝෂයක්", "Name" => "නම", "Size" => "ප්රමාණය", "Modified" => "වෙනස් කළ", @@ -40,7 +36,6 @@ $TRANSLATIONS = array( "Cancel upload" => "උඩුගත කිරීම අත් හරින්න", "Nothing in here. Upload something!" => "මෙහි කිසිවක් නොමැත. යමක් උඩුගත කරන්න", "Download" => "බාන්න", -"Unshare" => "නොබෙදු", "Delete" => "මකා දමන්න", "Upload too large" => "උඩුගත කිරීම විශාල වැඩිය", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "ඔබ උඩුගත කිරීමට තැත් කරන ගොනු මෙම සේවාදායකයා උඩුගත කිරීමට ඉඩදී ඇති උපරිම ගොනු විශාලත්වයට වඩා වැඩිය", diff --git a/apps/files/l10n/sk.php b/apps/files/l10n/sk.php index a3178a95c47..53daf549eaa 100644 --- a/apps/files/l10n/sk.php +++ b/apps/files/l10n/sk.php @@ -1,7 +1,11 @@ <?php $TRANSLATIONS = array( +"Share" => "Zdieľať", "_%n folder_::_%n folders_" => array("","",""), "_%n file_::_%n files_" => array("","",""), -"_Uploading %n file_::_Uploading %n files_" => array("","","") +"_Uploading %n file_::_Uploading %n files_" => array("","",""), +"Save" => "Uložiť", +"Download" => "Stiahnuť", +"Delete" => "Odstrániť" ); $PLURAL_FORMS = "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"; diff --git a/apps/files/l10n/sk_SK.php b/apps/files/l10n/sk_SK.php index 962ce7d7e9b..2d0eb25f622 100644 --- a/apps/files/l10n/sk_SK.php +++ b/apps/files/l10n/sk_SK.php @@ -2,48 +2,66 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "Nie je možné presunúť %s - súbor s týmto menom už existuje", "Could not move %s" => "Nie je možné presunúť %s", +"File name cannot be empty." => "Meno súboru nemôže byť prázdne", +"File name must not contain \"/\". Please choose a different name." => "Názov súboru nesmie obsahovať \"/\". Prosím zvoľte iný názov.", +"The name %s is already used in the folder %s. Please choose a different name." => "Názov %s už používa priečinok s%. Prosím zvoľte iný názov.", +"Not a valid source" => "Neplatný zdroj", +"Error while downloading %s to %s" => "Chyba pri sťahovaní súboru %s do %s", +"Error when creating the file" => "Chyba pri vytváraní súboru", +"Folder name cannot be empty." => "Názov priečinka nemôže byť prázdny.", +"Folder name must not contain \"/\". Please choose a different name." => "Názov priečinka nesmie obsahovať \"/\". Prosím zvoľte iný názov.", +"Error when creating the folder" => "Chyba pri vytváraní priečinka", "Unable to set upload directory." => "Nemožno nastaviť priečinok pre nahrané súbory.", "Invalid Token" => "Neplatný token", -"No file was uploaded. Unknown error" => "Žiaden súbor nebol odoslaný. Neznáma chyba", +"No file was uploaded. Unknown error" => "Žiaden súbor nebol nahraný. Neznáma chyba", "There is no error, the file uploaded with success" => "Nenastala žiadna chyba, súbor bol úspešne nahraný", -"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Nahraný súbor predčil konfiguračnú direktívu upload_max_filesize v súbore php.ini:", +"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Nahraný súbor prekročil limit nastavený v upload_max_filesize v súbore php.ini:", "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Ukladaný súbor prekračuje nastavenie MAX_FILE_SIZE z volieb HTML formulára.", "The uploaded file was only partially uploaded" => "Ukladaný súbor sa nahral len čiastočne", "No file was uploaded" => "Žiadny súbor nebol uložený", "Missing a temporary folder" => "Chýba dočasný priečinok", "Failed to write to disk" => "Zápis na disk sa nepodaril", "Not enough storage available" => "Nedostatok dostupného úložného priestoru", +"Upload failed. Could not get file info." => "Nahrávanie zlyhalo. Nepodarilo sa získať informácie o súbore.", +"Upload failed. Could not find uploaded file" => "Nahrávanie zlyhalo. Nepodarilo sa nájsť nahrávaný súbor", "Invalid directory." => "Neplatný priečinok.", "Files" => "Súbory", +"Unable to upload {filename} as it is a directory or has 0 bytes" => "Nemožno nahrať súbor {filename}, pretože je to priečinok, alebo má 0 bitov", "Not enough space available" => "Nie je k dispozícii dostatok miesta", "Upload cancelled." => "Odosielanie zrušené.", +"Could not get result from server." => "Nepodarilo sa dostať výsledky zo servera.", "File upload is in progress. Leaving the page now will cancel the upload." => "Opustenie stránky zruší práve prebiehajúce odosielanie súboru.", -"URL cannot be empty." => "URL nemôže byť prázdne.", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Neplatný názov priečinka. Názov \"Shared\" je rezervovaný pre ownCloud", -"Error" => "Chyba", +"URL cannot be empty" => "URL nemôže byť prázdna", +"In the home folder 'Shared' is a reserved filename" => "V domovskom priečinku je názov \"Shared\" vyhradený názov súboru", +"{new_name} already exists" => "{new_name} už existuje", +"Could not create file" => "Nemožno vytvoriť súbor", +"Could not create folder" => "Nemožno vytvoriť priečinok", "Share" => "Zdieľať", "Delete permanently" => "Zmazať trvalo", "Rename" => "Premenovať", "Pending" => "Prebieha", -"{new_name} already exists" => "{new_name} už existuje", -"replace" => "nahradiť", -"suggest name" => "pomôcť s menom", -"cancel" => "zrušiť", +"Could not rename file" => "Nemožno premenovať súbor", "replaced {new_name} with {old_name}" => "prepísaný {new_name} súborom {old_name}", "undo" => "vrátiť", +"Error deleting file." => "Chyba pri mazaní súboru.", "_%n folder_::_%n folders_" => array("%n priečinok","%n priečinky","%n priečinkov"), "_%n file_::_%n files_" => array("%n súbor","%n súbory","%n súborov"), +"{dirs} and {files}" => "{dirs} a {files}", "_Uploading %n file_::_Uploading %n files_" => array("Nahrávam %n súbor","Nahrávam %n súbory","Nahrávam %n súborov"), "'.' is an invalid file name." => "'.' je neplatné meno súboru.", -"File name cannot be empty." => "Meno súboru nemôže byť prázdne", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nesprávne meno, '\\', '/', '<', '>', ':', '\"', '|', '?' a '*' nie sú povolené hodnoty.", "Your storage is full, files can not be updated or synced anymore!" => "Vaše úložisko je plné. Súbory nemožno aktualizovať ani synchronizovať!", "Your storage is almost full ({usedSpacePercent}%)" => "Vaše úložisko je takmer plné ({usedSpacePercent}%)", +"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "Aplikácia na šifrovanie je zapnutá, ale vaše kľúče nie sú inicializované. Odhláste sa a znovu sa prihláste.", +"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "Chybný súkromný kľúč na šifrovanie aplikácií. Zaktualizujte si heslo súkromného kľúča v svojom osobnom nastavení, aby ste znovu získali prístup k svojim zašifrovaným súborom.", "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Šifrovanie bolo zakázané, ale vaše súbory sú stále zašifrované. Prosím, choďte do osobného nastavenia pre dešifrovanie súborov.", "Your download is being prepared. This might take some time if the files are big." => "Vaše sťahovanie sa pripravuje. Ak sú sťahované súbory veľké, môže to chvíľu trvať.", +"Error moving file" => "Chyba pri presúvaní súboru", +"Error" => "Chyba", "Name" => "Názov", "Size" => "Veľkosť", "Modified" => "Upravené", +"Invalid folder name. Usage of 'Shared' is reserved." => "Názov priečinka je chybný. Použitie názvu 'Shared' nie je povolené.", "%s could not be renamed" => "%s nemohol byť premenovaný", "Upload" => "Odoslať", "File handling" => "Nastavenie správania sa k súborom", @@ -54,16 +72,17 @@ $TRANSLATIONS = array( "0 is unlimited" => "0 znamená neobmedzené", "Maximum input size for ZIP files" => "Najväčšia veľkosť ZIP súborov", "Save" => "Uložiť", -"New" => "Nová", +"New" => "Nový", +"New text file" => "Nový textový súbor", "Text file" => "Textový súbor", +"New folder" => "Nový priečinok", "Folder" => "Priečinok", "From link" => "Z odkazu", "Deleted files" => "Zmazané súbory", "Cancel upload" => "Zrušiť odosielanie", -"You don’t have write permissions here." => "Nemáte oprávnenie na zápis.", +"You don’t have permission to upload or create files here" => "Nemáte oprávnenie sem nahrávať alebo vytvoriť súbory", "Nothing in here. Upload something!" => "Žiadny súbor. Nahrajte niečo!", "Download" => "Sťahovanie", -"Unshare" => "Zrušiť zdieľanie", "Delete" => "Zmazať", "Upload too large" => "Nahrávanie je príliš veľké", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Súbory, ktoré sa snažíte nahrať, presahujú maximálnu veľkosť pre nahratie súborov na tento server.", diff --git a/apps/files/l10n/sl.php b/apps/files/l10n/sl.php index 7190753eac9..037e5f6b6b0 100644 --- a/apps/files/l10n/sl.php +++ b/apps/files/l10n/sl.php @@ -1,7 +1,17 @@ <?php $TRANSLATIONS = array( -"Could not move %s - File with this name already exists" => "%s ni mogoče premakniti - datoteka s tem imenom že obstaja", -"Could not move %s" => "Ni mogoče premakniti %s", +"Could not move %s - File with this name already exists" => "Datoteke %s ni mogoče premakniti - datoteka s tem imenom že obstaja.", +"Could not move %s" => "Datoteke %s ni mogoče premakniti", +"File name cannot be empty." => "Ime datoteke ne sme biti prazno polje.", +"File name must not contain \"/\". Please choose a different name." => "Ime datoteke ne sme vsebovati znaka \"/\". Določiti je treba drugo ime.", +"The name %s is already used in the folder %s. Please choose a different name." => "Ime %s je že v mapi %s že v uporabi. Izbrati je treba drugo ime.", +"Not a valid source" => "Vir ni veljaven", +"Server is not allowed to open URLs, please check the server configuration" => "Odpiranje naslovov URL preko strežnika ni dovoljeno. Preverite nastavitve strežnika.", +"Error while downloading %s to %s" => "Napaka med prejemanjem %s v mapo %s", +"Error when creating the file" => "Napaka med ustvarjanjem datoteke", +"Folder name cannot be empty." => "Ime mape ne more biti prazna vrednost.", +"Folder name must not contain \"/\". Please choose a different name." => "Ime mape ne sme vsebovati znaka \"/\". Določiti je treba drugo ime.", +"Error when creating the folder" => "Napaka med ustvarjanjem mape", "Unable to set upload directory." => "Mapo, v katero boste prenašali dokumente, ni mogoče določiti", "Invalid Token" => "Neveljaven žeton", "No file was uploaded. Unknown error" => "Ni poslane datoteke. Neznana napaka.", @@ -13,37 +23,48 @@ $TRANSLATIONS = array( "Missing a temporary folder" => "Manjka začasna mapa", "Failed to write to disk" => "Pisanje na disk je spodletelo", "Not enough storage available" => "Na voljo ni dovolj prostora", +"Upload failed. Could not get file info." => "Pošiljanje je spodletelo. Ni mogoče pridobiti podrobnosti datoteke.", +"Upload failed. Could not find uploaded file" => "Pošiljanje je spodletelo. Ni mogoče najti poslane datoteke.", "Invalid directory." => "Neveljavna mapa.", "Files" => "Datoteke", +"Unable to upload {filename} as it is a directory or has 0 bytes" => "Ni mogoče poslati datoteke {filename}, saj je to ali mapa ali pa je velikost datoteke 0 bajtov.", "Not enough space available" => "Na voljo ni dovolj prostora.", "Upload cancelled." => "Pošiljanje je preklicano.", +"Could not get result from server." => "Ni mogoče pridobiti podatkov s strežnika.", "File upload is in progress. Leaving the page now will cancel the upload." => "V teku je pošiljanje datoteke. Če zapustite to stran zdaj, bo pošiljanje preklicano.", -"URL cannot be empty." => "Naslov URL ne sme biti prazna vrednost.", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Ime mape je neveljavno. Uporaba oznake \"Souporaba\" je rezervirana za ownCloud", -"Error" => "Napaka", +"URL cannot be empty" => "Polje naslova URL ne sme biti prazno", +"In the home folder 'Shared' is a reserved filename" => "V domači mapi ni dovoljeno ustvariti mape z imenom 'Souporabe', saj je ime zadržano za javno mapo.", +"{new_name} already exists" => "{new_name} že obstaja", +"Could not create file" => "Ni mogoče ustvariti datoteke", +"Could not create folder" => "Ni mogoče ustvariti mape", +"Error fetching URL" => "Napaka pridobivanja naslova URL", "Share" => "Souporaba", "Delete permanently" => "Izbriši dokončno", "Rename" => "Preimenuj", "Pending" => "V čakanju ...", -"{new_name} already exists" => "{new_name} že obstaja", -"replace" => "zamenjaj", -"suggest name" => "predlagaj ime", -"cancel" => "prekliči", +"Could not rename file" => "Ni mogoče preimenovati datoteke", "replaced {new_name} with {old_name}" => "preimenovano ime {new_name} z imenom {old_name}", "undo" => "razveljavi", -"_%n folder_::_%n folders_" => array("","","",""), -"_%n file_::_%n files_" => array("","","",""), -"_Uploading %n file_::_Uploading %n files_" => array("","","",""), +"Error deleting file." => "Napaka brisanja datoteke.", +"_%n folder_::_%n folders_" => array("%n mapa","%n mapi","%n mape","%n map"), +"_%n file_::_%n files_" => array("%n datoteka","%n datoteki","%n datoteke","%n datotek"), +"{dirs} and {files}" => "{dirs} in {files}", +"_Uploading %n file_::_Uploading %n files_" => array("Posodabljanje %n datoteke","Posodabljanje %n datotek","Posodabljanje %n datotek","Posodabljanje %n datotek"), "'.' is an invalid file name." => "'.' je neveljavno ime datoteke.", -"File name cannot be empty." => "Ime datoteke ne sme biti prazno polje.", -"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Neveljavno ime, znaki '\\', '/', '<', '>', ':', '\"', '|', '?' in '*' niso dovoljeni.", +"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Neveljavno ime; znaki '\\', '/', '<', '>', ':', '\"', '|', '?' in '*' niso dovoljeni.", "Your storage is full, files can not be updated or synced anymore!" => "Shramba je povsem napolnjena. Datotek ni več mogoče posodabljati in usklajevati!", -"Your storage is almost full ({usedSpacePercent}%)" => "Mesto za shranjevanje je skoraj polno ({usedSpacePercent}%)", -"Your download is being prepared. This might take some time if the files are big." => "Postopek priprave datoteke za prejem je lahko dolgotrajen, če je datoteka zelo velika.", +"Your storage is almost full ({usedSpacePercent}%)" => "Prostor za shranjevanje je skoraj do konca zaseden ({usedSpacePercent}%)", +"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "Program za šifriranje je omogočen, vendar ni začet. Odjavite se in nato ponovno prijavite.", +"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "Ni ustreznega osebnega ključa za program za šifriranje. Posodobite osebni ključ za dostop do šifriranih datotek med nastavitvami.", +"Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Šifriranje je onemogočeno, datoteke pa so še vedno šifrirane. Odšifrirajte jih med nastavitvami.", +"Your download is being prepared. This might take some time if the files are big." => "Postopek priprave datoteke za prejem je lahko dolgotrajen, kadar je datoteka zelo velika.", +"Error moving file" => "Napaka premikanja datoteke", +"Error" => "Napaka", "Name" => "Ime", "Size" => "Velikost", "Modified" => "Spremenjeno", -"%s could not be renamed" => "%s ni bilo mogoče preimenovati", +"Invalid folder name. Usage of 'Shared' is reserved." => "Neveljavno ime mape. Ime 'Souporaba' je zadržana za javno mapo.", +"%s could not be renamed" => "%s ni mogoče preimenovati", "Upload" => "Pošlji", "File handling" => "Upravljanje z datotekami", "Maximum upload size" => "Največja velikost za pošiljanja", @@ -54,15 +75,16 @@ $TRANSLATIONS = array( "Maximum input size for ZIP files" => "Največja vhodna velikost za datoteke ZIP", "Save" => "Shrani", "New" => "Novo", +"New text file" => "Nova besedilna datoteka", "Text file" => "Besedilna datoteka", +"New folder" => "Nova mapa", "Folder" => "Mapa", "From link" => "Iz povezave", "Deleted files" => "Izbrisane datoteke", "Cancel upload" => "Prekliči pošiljanje", -"You don’t have write permissions here." => "Za to mesto ni ustreznih dovoljenj za pisanje.", +"You don’t have permission to upload or create files here" => "Ni ustreznih dovoljenj za pošiljanje ali ustvarjanje datotek na tem mestu.", "Nothing in here. Upload something!" => "Tukaj še ni ničesar. Najprej je treba kakšno datoteko poslati v oblak!", "Download" => "Prejmi", -"Unshare" => "Prekliči souporabo", "Delete" => "Izbriši", "Upload too large" => "Prekoračenje omejitve velikosti", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Datoteke, ki jih želite poslati, presegajo največjo dovoljeno velikost na strežniku.", diff --git a/apps/files/l10n/sq.php b/apps/files/l10n/sq.php index ecc066a284c..a06b6821afe 100644 --- a/apps/files/l10n/sq.php +++ b/apps/files/l10n/sq.php @@ -1,75 +1,68 @@ <?php $TRANSLATIONS = array( -"Could not move %s - File with this name already exists" => "%s nuk u spostua - Aty ekziston një skedar me të njëjtin emër", -"Could not move %s" => "%s nuk u spostua", -"Unable to set upload directory." => "Nuk është i mundur caktimi i dosjes së ngarkimit.", -"Invalid Token" => "Përmbajtje e pavlefshme", -"No file was uploaded. Unknown error" => "Nuk u ngarkua asnjë skedar. Veprim i gabuar i panjohur", -"There is no error, the file uploaded with success" => "Nuk pati veprime të gabuara, skedari u ngarkua me sukses", -"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Skedari i ngarkuar tejkalon udhëzimin upload_max_filesize tek php.ini:", -"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Skedari i ngarkuar tejkalon udhëzimin MAX_FILE_SIZE të specifikuar në formularin HTML", -"The uploaded file was only partially uploaded" => "Skedari i ngarkuar u ngarkua vetëm pjesërisht", -"No file was uploaded" => "Nuk u ngarkua asnjë skedar", -"Missing a temporary folder" => "Një dosje e përkohshme nuk u gjet", -"Failed to write to disk" => "Ruajtja në disk dështoi", -"Not enough storage available" => "Nuk ka mbetur hapësirë memorizimi e mjaftueshme", -"Invalid directory." => "Dosje e pavlefshme.", -"Files" => "Skedarët", -"Not enough space available" => "Nuk ka hapësirë memorizimi e mjaftueshme", -"Upload cancelled." => "Ngarkimi u anulua.", -"File upload is in progress. Leaving the page now will cancel the upload." => "Ngarkimi i skedarit është në vazhdim. Nqse ndërroni faqen tani ngarkimi do të anulohet.", -"URL cannot be empty." => "URL-i nuk mund të jetë bosh.", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Emri i dosjes është i pavlefshëm. Përdorimi i \"Shared\" është i rezervuar nga Owncloud-i", -"Error" => "Veprim i gabuar", -"Share" => "Nda", -"Delete permanently" => "Elimino përfundimisht", -"Rename" => "Riemërto", -"Pending" => "Pezulluar", -"{new_name} already exists" => "{new_name} ekziston", -"replace" => "zëvëndëso", -"suggest name" => "sugjero një emër", -"cancel" => "anulo", -"replaced {new_name} with {old_name}" => "U zëvëndësua {new_name} me {old_name}", -"undo" => "anulo", +"Could not move %s - File with this name already exists" => "E pa mundur zhvendosja e %s - ekziston nje skedar me te njetin emer", +"Could not move %s" => "Nuk mund të zhvendoset %s", +"File name cannot be empty." => "Emri i skedarit nuk mund të jetë bosh.", +"Unable to set upload directory." => "E pa mundur të vendoset dosja e ngarkimit", +"Invalid Token" => "Shenjë e gabuar", +"No file was uploaded. Unknown error" => "Asnjë skedar nuk u dërgua. Gabim i pa njohur", +"There is no error, the file uploaded with success" => "Skedari u ngarkua me sukses", +"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Skedari i ngarkuar tejkalon limitin hapsirës së lejuar në php.ini", +"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" => "Skedari i ngarkuar tejlakon vlerën MAX_FILE_SIZE të përcaktuar në formën HTML", +"The uploaded file was only partially uploaded" => "Skedari është ngakruar vetëm pjesërisht", +"No file was uploaded" => "Asnjë skedar nuk është ngarkuar", +"Missing a temporary folder" => "Mungon dosja e përkohshme", +"Failed to write to disk" => "Dështoi shkrimi në disk", +"Not enough storage available" => "Hapsira e arkivimit e pamjaftueshme", +"Invalid directory." => "Dosje e pavlefshme", +"Files" => "Skedarë", +"Not enough space available" => "Nuk ka hapsirë të nevojshme", +"Upload cancelled." => "Ngarkimi u anullua", +"File upload is in progress. Leaving the page now will cancel the upload." => "Skedari duke u ngarkuar. Largimi nga faqja do të anullojë ngarkimin", +"{new_name} already exists" => "{new_name} është ekzistues ", +"Share" => "Ndaj", +"Delete permanently" => "Fshi përfundimisht", +"Rename" => "Riemëro", +"Pending" => "Në vijim", +"replaced {new_name} with {old_name}" => "u zëvendësua {new_name} me {old_name}", +"undo" => "anullo", "_%n folder_::_%n folders_" => array("%n dosje","%n dosje"), "_%n file_::_%n files_" => array("%n skedar","%n skedarë"), "{dirs} and {files}" => "{dirs} dhe {files}", "_Uploading %n file_::_Uploading %n files_" => array("Po ngarkoj %n skedar","Po ngarkoj %n skedarë"), -"'.' is an invalid file name." => "'.' është emër i pavlefshëm.", -"File name cannot be empty." => "Emri i skedarit nuk mund të jetë bosh.", -"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Emër i pavlefshëm, '\\', '/', '<', '>', ':', '\"', '|', '?' dhe '*' nuk lejohen.", -"Your storage is full, files can not be updated or synced anymore!" => "Hapësira juaj e memorizimit është plot, nuk mund të ngarkoni apo sinkronizoni më skedarët.", -"Your storage is almost full ({usedSpacePercent}%)" => "Hapësira juaj e memorizimit është gati plot ({usedSpacePercent}%)", +"'.' is an invalid file name." => "'.' nuk është skedar i vlefshem.", +"Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Emër jo i vlefshëm, '\\', '/', '<', '>', ':', '\"', '|', '?' dhe '*' nuk lejohen.", +"Your storage is full, files can not be updated or synced anymore!" => "Hapsira juaj e arkivimit është plot, skedarët nuk mund të përditësohen ose sinkronizohen!", +"Your storage is almost full ({usedSpacePercent}%)" => "Hapsira juaj e arkivimit është pothuajse në fund ({usedSpacePercent}%)", "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Kodifikimi u çaktivizua por skedarët tuaj vazhdojnë të jenë të kodifikuar. Ju lutem shkoni tek parametrat personale për të dekodifikuar skedarët tuaj.", -"Your download is being prepared. This might take some time if the files are big." => "Shkarkimi juaj po përgatitet. Mund të duhet pak kohë nqse skedarët janë të mëdhenj.", +"Your download is being prepared. This might take some time if the files are big." => "Shkarkimi juaj është duke u përgatitur. Kjo mund të kërkojë kohë nëse skedarët janë të mëdhenj.", +"Error" => "Gabim", "Name" => "Emri", -"Size" => "Dimensioni", -"Modified" => "Modifikuar", +"Size" => "Madhësia", +"Modified" => "Ndryshuar", "%s could not be renamed" => "Nuk është i mundur riemërtimi i %s", "Upload" => "Ngarko", -"File handling" => "Trajtimi i skedarit", -"Maximum upload size" => "Dimensioni maksimal i ngarkimit", -"max. possible: " => "maks. i mundur:", -"Needed for multi-file and folder downloads." => "Duhet për shkarkimin e dosjeve dhe të skedarëve", -"Enable ZIP-download" => "Aktivizo shkarkimin e ZIP-eve", -"0 is unlimited" => "0 është i pakufizuar", -"Maximum input size for ZIP files" => "Dimensioni maksimal i ngarkimit të skedarëve ZIP", +"File handling" => "Trajtimi i Skedarëve", +"Maximum upload size" => "Madhësia maksimale e nagarkimit", +"max. possible: " => "maks i mundshëm", +"Needed for multi-file and folder downloads." => "Nevojitej shkarkim i shumë skedarëve dhe dosjeve", +"Enable ZIP-download" => "Mundëso skarkimin e ZIP", +"0 is unlimited" => "o është pa limit", +"Maximum input size for ZIP files" => "Maksimumi hyrës i skedarëve ZIP", "Save" => "Ruaj", -"New" => "I ri", -"Text file" => "Skedar teksti", +"New" => "E re", +"Text file" => "Skedar tekst", "Folder" => "Dosje", "From link" => "Nga lidhja", -"Deleted files" => "Skedarë të eliminuar", -"Cancel upload" => "Anulo ngarkimin", -"You don’t have write permissions here." => "Nuk keni të drejta për të shkruar këtu.", -"Nothing in here. Upload something!" => "Këtu nuk ka asgjë. Ngarkoni diçka!", +"Deleted files" => "Skedarë të fshirë ", +"Cancel upload" => "Anullo ngarkimin", +"Nothing in here. Upload something!" => "Këtu nuk ka asgje. Ngarko dicka", "Download" => "Shkarko", -"Unshare" => "Hiq ndarjen", -"Delete" => "Elimino", -"Upload too large" => "Ngarkimi është shumë i madh", -"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Skedarët që doni të ngarkoni tejkalojnë dimensionet maksimale për ngarkimet në këtë server.", -"Files are being scanned, please wait." => "Skedarët po analizohen, ju lutemi pritni.", -"Current scanning" => "Analizimi aktual", -"Upgrading filesystem cache..." => "Po përmirësoj memorjen e filesystem-it..." +"Delete" => "Fshi", +"Upload too large" => "Ngarkimi shumë i madh", +"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Skedarët që po mundoheni të ngarkoni e tejkalojnë madhësinë maksimale të lejuar nga serveri.", +"Files are being scanned, please wait." => "Skanerizimi i skedarit në proces. Ju lutem prisni.", +"Current scanning" => "Skanimi aktual", +"Upgrading filesystem cache..." => "Përditësimi i cache-se së sistemit në procesim..." ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files/l10n/sr.php b/apps/files/l10n/sr.php index fd3b2a2912f..e383b66e078 100644 --- a/apps/files/l10n/sr.php +++ b/apps/files/l10n/sr.php @@ -2,6 +2,7 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "Не могу да преместим %s – датотека с овим именом већ постоји", "Could not move %s" => "Не могу да преместим %s", +"File name cannot be empty." => "Име датотеке не може бити празно.", "No file was uploaded. Unknown error" => "Ниједна датотека није отпремљена услед непознате грешке", "There is no error, the file uploaded with success" => "Није дошло до грешке. Датотека је успешно отпремљена.", "The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Отпремљена датотека прелази смерницу upload_max_filesize у датотеци php.ini:", @@ -16,27 +17,22 @@ $TRANSLATIONS = array( "Not enough space available" => "Нема довољно простора", "Upload cancelled." => "Отпремање је прекинуто.", "File upload is in progress. Leaving the page now will cancel the upload." => "Отпремање датотеке је у току. Ако сада напустите страницу, прекинућете отпремање.", -"URL cannot be empty." => "Адреса не може бити празна.", -"Error" => "Грешка", +"{new_name} already exists" => "{new_name} већ постоји", "Share" => "Дели", "Delete permanently" => "Обриши за стално", "Rename" => "Преименуј", "Pending" => "На чекању", -"{new_name} already exists" => "{new_name} већ постоји", -"replace" => "замени", -"suggest name" => "предложи назив", -"cancel" => "откажи", "replaced {new_name} with {old_name}" => "замењено {new_name} са {old_name}", "undo" => "опозови", "_%n folder_::_%n folders_" => array("","",""), "_%n file_::_%n files_" => array("","",""), "_Uploading %n file_::_Uploading %n files_" => array("","",""), "'.' is an invalid file name." => "Датотека „.“ је неисправног имена.", -"File name cannot be empty." => "Име датотеке не може бити празно.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Неисправан назив. Следећи знакови нису дозвољени: \\, /, <, >, :, \", |, ? и *.", "Your storage is full, files can not be updated or synced anymore!" => "Ваше складиште је пуно. Датотеке више не могу бити ажуриране ни синхронизоване.", "Your storage is almost full ({usedSpacePercent}%)" => "Ваше складиште је скоро па пуно ({usedSpacePercent}%)", "Your download is being prepared. This might take some time if the files are big." => "Припремам преузимање. Ово може да потраје ако су датотеке велике.", +"Error" => "Грешка", "Name" => "Име", "Size" => "Величина", "Modified" => "Измењено", @@ -55,10 +51,8 @@ $TRANSLATIONS = array( "From link" => "Са везе", "Deleted files" => "Обрисане датотеке", "Cancel upload" => "Прекини отпремање", -"You don’t have write permissions here." => "Овде немате дозволу за писање.", "Nothing in here. Upload something!" => "Овде нема ничег. Отпремите нешто!", "Download" => "Преузми", -"Unshare" => "Укини дељење", "Delete" => "Обриши", "Upload too large" => "Датотека је превелика", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Датотеке које желите да отпремите прелазе ограничење у величини.", diff --git a/apps/files/l10n/sr@latin.php b/apps/files/l10n/sr@latin.php index 8831d1a1bef..13ce5ec8b3e 100644 --- a/apps/files/l10n/sr@latin.php +++ b/apps/files/l10n/sr@latin.php @@ -6,11 +6,11 @@ $TRANSLATIONS = array( "No file was uploaded" => "Nijedan fajl nije poslat", "Missing a temporary folder" => "Nedostaje privremena fascikla", "Files" => "Fajlovi", -"Error" => "Greška", "Share" => "Podeli", "_%n folder_::_%n folders_" => array("","",""), "_%n file_::_%n files_" => array("","",""), "_Uploading %n file_::_Uploading %n files_" => array("","",""), +"Error" => "Greška", "Name" => "Ime", "Size" => "Veličina", "Modified" => "Zadnja izmena", @@ -19,7 +19,6 @@ $TRANSLATIONS = array( "Save" => "Snimi", "Nothing in here. Upload something!" => "Ovde nema ničeg. Pošaljite nešto!", "Download" => "Preuzmi", -"Unshare" => "Ukljoni deljenje", "Delete" => "Obriši", "Upload too large" => "Pošiljka je prevelika", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Fajlovi koje želite da pošaljete prevazilaze ograničenje maksimalne veličine pošiljke na ovom serveru." diff --git a/apps/files/l10n/sv.php b/apps/files/l10n/sv.php index 208dcd4ea12..9e1b8110d48 100644 --- a/apps/files/l10n/sv.php +++ b/apps/files/l10n/sv.php @@ -2,6 +2,15 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "Kunde inte flytta %s - Det finns redan en fil med detta namn", "Could not move %s" => "Kan inte flytta %s", +"File name cannot be empty." => "Filnamn kan inte vara tomt.", +"File name must not contain \"/\". Please choose a different name." => "Filnamnet får ej innehålla \"/\". Välj ett annat namn.", +"The name %s is already used in the folder %s. Please choose a different name." => "Namnet %s används redan i katalogen %s. Välj ett annat namn.", +"Not a valid source" => "Inte en giltig källa", +"Error while downloading %s to %s" => "Fel under nerladdning från %s till %s", +"Error when creating the file" => "Fel under skapande utav filen", +"Folder name cannot be empty." => "Katalognamn kan ej vara tomt.", +"Folder name must not contain \"/\". Please choose a different name." => "Katalog namnet får ej innehålla \"/\". Välj ett annat namn.", +"Error when creating the folder" => "Fel under skapande utav en katalog", "Unable to set upload directory." => "Kan inte sätta mapp för uppladdning.", "Invalid Token" => "Ogiltig token", "No file was uploaded. Unknown error" => "Ingen fil uppladdad. Okänt fel", @@ -13,38 +22,46 @@ $TRANSLATIONS = array( "Missing a temporary folder" => "En temporär mapp saknas", "Failed to write to disk" => "Misslyckades spara till disk", "Not enough storage available" => "Inte tillräckligt med lagringsutrymme tillgängligt", +"Upload failed. Could not get file info." => "Uppladdning misslyckades. Gick inte att hämta filinformation.", +"Upload failed. Could not find uploaded file" => "Uppladdning misslyckades. Kunde inte hitta den uppladdade filen", "Invalid directory." => "Felaktig mapp.", "Files" => "Filer", +"Unable to upload {filename} as it is a directory or has 0 bytes" => "Kan inte ladda upp {filename} eftersom den antingen är en mapp eller har 0 bytes.", "Not enough space available" => "Inte tillräckligt med utrymme tillgängligt", "Upload cancelled." => "Uppladdning avbruten.", +"Could not get result from server." => "Gick inte att hämta resultat från server.", "File upload is in progress. Leaving the page now will cancel the upload." => "Filuppladdning pågår. Lämnar du sidan så avbryts uppladdningen.", -"URL cannot be empty." => "URL kan inte vara tom.", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Ogiltigt mappnamn. Användning av 'Shared' är reserverad av ownCloud", -"Error" => "Fel", +"URL cannot be empty" => "URL kan ej vara tomt", +"In the home folder 'Shared' is a reserved filename" => "I hemma katalogen 'Delat' är ett reserverat filnamn", +"{new_name} already exists" => "{new_name} finns redan", +"Could not create file" => "Kunde ej skapa fil", +"Could not create folder" => "Kunde ej skapa katalog", "Share" => "Dela", "Delete permanently" => "Radera permanent", "Rename" => "Byt namn", "Pending" => "Väntar", -"{new_name} already exists" => "{new_name} finns redan", -"replace" => "ersätt", -"suggest name" => "föreslå namn", -"cancel" => "avbryt", +"Could not rename file" => "Kan ej byta filnamn", "replaced {new_name} with {old_name}" => "ersatt {new_name} med {old_name}", "undo" => "ångra", +"Error deleting file." => "Kunde inte ta bort filen.", "_%n folder_::_%n folders_" => array("%n mapp","%n mappar"), "_%n file_::_%n files_" => array("%n fil","%n filer"), "{dirs} and {files}" => "{dirs} och {files}", "_Uploading %n file_::_Uploading %n files_" => array("Laddar upp %n fil","Laddar upp %n filer"), "'.' is an invalid file name." => "'.' är ett ogiltigt filnamn.", -"File name cannot be empty." => "Filnamn kan inte vara tomt.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Ogiltigt namn, '\\', '/', '<', '>', ':', '\"', '|', '?' och '*' är inte tillåtet.", "Your storage is full, files can not be updated or synced anymore!" => "Ditt lagringsutrymme är fullt, filer kan inte längre uppdateras eller synkroniseras!", "Your storage is almost full ({usedSpacePercent}%)" => "Ditt lagringsutrymme är nästan fullt ({usedSpacePercent}%)", +"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "Krypteringsprogrammet är aktiverat men dina nycklar är inte initierade. Vänligen logga ut och in igen", +"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "Ogiltig privat nyckel i krypteringsprogrammet. Vänligen uppdatera lösenordet till din privata nyckel under dina personliga inställningar för att återfå tillgång till dina krypterade filer.", "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Kryptering inaktiverades men dina filer är fortfarande krypterade. Vänligen gå till sidan för dina personliga inställningar för att dekryptera dina filer.", "Your download is being prepared. This might take some time if the files are big." => "Din nedladdning förbereds. Det kan ta tid om det är stora filer.", +"Error moving file" => "Fel uppstod vid flyttning av fil", +"Error" => "Fel", "Name" => "Namn", "Size" => "Storlek", "Modified" => "Ändrad", +"Invalid folder name. Usage of 'Shared' is reserved." => "Ogiltigt mappnamn. Användande av 'Shared' är reserverat av ownCloud", "%s could not be renamed" => "%s kunde inte namnändras", "Upload" => "Ladda upp", "File handling" => "Filhantering", @@ -57,14 +74,14 @@ $TRANSLATIONS = array( "Save" => "Spara", "New" => "Ny", "Text file" => "Textfil", +"New folder" => "Ny mapp", "Folder" => "Mapp", "From link" => "Från länk", "Deleted files" => "Raderade filer", "Cancel upload" => "Avbryt uppladdning", -"You don’t have write permissions here." => "Du saknar skrivbehörighet här.", +"You don’t have permission to upload or create files here" => "Du har ej tillåtelse att ladda upp eller skapa filer här", "Nothing in here. Upload something!" => "Ingenting här. Ladda upp något!", "Download" => "Ladda ner", -"Unshare" => "Sluta dela", "Delete" => "Radera", "Upload too large" => "För stor uppladdning", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Filerna du försöker ladda upp överstiger den maximala storleken för filöverföringar på servern.", diff --git a/apps/files/l10n/ta_LK.php b/apps/files/l10n/ta_LK.php index f05990b94f0..f91a74ee9bd 100644 --- a/apps/files/l10n/ta_LK.php +++ b/apps/files/l10n/ta_LK.php @@ -10,21 +10,17 @@ $TRANSLATIONS = array( "Files" => "கோப்புகள்", "Upload cancelled." => "பதிவேற்றல் இரத்து செய்யப்பட்டுள்ளது", "File upload is in progress. Leaving the page now will cancel the upload." => "கோப்பு பதிவேற்றம் செயல்பாட்டில் உள்ளது. இந்தப் பக்கத்திலிருந்து வெறியேறுவதானது பதிவேற்றலை இரத்து செய்யும்.", -"URL cannot be empty." => "URL வெறுமையாக இருக்கமுடியாது.", -"Error" => "வழு", +"{new_name} already exists" => "{new_name} ஏற்கனவே உள்ளது", "Share" => "பகிர்வு", "Rename" => "பெயர்மாற்றம்", "Pending" => "நிலுவையிலுள்ள", -"{new_name} already exists" => "{new_name} ஏற்கனவே உள்ளது", -"replace" => "மாற்றிடுக", -"suggest name" => "பெயரை பரிந்துரைக்க", -"cancel" => "இரத்து செய்க", "replaced {new_name} with {old_name}" => "{new_name} ஆனது {old_name} இனால் மாற்றப்பட்டது", "undo" => "முன் செயல் நீக்கம் ", "_%n folder_::_%n folders_" => array("",""), "_%n file_::_%n files_" => array("",""), "_Uploading %n file_::_Uploading %n files_" => array("",""), "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "செல்லுபடியற்ற பெயர்,'\\', '/', '<', '>', ':', '\"', '|', '?' மற்றும் '*' ஆகியன அனுமதிக்கப்படமாட்டாது.", +"Error" => "வழு", "Name" => "பெயர்", "Size" => "அளவு", "Modified" => "மாற்றப்பட்டது", @@ -44,7 +40,6 @@ $TRANSLATIONS = array( "Cancel upload" => "பதிவேற்றலை இரத்து செய்க", "Nothing in here. Upload something!" => "இங்கு ஒன்றும் இல்லை. ஏதாவது பதிவேற்றுக!", "Download" => "பதிவிறக்குக", -"Unshare" => "பகிரப்படாதது", "Delete" => "நீக்குக", "Upload too large" => "பதிவேற்றல் மிகப்பெரியது", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "நீங்கள் பதிவேற்ற முயற்சிக்கும் கோப்புகளானது இந்த சேவையகத்தில் கோப்பு பதிவேற்றக்கூடிய ஆகக்கூடிய அளவிலும் கூடியது.", diff --git a/apps/files/l10n/te.php b/apps/files/l10n/te.php index 60aabc8a365..155e4b5c201 100644 --- a/apps/files/l10n/te.php +++ b/apps/files/l10n/te.php @@ -1,14 +1,14 @@ <?php $TRANSLATIONS = array( -"Error" => "పొరపాటు", "Delete permanently" => "శాశ్వతంగా తొలగించు", -"cancel" => "రద్దుచేయి", "_%n folder_::_%n folders_" => array("",""), "_%n file_::_%n files_" => array("",""), "_Uploading %n file_::_Uploading %n files_" => array("",""), +"Error" => "పొరపాటు", "Name" => "పేరు", "Size" => "పరిమాణం", "Save" => "భద్రపరచు", +"New folder" => "కొత్త సంచయం", "Folder" => "సంచయం", "Delete" => "తొలగించు" ); diff --git a/apps/files/l10n/th_TH.php b/apps/files/l10n/th_TH.php index 37144ebc883..38a67c50679 100644 --- a/apps/files/l10n/th_TH.php +++ b/apps/files/l10n/th_TH.php @@ -2,6 +2,7 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "ไม่สามารถย้าย %s ได้ - ไฟล์ที่ใช้ชื่อนี้มีอยู่แล้ว", "Could not move %s" => "ไม่สามารถย้าย %s ได้", +"File name cannot be empty." => "ชื่อไฟล์ไม่สามารถเว้นว่างได้", "No file was uploaded. Unknown error" => "ยังไม่มีไฟล์ใดที่ถูกอัพโหลด เกิดข้อผิดพลาดที่ไม่ทราบสาเหตุ", "There is no error, the file uploaded with success" => "ไม่พบข้อผิดพลาดใดๆ, ไฟล์ถูกอัพโหลดเรียบร้อยแล้ว", "The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "ขนาดไฟล์ที่อัพโหลดมีขนาดเกิน upload_max_filesize ที่ระบุไว้ใน php.ini", @@ -16,26 +17,21 @@ $TRANSLATIONS = array( "Not enough space available" => "มีพื้นที่เหลือไม่เพียงพอ", "Upload cancelled." => "การอัพโหลดถูกยกเลิก", "File upload is in progress. Leaving the page now will cancel the upload." => "การอัพโหลดไฟล์กำลังอยู่ในระหว่างดำเนินการ การออกจากหน้าเว็บนี้จะทำให้การอัพโหลดถูกยกเลิก", -"URL cannot be empty." => "URL ไม่สามารถเว้นว่างได้", -"Error" => "ข้อผิดพลาด", +"{new_name} already exists" => "{new_name} มีอยู่แล้วในระบบ", "Share" => "แชร์", "Rename" => "เปลี่ยนชื่อ", "Pending" => "อยู่ระหว่างดำเนินการ", -"{new_name} already exists" => "{new_name} มีอยู่แล้วในระบบ", -"replace" => "แทนที่", -"suggest name" => "แนะนำชื่อ", -"cancel" => "ยกเลิก", "replaced {new_name} with {old_name}" => "แทนที่ {new_name} ด้วย {old_name} แล้ว", "undo" => "เลิกทำ", "_%n folder_::_%n folders_" => array(""), "_%n file_::_%n files_" => array(""), "_Uploading %n file_::_Uploading %n files_" => array(""), "'.' is an invalid file name." => "'.' เป็นชื่อไฟล์ที่ไม่ถูกต้อง", -"File name cannot be empty." => "ชื่อไฟล์ไม่สามารถเว้นว่างได้", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "ชื่อที่ใช้ไม่ถูกต้อง, '\\', '/', '<', '>', ':', '\"', '|', '?' และ '*' ไม่ได้รับอนุญาตให้ใช้งานได้", "Your storage is full, files can not be updated or synced anymore!" => "พื้นที่จัดเก็บข้อมูลของคุณเต็มแล้ว ไม่สามารถอัพเดทหรือผสานไฟล์ต่างๆได้อีกต่อไป", "Your storage is almost full ({usedSpacePercent}%)" => "พื้นที่จัดเก็บข้อมูลของคุณใกล้เต็มแล้ว ({usedSpacePercent}%)", "Your download is being prepared. This might take some time if the files are big." => "กำลังเตรียมดาวน์โหลดข้อมูล หากไฟล์มีขนาดใหญ่ อาจใช้เวลาสักครู่", +"Error" => "ข้อผิดพลาด", "Name" => "ชื่อ", "Size" => "ขนาด", "Modified" => "แก้ไขแล้ว", @@ -55,7 +51,6 @@ $TRANSLATIONS = array( "Cancel upload" => "ยกเลิกการอัพโหลด", "Nothing in here. Upload something!" => "ยังไม่มีไฟล์ใดๆอยู่ที่นี่ กรุณาอัพโหลดไฟล์!", "Download" => "ดาวน์โหลด", -"Unshare" => "ยกเลิกการแชร์", "Delete" => "ลบ", "Upload too large" => "ไฟล์ที่อัพโหลดมีขนาดใหญ่เกินไป", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "ไฟล์ที่คุณพยายามที่จะอัพโหลดมีขนาดเกินกว่าขนาดสูงสุดที่กำหนดไว้ให้อัพโหลดได้สำหรับเซิร์ฟเวอร์นี้", diff --git a/apps/files/l10n/tr.php b/apps/files/l10n/tr.php index 8cb05e16ace..90b16922a76 100644 --- a/apps/files/l10n/tr.php +++ b/apps/files/l10n/tr.php @@ -1,9 +1,19 @@ <?php $TRANSLATIONS = array( -"Could not move %s - File with this name already exists" => "%s taşınamadı. Bu isimde dosya zaten var.", +"Could not move %s - File with this name already exists" => "%s taşınamadı - Bu isimde dosya zaten var", "Could not move %s" => "%s taşınamadı", +"File name cannot be empty." => "Dosya adı boş olamaz.", +"File name must not contain \"/\". Please choose a different name." => "Dosya adı \"/\" içermemelidir. Lütfen farklı bir isim seçin.", +"The name %s is already used in the folder %s. Please choose a different name." => "%s ismi zaten %s klasöründe kullanılıyor. Lütfen farklı bir isim seçin.", +"Not a valid source" => "Geçerli bir kaynak değil", +"Server is not allowed to open URLs, please check the server configuration" => "Sunucunun adresleri açma izi yok, lütfen sunucu yapılandırmasını denetleyin", +"Error while downloading %s to %s" => "%s, %s içine indirilirken hata", +"Error when creating the file" => "Dosya oluşturulurken hata", +"Folder name cannot be empty." => "Klasör adı boş olamaz.", +"Folder name must not contain \"/\". Please choose a different name." => "Klasör adı \"/\" içermemelidir. Lütfen farklı bir isim seçin.", +"Error when creating the folder" => "Klasör oluşturulurken hata", "Unable to set upload directory." => "Yükleme dizini tanımlanamadı.", -"Invalid Token" => "Geçeriz simge", +"Invalid Token" => "Geçersiz Simge", "No file was uploaded. Unknown error" => "Dosya yüklenmedi. Bilinmeyen hata", "There is no error, the file uploaded with success" => "Dosya başarıyla yüklendi, hata oluşmadı", "The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "php.ini dosyasında upload_max_filesize ile belirtilen dosya yükleme sınırı aşıldı.", @@ -13,57 +23,68 @@ $TRANSLATIONS = array( "Missing a temporary folder" => "Geçici dizin eksik", "Failed to write to disk" => "Diske yazılamadı", "Not enough storage available" => "Yeterli disk alanı yok", +"Upload failed. Could not get file info." => "Yükleme başarısız. Dosya bilgisi alınamadı.", +"Upload failed. Could not find uploaded file" => "Yükleme başarısız. Yüklenen dosya bulunamadı", "Invalid directory." => "Geçersiz dizin.", "Files" => "Dosyalar", +"Unable to upload {filename} as it is a directory or has 0 bytes" => "Bir dizin veya 0 bayt olduğundan {filename} yüklenemedi", "Not enough space available" => "Yeterli disk alanı yok", "Upload cancelled." => "Yükleme iptal edildi.", +"Could not get result from server." => "Sunucudan sonuç alınamadı.", "File upload is in progress. Leaving the page now will cancel the upload." => "Dosya yükleme işlemi sürüyor. Şimdi sayfadan ayrılırsanız işleminiz iptal olur.", -"URL cannot be empty." => "URL boş olamaz.", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Geçersiz dizin adı. 'Shared' dizin ismi kullanımı ownCloud tarafından rezerve edilmiştir.", -"Error" => "Hata", +"URL cannot be empty" => "URL boş olamaz", +"In the home folder 'Shared' is a reserved filename" => "Ev klasöründeki 'Paylaşılan', ayrılmış bir dosya adıdır", +"{new_name} already exists" => "{new_name} zaten mevcut", +"Could not create file" => "Dosya oluşturulamadı", +"Could not create folder" => "Klasör oluşturulamadı", +"Error fetching URL" => "Adres getirilirken hata", "Share" => "Paylaş", "Delete permanently" => "Kalıcı olarak sil", "Rename" => "İsim değiştir.", "Pending" => "Bekliyor", -"{new_name} already exists" => "{new_name} zaten mevcut", -"replace" => "değiştir", -"suggest name" => "Öneri ad", -"cancel" => "iptal", +"Could not rename file" => "Dosya adlandırılamadı", "replaced {new_name} with {old_name}" => "{new_name} ismi {old_name} ile değiştirildi", "undo" => "geri al", +"Error deleting file." => "Dosya silinirken hata.", "_%n folder_::_%n folders_" => array("%n dizin","%n dizin"), "_%n file_::_%n files_" => array("%n dosya","%n dosya"), +"{dirs} and {files}" => "{dirs} ve {files}", "_Uploading %n file_::_Uploading %n files_" => array("%n dosya yükleniyor","%n dosya yükleniyor"), -"'.' is an invalid file name." => "'.' geçersiz dosya adı.", -"File name cannot be empty." => "Dosya adı boş olamaz.", +"'.' is an invalid file name." => "'.' geçersiz bir dosya adı.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Geçersiz isim, '\\', '/', '<', '>', ':', '\"', '|', '?' ve '*' karakterlerine izin verilmemektedir.", -"Your storage is full, files can not be updated or synced anymore!" => "Depolama alanınız dolu, artık dosyalar güncellenmeyecek yada senkronizasyon edilmeyecek.", +"Your storage is full, files can not be updated or synced anymore!" => "Depolama alanınız dolu, artık dosyalar güncellenmeyecek veya eşitlenmeyecek.", "Your storage is almost full ({usedSpacePercent}%)" => "Depolama alanınız neredeyse dolu ({usedSpacePercent}%)", -"Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Şifreleme işlemi durduruldu ancak dosyalarınız şifreli. Dosyalarınızın şifresini kaldırmak için lütfen kişisel ayarlar kısmına geçiniz.", +"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "Şifreleme Uygulaması etkin ancak anahtarlarınız başlatılmamış. Lütfen oturumu kapatıp yeniden açın", +"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "Şifreleme Uygulaması için geçersiz özel anahtar. Lütfen şifreli dosyalarınıza erişimi tekrar kazanabilmek için kişisel ayarlarınızdan özel anahtar parolanızı güncelleyin.", +"Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Şifreleme işlemi durduruldu ancak dosyalarınız şifreli. Dosyalarınızın şifresini kaldırmak için lütfen kişisel ayarlar kısmına geçin.", "Your download is being prepared. This might take some time if the files are big." => "İndirmeniz hazırlanıyor. Dosya büyük ise biraz zaman alabilir.", +"Error moving file" => "Dosya taşıma hatası", +"Error" => "Hata", "Name" => "İsim", "Size" => "Boyut", "Modified" => "Değiştirilme", +"Invalid folder name. Usage of 'Shared' is reserved." => "Geçersiz dizin adı. 'Shared' ismi ayrılmıştır.", "%s could not be renamed" => "%s yeniden adlandırılamadı", "Upload" => "Yükle", -"File handling" => "Dosya taşıma", +"File handling" => "Dosya işlemleri", "Maximum upload size" => "Maksimum yükleme boyutu", "max. possible: " => "mümkün olan en fazla: ", "Needed for multi-file and folder downloads." => "Çoklu dosya ve dizin indirmesi için gerekli.", -"Enable ZIP-download" => "ZIP indirmeyi aktif et", +"Enable ZIP-download" => "ZIP indirmeyi etkinleştir", "0 is unlimited" => "0 limitsiz demektir", -"Maximum input size for ZIP files" => "ZIP dosyaları için en fazla girdi sayısı", +"Maximum input size for ZIP files" => "ZIP dosyaları için en fazla girdi boyutu", "Save" => "Kaydet", "New" => "Yeni", +"New text file" => "Yeni metin dosyası", "Text file" => "Metin dosyası", +"New folder" => "Yeni klasör", "Folder" => "Klasör", "From link" => "Bağlantıdan", -"Deleted files" => "Dosyalar silindi", +"Deleted files" => "Silinmiş dosyalar", "Cancel upload" => "Yüklemeyi iptal et", -"You don’t have write permissions here." => "Buraya erişim hakkınız yok.", -"Nothing in here. Upload something!" => "Burada hiçbir şey yok. Birşeyler yükleyin!", +"You don’t have permission to upload or create files here" => "Buraya dosya yükleme veya oluşturma izniniz yok", +"Nothing in here. Upload something!" => "Burada hiçbir şey yok. Bir şeyler yükleyin!", "Download" => "İndir", -"Unshare" => "Paylaşılmayan", "Delete" => "Sil", "Upload too large" => "Yükleme çok büyük", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Yüklemeye çalıştığınız dosyalar bu sunucudaki maksimum yükleme boyutunu aşıyor.", diff --git a/apps/files/l10n/tzm.php b/apps/files/l10n/tzm.php new file mode 100644 index 00000000000..c50e35da623 --- /dev/null +++ b/apps/files/l10n/tzm.php @@ -0,0 +1,7 @@ +<?php +$TRANSLATIONS = array( +"_%n folder_::_%n folders_" => array("",""), +"_%n file_::_%n files_" => array("",""), +"_Uploading %n file_::_Uploading %n files_" => array("","") +); +$PLURAL_FORMS = "nplurals=2; plural=(n == 0 || n == 1 || (n > 10 && n < 100) ? 0 : 1;"; diff --git a/apps/files/l10n/ug.php b/apps/files/l10n/ug.php index a38ce706ef9..45458c51af0 100644 --- a/apps/files/l10n/ug.php +++ b/apps/files/l10n/ug.php @@ -10,19 +10,16 @@ $TRANSLATIONS = array( "Not enough space available" => "يېتەرلىك بوشلۇق يوق", "Upload cancelled." => "يۈكلەشتىن ۋاز كەچتى.", "File upload is in progress. Leaving the page now will cancel the upload." => "ھۆججەت يۈكلەش مەشغۇلاتى ئېلىپ بېرىلىۋاتىدۇ. Leaving the page now will cancel the upload.", -"Error" => "خاتالىق", +"{new_name} already exists" => "{new_name} مەۋجۇت", "Share" => "ھەمبەھىر", "Delete permanently" => "مەڭگۈلۈك ئۆچۈر", "Rename" => "ئات ئۆزگەرت", "Pending" => "كۈتۈۋاتىدۇ", -"{new_name} already exists" => "{new_name} مەۋجۇت", -"replace" => "ئالماشتۇر", -"suggest name" => "تەۋسىيە ئات", -"cancel" => "ۋاز كەچ", "undo" => "يېنىۋال", "_%n folder_::_%n folders_" => array(""), "_%n file_::_%n files_" => array(""), "_Uploading %n file_::_Uploading %n files_" => array(""), +"Error" => "خاتالىق", "Name" => "ئاتى", "Size" => "چوڭلۇقى", "Modified" => "ئۆزگەرتكەن", @@ -30,12 +27,12 @@ $TRANSLATIONS = array( "Save" => "ساقلا", "New" => "يېڭى", "Text file" => "تېكىست ھۆججەت", +"New folder" => "يېڭى قىسقۇچ", "Folder" => "قىسقۇچ", "Deleted files" => "ئۆچۈرۈلگەن ھۆججەتلەر", "Cancel upload" => "يۈكلەشتىن ۋاز كەچ", "Nothing in here. Upload something!" => "بۇ جايدا ھېچنېمە يوق. Upload something!", "Download" => "چۈشۈر", -"Unshare" => "ھەمبەھىرلىمە", "Delete" => "ئۆچۈر", "Upload too large" => "يۈكلەندىغىنى بەك چوڭ", "Upgrading filesystem cache..." => "ھۆججەت سىستېما غەملىكىنى يۈكسەلدۈرۈۋاتىدۇ…" diff --git a/apps/files/l10n/uk.php b/apps/files/l10n/uk.php index 4aaeca25542..1e37d3d77d4 100644 --- a/apps/files/l10n/uk.php +++ b/apps/files/l10n/uk.php @@ -2,6 +2,8 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "Не вдалося перемістити %s - Файл з таким ім'ям вже існує", "Could not move %s" => "Не вдалося перемістити %s", +"File name cannot be empty." => " Ім'я файлу не може бути порожнім.", +"Folder name cannot be empty." => "Ім'я теки не може бути порожнім.", "Unable to set upload directory." => "Не вдалося встановити каталог завантаження.", "No file was uploaded. Unknown error" => "Не завантажено жодного файлу. Невідома помилка", "There is no error, the file uploaded with success" => "Файл успішно вивантажено без помилок.", @@ -17,28 +19,27 @@ $TRANSLATIONS = array( "Not enough space available" => "Місця більше немає", "Upload cancelled." => "Завантаження перервано.", "File upload is in progress. Leaving the page now will cancel the upload." => "Виконується завантаження файлу. Закриття цієї сторінки приведе до відміни завантаження.", -"URL cannot be empty." => "URL не може бути пустим.", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "Неправильне ім'я теки. Використання 'Shared' зарезервовано ownCloud", -"Error" => "Помилка", +"URL cannot be empty" => "URL не може бути порожнім", +"{new_name} already exists" => "{new_name} вже існує", +"Could not create file" => "Не вдалося створити файл", +"Could not create folder" => "Не вдалося створити теку", "Share" => "Поділитися", "Delete permanently" => "Видалити назавжди", "Rename" => "Перейменувати", "Pending" => "Очікування", -"{new_name} already exists" => "{new_name} вже існує", -"replace" => "заміна", -"suggest name" => "запропонуйте назву", -"cancel" => "відміна", +"Could not rename file" => "Неможливо перейменувати файл", "replaced {new_name} with {old_name}" => "замінено {new_name} на {old_name}", "undo" => "відмінити", "_%n folder_::_%n folders_" => array("%n тека","%n тека","%n теки"), -"_%n file_::_%n files_" => array("","",""), +"_%n file_::_%n files_" => array("%n файл","%n файлів","%n файли"), "_Uploading %n file_::_Uploading %n files_" => array("","",""), "'.' is an invalid file name." => "'.' це невірне ім'я файлу.", -"File name cannot be empty." => " Ім'я файлу не може бути порожнім.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Невірне ім'я, '\\', '/', '<', '>', ':', '\"', '|', '?' та '*' не дозволені.", "Your storage is full, files can not be updated or synced anymore!" => "Ваше сховище переповнене, файли більше не можуть бути оновлені або синхронізовані !", "Your storage is almost full ({usedSpacePercent}%)" => "Ваше сховище майже повне ({usedSpacePercent}%)", "Your download is being prepared. This might take some time if the files are big." => "Ваше завантаження готується. Це може зайняти деякий час, якщо файли завеликі.", +"Error moving file" => "Помилка переміщення файлу", +"Error" => "Помилка", "Name" => "Ім'я", "Size" => "Розмір", "Modified" => "Змінено", @@ -54,14 +55,13 @@ $TRANSLATIONS = array( "Save" => "Зберегти", "New" => "Створити", "Text file" => "Текстовий файл", +"New folder" => "Нова тека", "Folder" => "Тека", "From link" => "З посилання", "Deleted files" => "Видалено файлів", "Cancel upload" => "Перервати завантаження", -"You don’t have write permissions here." => "У вас тут немає прав на запис.", "Nothing in here. Upload something!" => "Тут нічого немає. Відвантажте що-небудь!", "Download" => "Завантажити", -"Unshare" => "Закрити доступ", "Delete" => "Видалити", "Upload too large" => "Файл занадто великий", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Файли,що ви намагаєтесь відвантажити перевищують максимальний дозволений розмір файлів на цьому сервері.", diff --git a/apps/files/l10n/ur.php b/apps/files/l10n/ur.php new file mode 100644 index 00000000000..0157af093e9 --- /dev/null +++ b/apps/files/l10n/ur.php @@ -0,0 +1,7 @@ +<?php +$TRANSLATIONS = array( +"_%n folder_::_%n folders_" => array("",""), +"_%n file_::_%n files_" => array("",""), +"_Uploading %n file_::_Uploading %n files_" => array("","") +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files/l10n/ur_PK.php b/apps/files/l10n/ur_PK.php index 6854c421587..3e13a7f516d 100644 --- a/apps/files/l10n/ur_PK.php +++ b/apps/files/l10n/ur_PK.php @@ -1,9 +1,8 @@ <?php $TRANSLATIONS = array( -"Error" => "ایرر", "_%n folder_::_%n folders_" => array("",""), "_%n file_::_%n files_" => array("",""), "_Uploading %n file_::_Uploading %n files_" => array("",""), -"Unshare" => "شئیرنگ ختم کریں" +"Error" => "ایرر" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files/l10n/uz.php b/apps/files/l10n/uz.php new file mode 100644 index 00000000000..70ab6572ba4 --- /dev/null +++ b/apps/files/l10n/uz.php @@ -0,0 +1,7 @@ +<?php +$TRANSLATIONS = array( +"_%n folder_::_%n folders_" => array(""), +"_%n file_::_%n files_" => array(""), +"_Uploading %n file_::_Uploading %n files_" => array("") +); +$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/files/l10n/vi.php b/apps/files/l10n/vi.php index 2d63128aa26..8236d5e7efe 100644 --- a/apps/files/l10n/vi.php +++ b/apps/files/l10n/vi.php @@ -2,6 +2,7 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "Không thể di chuyển %s - Đã có tên tập tin này trên hệ thống", "Could not move %s" => "Không thể di chuyển %s", +"File name cannot be empty." => "Tên file không được rỗng", "No file was uploaded. Unknown error" => "Không có tập tin nào được tải lên. Lỗi không xác định", "There is no error, the file uploaded with success" => "Không có lỗi, các tập tin đã được tải lên thành công", "The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "The uploaded file exceeds the upload_max_filesize directive in php.ini: ", @@ -16,27 +17,22 @@ $TRANSLATIONS = array( "Not enough space available" => "Không đủ chỗ trống cần thiết", "Upload cancelled." => "Hủy tải lên", "File upload is in progress. Leaving the page now will cancel the upload." => "Tập tin tải lên đang được xử lý. Nếu bạn rời khỏi trang bây giờ sẽ hủy quá trình này.", -"URL cannot be empty." => "URL không được để trống.", -"Error" => "Lỗi", +"{new_name} already exists" => "{new_name} đã tồn tại", "Share" => "Chia sẻ", "Delete permanently" => "Xóa vĩnh vễn", "Rename" => "Sửa tên", "Pending" => "Đang chờ", -"{new_name} already exists" => "{new_name} đã tồn tại", -"replace" => "thay thế", -"suggest name" => "tên gợi ý", -"cancel" => "hủy", "replaced {new_name} with {old_name}" => "đã thay thế {new_name} bằng {old_name}", "undo" => "lùi lại", "_%n folder_::_%n folders_" => array(""), "_%n file_::_%n files_" => array(""), "_Uploading %n file_::_Uploading %n files_" => array(""), "'.' is an invalid file name." => "'.' là một tên file không hợp lệ", -"File name cannot be empty." => "Tên file không được rỗng", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Tên không hợp lệ, '\\', '/', '<', '>', ':', '\"', '|', '?' và '*' thì không được phép dùng.", "Your storage is full, files can not be updated or synced anymore!" => "Your storage is full, files can not be updated or synced anymore!", "Your storage is almost full ({usedSpacePercent}%)" => "Your storage is almost full ({usedSpacePercent}%)", "Your download is being prepared. This might take some time if the files are big." => "Your download is being prepared. This might take some time if the files are big.", +"Error" => "Lỗi", "Name" => "Tên", "Size" => "Kích cỡ", "Modified" => "Thay đổi", @@ -51,14 +47,13 @@ $TRANSLATIONS = array( "Save" => "Lưu", "New" => "Mới", "Text file" => "Tập tin văn bản", +"New folder" => "Tạo thư mục", "Folder" => "Thư mục", "From link" => "Từ liên kết", "Deleted files" => "File đã bị xóa", "Cancel upload" => "Hủy upload", -"You don’t have write permissions here." => "Bạn không có quyền ghi vào đây.", "Nothing in here. Upload something!" => "Không có gì ở đây .Hãy tải lên một cái gì đó !", "Download" => "Tải về", -"Unshare" => "Bỏ chia sẻ", "Delete" => "Xóa", "Upload too large" => "Tập tin tải lên quá lớn", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "Các tập tin bạn đang tải lên vượt quá kích thước tối đa cho phép trên máy chủ .", diff --git a/apps/files/l10n/zh_CN.php b/apps/files/l10n/zh_CN.php index b739b72ce7e..effcb0225ca 100644 --- a/apps/files/l10n/zh_CN.php +++ b/apps/files/l10n/zh_CN.php @@ -2,6 +2,7 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "无法移动 %s - 同名文件已存在", "Could not move %s" => "无法移动 %s", +"File name cannot be empty." => "文件名不能为空。", "Unable to set upload directory." => "无法设置上传文件夹。", "Invalid Token" => "无效密匙", "No file was uploaded. Unknown error" => "没有文件被上传。未知错误", @@ -18,28 +19,22 @@ $TRANSLATIONS = array( "Not enough space available" => "没有足够可用空间", "Upload cancelled." => "上传已取消", "File upload is in progress. Leaving the page now will cancel the upload." => "文件正在上传中。现在离开此页会导致上传动作被取消。", -"URL cannot be empty." => "URL不能为空", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "无效的文件夹名。”Shared“ 是 Owncloud 预留的文件夹", -"Error" => "错误", +"{new_name} already exists" => "{new_name} 已存在", "Share" => "分享", "Delete permanently" => "永久删除", "Rename" => "重命名", "Pending" => "等待", -"{new_name} already exists" => "{new_name} 已存在", -"replace" => "替换", -"suggest name" => "建议名称", -"cancel" => "取消", "replaced {new_name} with {old_name}" => "已将 {old_name}替换成 {new_name}", "undo" => "撤销", "_%n folder_::_%n folders_" => array("%n 文件夹"), "_%n file_::_%n files_" => array("%n个文件"), "_Uploading %n file_::_Uploading %n files_" => array(""), "'.' is an invalid file name." => "'.' 是一个无效的文件名。", -"File name cannot be empty." => "文件名不能为空。", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "无效名称,'\\', '/', '<', '>', ':', '\"', '|', '?' 和 '*' 不被允许使用。", "Your storage is full, files can not be updated or synced anymore!" => "您的存储空间已满,文件将无法更新或同步!", "Your storage is almost full ({usedSpacePercent}%)" => "您的存储空间即将用完 ({usedSpacePercent}%)", "Your download is being prepared. This might take some time if the files are big." => "下载正在准备中。如果文件较大可能会花费一些时间。", +"Error" => "错误", "Name" => "名称", "Size" => "大小", "Modified" => "修改日期", @@ -55,14 +50,13 @@ $TRANSLATIONS = array( "Save" => "保存", "New" => "新建", "Text file" => "文本文件", +"New folder" => "添加文件夹", "Folder" => "文件夹", "From link" => "来自链接", "Deleted files" => "已删除文件", "Cancel upload" => "取消上传", -"You don’t have write permissions here." => "您没有写权限", "Nothing in here. Upload something!" => "这里还什么都没有。上传些东西吧!", "Download" => "下载", -"Unshare" => "取消共享", "Delete" => "删除", "Upload too large" => "上传文件过大", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "您正尝试上传的文件超过了此服务器可以上传的最大容量限制", diff --git a/apps/files/l10n/zh_HK.php b/apps/files/l10n/zh_HK.php index febed4fe8fb..4885500ce43 100644 --- a/apps/files/l10n/zh_HK.php +++ b/apps/files/l10n/zh_HK.php @@ -1,16 +1,15 @@ <?php $TRANSLATIONS = array( "Files" => "文件", -"Error" => "錯誤", "Share" => "分享", "_%n folder_::_%n folders_" => array(""), "_%n file_::_%n files_" => array(""), "_Uploading %n file_::_Uploading %n files_" => array(""), +"Error" => "錯誤", "Name" => "名稱", "Upload" => "上傳", "Save" => "儲存", "Download" => "下載", -"Unshare" => "取消分享", "Delete" => "刪除" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/files/l10n/zh_TW.php b/apps/files/l10n/zh_TW.php index 214812d7ada..dd9cbfdf1a9 100644 --- a/apps/files/l10n/zh_TW.php +++ b/apps/files/l10n/zh_TW.php @@ -2,6 +2,15 @@ $TRANSLATIONS = array( "Could not move %s - File with this name already exists" => "無法移動 %s ,同名的檔案已經存在", "Could not move %s" => "無法移動 %s", +"File name cannot be empty." => "檔名不能為空", +"File name must not contain \"/\". Please choose a different name." => "檔名不能包含 \"/\" ,請選其他名字", +"The name %s is already used in the folder %s. Please choose a different name." => "%s 已經被使用於資料夾 %s ,請換一個名字", +"Not a valid source" => "不是有效的來源", +"Error while downloading %s to %s" => "下載 %s 到 %s 失敗", +"Error when creating the file" => "建立檔案失敗", +"Folder name cannot be empty." => "資料夾名稱不能留空", +"Folder name must not contain \"/\". Please choose a different name." => "資料夾名稱不能包含 \"/\" ,請選其他名字", +"Error when creating the folder" => "建立資料夾失敗", "Unable to set upload directory." => "無法設定上傳目錄", "Invalid Token" => "無效的 token", "No file was uploaded. Unknown error" => "沒有檔案被上傳,原因未知", @@ -13,22 +22,25 @@ $TRANSLATIONS = array( "Missing a temporary folder" => "找不到暫存資料夾", "Failed to write to disk" => "寫入硬碟失敗", "Not enough storage available" => "儲存空間不足", +"Upload failed. Could not get file info." => "上傳失敗,無法取得檔案資訊", +"Upload failed. Could not find uploaded file" => "上傳失敗,找不到上傳的檔案", "Invalid directory." => "無效的資料夾", "Files" => "檔案", +"Unable to upload {filename} as it is a directory or has 0 bytes" => "因為 {filename} 是個目錄或是大小為零,所以無法上傳", "Not enough space available" => "沒有足夠的可用空間", "Upload cancelled." => "上傳已取消", +"Could not get result from server." => "無法從伺服器取回結果", "File upload is in progress. Leaving the page now will cancel the upload." => "檔案上傳中,離開此頁面將會取消上傳。", -"URL cannot be empty." => "URL 不能為空", -"Invalid folder name. Usage of 'Shared' is reserved by ownCloud" => "無效的資料夾名稱,'Shared' 的使用被 ownCloud 保留", -"Error" => "錯誤", +"URL cannot be empty" => "URL 不能留空", +"In the home folder 'Shared' is a reserved filename" => "在家目錄中不能使用「共享」作為檔名", +"{new_name} already exists" => "{new_name} 已經存在", +"Could not create file" => "無法建立檔案", +"Could not create folder" => "無法建立資料夾", "Share" => "分享", "Delete permanently" => "永久刪除", "Rename" => "重新命名", "Pending" => "等候中", -"{new_name} already exists" => "{new_name} 已經存在", -"replace" => "取代", -"suggest name" => "建議檔名", -"cancel" => "取消", +"Could not rename file" => "無法重新命名", "replaced {new_name} with {old_name}" => "使用 {new_name} 取代 {old_name}", "undo" => "復原", "_%n folder_::_%n folders_" => array("%n 個資料夾"), @@ -36,12 +48,15 @@ $TRANSLATIONS = array( "{dirs} and {files}" => "{dirs} 和 {files}", "_Uploading %n file_::_Uploading %n files_" => array("%n 個檔案正在上傳"), "'.' is an invalid file name." => "'.' 是不合法的檔名", -"File name cannot be empty." => "檔名不能為空", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "檔名不合法,不允許 \\ / < > : \" | ? * 字元", "Your storage is full, files can not be updated or synced anymore!" => "您的儲存空間已滿,沒有辦法再更新或是同步檔案!", "Your storage is almost full ({usedSpacePercent}%)" => "您的儲存空間快要滿了 ({usedSpacePercent}%)", +"Encryption App is enabled but your keys are not initialized, please log-out and log-in again" => "檔案加密已啓用,但是您的金鑰尚未初始化,請重新登入一次", +"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "無效的檔案加密私鑰,請在個人設定中更新您的私鑰密語以存取加密的檔案。", "Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "加密已經被停用,但是您的舊檔案還是處於已加密的狀態,請前往個人設定以解密這些檔案。", "Your download is being prepared. This might take some time if the files are big." => "正在準備您的下載,若您的檔案較大,將會需要更多時間。", +"Error moving file" => "移動檔案失敗", +"Error" => "錯誤", "Name" => "名稱", "Size" => "大小", "Modified" => "修改時間", @@ -57,14 +72,14 @@ $TRANSLATIONS = array( "Save" => "儲存", "New" => "新增", "Text file" => "文字檔", +"New folder" => "新資料夾", "Folder" => "資料夾", "From link" => "從連結", "Deleted files" => "回收桶", "Cancel upload" => "取消上傳", -"You don’t have write permissions here." => "您在這裡沒有編輯權", +"You don’t have permission to upload or create files here" => "您沒有權限在這裡上傳或建立檔案", "Nothing in here. Upload something!" => "這裡還沒有東西,上傳一些吧!", "Download" => "下載", -"Unshare" => "取消分享", "Delete" => "刪除", "Upload too large" => "上傳過大", "The files you are trying to upload exceed the maximum size for file uploads on this server." => "您試圖上傳的檔案大小超過伺服器的限制。", diff --git a/apps/files/lib/app.php b/apps/files/lib/app.php index 579e8676cfc..e04ac173d55 100644 --- a/apps/files/lib/app.php +++ b/apps/files/lib/app.php @@ -25,7 +25,14 @@ namespace OCA\Files; class App { + /** + * @var \OC_L10N + */ private $l10n; + + /** + * @var \OC\Files\View + */ private $view; public function __construct($view, $l10n) { @@ -50,9 +57,17 @@ class App { // rename to "/Shared" is denied if( $dir === '/' and $newname === 'Shared' ) { $result['data'] = array( - 'message' => $this->l10n->t("Invalid folder name. Usage of 'Shared' is reserved by ownCloud") + 'message' => $this->l10n->t("Invalid folder name. Usage of 'Shared' is reserved.") ); - } elseif( + // rename to existing file is denied + } else if ($this->view->file_exists($dir . '/' . $newname)) { + + $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 // rename of "/Shared" is denied @@ -61,12 +76,25 @@ class App { $this->view->rename($dir . '/' . $oldname, $dir . '/' . $newname) ) { // successful rename - $result['success'] = true; - $result['data'] = array( - 'dir' => $dir, - 'file' => $oldname, - 'newname' => $newname + $meta = $this->view->getFileInfo($dir . '/' . $newname); + if ($meta['mimetype'] === 'httpd/unix-directory') { + $meta['type'] = 'dir'; + } + else { + $meta['type'] = 'file'; + } + $fileinfo = array( + 'id' => $meta['fileid'], + 'mime' => $meta['mimetype'], + 'size' => $meta['size'], + 'etag' => $meta['etag'], + 'directory' => $dir, + 'name' => $newname, + 'isPreviewAvailable' => \OC::$server->getPreviewManager()->isMimeSupported($meta['mimetype']), + 'icon' => \OCA\Files\Helper::determineIcon($meta) ); + $result['success'] = true; + $result['data'] = $fileinfo; } else { // rename failed $result['data'] = array( diff --git a/apps/files/lib/helper.php b/apps/files/lib/helper.php index 709d78a4d45..eaff28178ea 100644 --- a/apps/files/lib/helper.php +++ b/apps/files/lib/helper.php @@ -30,7 +30,7 @@ class Helper if ($sid[0] === 'shared') { return \OC_Helper::mimetypeIcon('dir-shared'); } - if ($sid[0] !== 'local') { + if ($sid[0] !== 'local' and $sid[0] !== 'home') { return \OC_Helper::mimetypeIcon('dir-external'); } } @@ -40,7 +40,7 @@ class Helper if($file['isPreviewAvailable']) { $pathForPreview = $file['directory'] . '/' . $file['name']; - return \OC_Helper::previewIcon($pathForPreview); + return \OC_Helper::previewIcon($pathForPreview) . '&c=' . $file['etag']; } return \OC_Helper::mimetypeIcon($file['mimetype']); } diff --git a/apps/files/templates/index.php b/apps/files/templates/index.php index 7067b854f50..00ec109621f 100644 --- a/apps/files/templates/index.php +++ b/apps/files/templates/index.php @@ -1,14 +1,13 @@ -<!--[if IE 8]><style>input[type="checkbox"]{padding:0;}table td{position:static !important;}</style><![endif]--> <div id="controls"> <?php print_unescaped($_['breadcrumb']); ?> - <div class="actions creatable <?php if (!$_['isCreatable']):?>hidden<?php endif; ?> <?php if (isset($_['files']) and count($_['files'])==0):?>emptycontent<?php endif; ?>"> + <div class="actions creatable <?php if (!$_['isCreatable']):?>hidden<?php endif; ?>"> <div id="new" class="button"> <a><?php p($l->t('New'));?></a> <ul> <li style="background-image:url('<?php p(OCP\mimetype_icon('text/plain')) ?>')" - data-type='file'><p><?php p($l->t('Text file'));?></p></li> + data-type='file' data-newname='<?php p($l->t('New text file')) ?>.txt'><p><?php p($l->t('Text file'));?></p></li> <li style="background-image:url('<?php p(OCP\mimetype_icon('dir')) ?>')" - data-type='folder'><p><?php p($l->t('Folder'));?></p></li> + data-type='folder' data-newname='<?php p($l->t('New folder')) ?>'><p><?php p($l->t('Folder'));?></p></li> <li style="background-image:url('<?php p(OCP\image_path('core', 'places/link.svg')) ?>')" data-type='web'><p><?php p($l->t('From link'));?></p></li> </ul> @@ -19,8 +18,6 @@ <input type="hidden" name="MAX_FILE_SIZE" id="max_upload" value="<?php p($_['uploadMaxFilesize']) ?>"> <?php endif;?> - <!-- Send the requesttoken, this is needed for older IE versions - because they don't send the CSRF token via HTTP header in this case --> <input type="hidden" class="max_human_file_size" value="(max <?php p($_['uploadMaxHumanFilesize']); ?>)"> <input type="hidden" name="dir" value="<?php p($_['dir']) ?>" id="dir"> @@ -28,10 +25,8 @@ data-url="<?php print_unescaped(OCP\Util::linkTo('files', 'ajax/upload.php')); ?>" /> <a href="#" class="svg"></a> </div> - <?php if ($_['trash'] ): ?> - <div id="trash" class="button" <?php $_['trashEmpty'] ? p('disabled') : '' ?>> - <a><?php p($l->t('Deleted files'));?></a> - </div> + <?php if ($_['trash']): ?> + <input id="trash" type="button" value="<?php p($l->t('Deleted files'));?>" class="button" <?php $_['trashEmpty'] ? p('disabled') : '' ?>></input> <?php endif; ?> <div id="uploadprogresswrapper"> <div id="uploadprogressbar"></div> @@ -42,19 +37,19 @@ </div> <div id="file_action_panel"></div> <div class="notCreatable notPublic <?php if ($_['isCreatable'] or $_['isPublic'] ):?>hidden<?php endif; ?>"> - <div class="actions"><input type="button" disabled value="<?php p($l->t('You don’t have write permissions here.'))?>"></div> + <?php p($l->t('You don’t have permission to upload or create files here'))?> </div> <input type="hidden" name="permissions" value="<?php p($_['permissions']); ?>" id="permissions"> </div> -<div id="emptycontent" <?php if (!isset($_['files']) or !$_['isCreatable'] or count($_['files']) > 0 or $_['ajaxLoad']):?>class="hidden"<?php endif; ?>><?php p($l->t('Nothing in here. Upload something!'))?></div> +<div id="emptycontent" <?php if (!$_['emptyContent']):?>class="hidden"<?php endif; ?>><?php p($l->t('Nothing in here. Upload something!'))?></div> <input type="hidden" id="disableSharing" data-status="<?php p($_['disableSharing']); ?>"></input> <table id="filestable" data-allow-public-upload="<?php p($_['publicUploadEnabled'])?>" data-preview-x="36" data-preview-y="36"> <thead> <tr> - <th id='headerName'> + <th <?php if (!$_['fileHeader']):?>class="hidden"<?php endif; ?> id='headerName'> <div id="headerName-container"> <input type="checkbox" id="select_all" /> <label for="select_all"></label> @@ -70,24 +65,15 @@ </span> </div> </th> - <th id="headerSize"><?php p($l->t('Size')); ?></th> - <th id="headerDate"> + <th <?php if (!$_['fileHeader']):?>class="hidden"<?php endif; ?> id="headerSize"><?php p($l->t('Size')); ?></th> + <th <?php if (!$_['fileHeader']):?>class="hidden"<?php endif; ?> id="headerDate"> <span id="modified"><?php p($l->t( 'Modified' )); ?></span> <?php if ($_['permissions'] & OCP\PERMISSION_DELETE): ?> -<!-- NOTE: Temporary fix to allow unsharing of files in root of Shared folder --> - <?php if ($_['dir'] == '/Shared'): ?> - <span class="selectedActions"><a href="" class="delete-selected"> - <?php p($l->t('Unshare'))?> - <img class="svg" alt="<?php p($l->t('Unshare'))?>" - src="<?php print_unescaped(OCP\image_path("core", "actions/delete.svg")); ?>" /> - </a></span> - <?php else: ?> - <span class="selectedActions"><a href="" class="delete-selected"> - <?php p($l->t('Delete'))?> - <img class="svg" alt="<?php p($l->t('Delete'))?>" - src="<?php print_unescaped(OCP\image_path("core", "actions/delete.svg")); ?>" /> - </a></span> - <?php endif; ?> + <span class="selectedActions"><a href="" class="delete-selected"> + <?php p($l->t('Delete'))?> + <img class="svg" alt="<?php p($l->t('Delete'))?>" + src="<?php print_unescaped(OCP\image_path("core", "actions/delete.svg")); ?>" /> + </a></span> <?php endif; ?> </th> </tr> @@ -112,9 +98,13 @@ </div> <!-- config hints for javascript --> +<input type="hidden" name="filesApp" id="filesApp" value="1" /> <input type="hidden" name="ajaxLoad" id="ajaxLoad" value="<?php p($_['ajaxLoad']); ?>" /> <input type="hidden" name="allowZipDownload" id="allowZipDownload" value="<?php p($_['allowZipDownload']); ?>" /> <input type="hidden" name="usedSpacePercent" id="usedSpacePercent" value="<?php p($_['usedSpacePercent']); ?>" /> +<?php if (!$_['isPublic']) :?> <input type="hidden" name="encryptedFiles" id="encryptedFiles" value="<?php $_['encryptedFiles'] ? p('1') : p('0'); ?>" /> <input type="hidden" name="encryptedInitStatus" id="encryptionInitStatus" value="<?php p($_['encryptionInitStatus']) ?>" /> <input type="hidden" name="mailNotificationEnabled" id="mailNotificationEnabled" value="<?php p($_['mailNotificationEnabled']) ?>" /> +<input type="hidden" name="allowShareWithLink" id="allowShareWithLink" value="<?php p($_['allowShareWithLink']) ?>" /> +<?php endif; diff --git a/apps/files/templates/part.breadcrumb.php b/apps/files/templates/part.breadcrumb.php index 9db27eb9b29..2a0df622767 100644 --- a/apps/files/templates/part.breadcrumb.php +++ b/apps/files/templates/part.breadcrumb.php @@ -1,10 +1,12 @@ -<?php if(count($_["breadcrumb"])):?> - <div class="crumb" data-dir=''> - <a href="<?php print_unescaped($_['baseURL']); ?>"> +<div class="crumb <?php if(!count($_["breadcrumb"])) p('last');?>" data-dir=''> + <a href="<?php print_unescaped($_['baseURL']); ?>"> + <?php if(isset($_['rootBreadCrumb'])): + echo $_['rootBreadCrumb']; + else:?> <img src="<?php print_unescaped(OCP\image_path('core', 'places/home.svg'));?>" class="svg" /> - </a> - </div> -<?php endif;?> + <?php endif;?> + </a> +</div> <?php for($i=0; $i<count($_["breadcrumb"]); $i++): $crumb = $_["breadcrumb"][$i]; $dir = \OCP\Util::encodePath($crumb["dir"]); ?> diff --git a/apps/files/templates/part.list.php b/apps/files/templates/part.list.php index 0679da334de..2f630e1f014 100644 --- a/apps/files/templates/part.list.php +++ b/apps/files/templates/part.list.php @@ -16,6 +16,7 @@ $totalsize = 0; ?> data-type="<?php ($file['type'] == 'dir')?p('dir'):p('file')?>" data-mime="<?php p($file['mimetype'])?>" data-size="<?php p($file['size']);?>" + data-etag="<?php p($file['etag']);?>" data-permissions="<?php p($file['permissions']); ?>"> <?php if($file['isPreviewAvailable']): ?> <td class="filename svg preview-icon" @@ -36,7 +37,7 @@ $totalsize = 0; ?> <?php else: ?> <a class="name" href="<?php p(rtrim($_['downloadURL'],'/').'/'.trim($directory,'/').'/'.$name); ?>"> <label class="filetext" title="" for="select-<?php p($file['fileid']); ?>"></label> - <span class="nametext"><?php print_unescaped(htmlspecialchars($file['basename']));?><span class='extension'><?php p($file['extension']);?></span> + <span class="nametext"><?php print_unescaped(htmlspecialchars($file['basename']));?><span class='extension'><?php p($file['extension']);?></span></span> </a> <?php endif; ?> <?php if($file['type'] == 'dir'):?> diff --git a/apps/files/tests/ajax_rename.php b/apps/files/tests/ajax_rename.php index 8eff978cde0..350ff5d3687 100644 --- a/apps/files/tests/ajax_rename.php +++ b/apps/files/tests/ajax_rename.php @@ -22,23 +22,39 @@ */ class Test_OC_Files_App_Rename extends \PHPUnit_Framework_TestCase { + private static $user; function setUp() { // mock OC_L10n + if (!self::$user) { + self::$user = uniqid(); + } + \OC_User::createUser(self::$user, 'password'); + \OC_User::setUserId(self::$user); + + \OC\Files\Filesystem::init(self::$user, '/' . self::$user . '/files'); + $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'), array(), '', false); + $viewMock = $this->getMock('\OC\Files\View', array('rename', 'normalizePath', 'getFileInfo'), 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); } + function tearDown() { + $result = \OC_User::deleteUser(self::$user); + $this->assertTrue($result); + \OC\Files\Filesystem::tearDown(); + } + /** * @brief test rename of file/folder named "Shared" */ @@ -64,17 +80,28 @@ class Test_OC_Files_App_Rename extends \PHPUnit_Framework_TestCase { $oldname = 'Shared'; $newname = 'new_name'; + $this->viewMock->expects($this->any()) + ->method('getFileInfo') + ->will($this->returnValue(array( + 'fileid' => 123, + 'type' => 'dir', + 'mimetype' => 'httpd/unix-directory', + 'size' => 18, + 'etag' => 'abcdef', + 'directory' => '/', + 'name' => 'new_name', + ))); + $result = $this->files->rename($dir, $oldname, $newname); - $expected = array( - 'success' => true, - 'data' => array( - 'dir' => $dir, - 'file' => $oldname, - 'newname' => $newname - ) - ); - $this->assertEquals($expected, $result); + $this->assertTrue($result['success']); + $this->assertEquals(123, $result['data']['id']); + $this->assertEquals('new_name', $result['data']['name']); + $this->assertEquals('/test', $result['data']['directory']); + $this->assertEquals(18, $result['data']['size']); + $this->assertEquals('httpd/unix-directory', $result['data']['mime']); + $this->assertEquals(\OC_Helper::mimetypeIcon('dir'), $result['data']['icon']); + $this->assertFalse($result['data']['isPreviewAvailable']); } /** @@ -88,7 +115,7 @@ class Test_OC_Files_App_Rename extends \PHPUnit_Framework_TestCase { $result = $this->files->rename($dir, $oldname, $newname); $expected = array( 'success' => false, - 'data' => array('message' => "Invalid folder name. Usage of 'Shared' is reserved by ownCloud") + 'data' => array('message' => "Invalid folder name. Usage of 'Shared' is reserved.") ); $this->assertEquals($expected, $result); @@ -102,16 +129,29 @@ class Test_OC_Files_App_Rename extends \PHPUnit_Framework_TestCase { $oldname = 'oldname'; $newname = 'newname'; + $this->viewMock->expects($this->any()) + ->method('getFileInfo') + ->will($this->returnValue(array( + 'fileid' => 123, + 'type' => 'dir', + 'mimetype' => 'httpd/unix-directory', + 'size' => 18, + 'etag' => 'abcdef', + 'directory' => '/', + 'name' => 'new_name', + ))); + + $result = $this->files->rename($dir, $oldname, $newname); - $expected = array( - 'success' => true, - 'data' => array( - 'dir' => $dir, - 'file' => $oldname, - 'newname' => $newname - ) - ); - $this->assertEquals($expected, $result); + $this->assertTrue($result['success']); + $this->assertEquals(123, $result['data']['id']); + $this->assertEquals('newname', $result['data']['name']); + $this->assertEquals('/', $result['data']['directory']); + $this->assertEquals(18, $result['data']['size']); + $this->assertEquals('httpd/unix-directory', $result['data']['mime']); + $this->assertEquals('abcdef', $result['data']['etag']); + $this->assertEquals(\OC_Helper::mimetypeIcon('dir'), $result['data']['icon']); + $this->assertFalse($result['data']['isPreviewAvailable']); } } diff --git a/apps/files_encryption/ajax/getMigrationStatus.php b/apps/files_encryption/ajax/getMigrationStatus.php new file mode 100644 index 00000000000..17469a1af0c --- /dev/null +++ b/apps/files_encryption/ajax/getMigrationStatus.php @@ -0,0 +1,28 @@ +<?php +/** + * Copyright (c) 2013, Bjoern Schiessle <schiessle@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or later. + * See the COPYING-README file. + * + * @brief check migration status + */ +use OCA\Encryption\Util; + +\OCP\JSON::checkAppEnabled('files_encryption'); + +$loginname = isset($_POST['user']) ? $_POST['user'] : ''; +$password = isset($_POST['password']) ? $_POST['password'] : ''; + +$migrationCompleted = true; + +if ($loginname !== '' && $password !== '') { + $username = \OCP\User::checkPassword($loginname, $password); + if ($username) { + $util = new Util(new \OC_FilesystemView('/'), $username); + if ($util->getMigrationStatus() !== Util::MIGRATION_COMPLETED) { + $migrationCompleted = false; + } + } +} + +\OCP\JSON::success(array('data' => array('migrationCompleted' => $migrationCompleted))); diff --git a/apps/files_encryption/appinfo/app.php b/apps/files_encryption/appinfo/app.php index c930ac9eca8..fd9aa429b01 100644 --- a/apps/files_encryption/appinfo/app.php +++ b/apps/files_encryption/appinfo/app.php @@ -10,6 +10,8 @@ OC::$CLASSPATH['OCA\Encryption\Session'] = 'files_encryption/lib/session.php'; OC::$CLASSPATH['OCA\Encryption\Capabilities'] = 'files_encryption/lib/capabilities.php'; OC::$CLASSPATH['OCA\Encryption\Helper'] = 'files_encryption/lib/helper.php'; +\OCP\Util::addscript('files_encryption', 'detect-migration'); + if (!OC_Config::getValue('maintenance', false)) { OC_FileProxy::register(new OCA\Encryption\Proxy()); @@ -52,4 +54,3 @@ if (!OC_Config::getValue('maintenance', false)) { // Register settings scripts OCP\App::registerAdmin('files_encryption', 'settings-admin'); OCP\App::registerPersonal('files_encryption', 'settings-personal'); - diff --git a/apps/files_encryption/files/error.php b/apps/files_encryption/files/error.php index ac0c0269164..317cea05a12 100644 --- a/apps/files_encryption/files/error.php +++ b/apps/files_encryption/files/error.php @@ -5,26 +5,40 @@ if (!isset($_)) { //also provide standalone error page $l = OC_L10N::get('files_encryption'); - if (isset($_GET['i']) && $_GET['i'] === '0') { - $errorMsg = $l->t('Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app.'); - $init = '0'; + if (isset($_GET['errorCode'])) { + $errorCode = $_GET['errorCode']; + switch ($errorCode) { + case \OCA\Encryption\Crypt::ENCRYPTION_NOT_INITIALIZED_ERROR: + $errorMsg = $l->t('Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app.'); + break; + case \OCA\Encryption\Crypt::ENCRYPTION_PRIVATE_KEY_NOT_VALID_ERROR: + $theme = new OC_Defaults(); + $errorMsg = $l->t('Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files.', array($theme->getName())); + break; + case \OCA\Encryption\Crypt::ENCRYPTION_NO_SHARE_KEY_FOUND: + $errorMsg = $l->t('Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you.'); + break; + default: + $errorMsg = $l->t("Unknown error please check your system settings or contact your administrator"); + break; + } } else { - $errorMsg = $l->t('Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files.'); - $init = '1'; + $errorCode = \OCA\Encryption\Crypt::ENCRYPTION_UNKNOWN_ERROR; + $errorMsg = $l->t("Unknown error please check your system settings or contact your administrator"); } if (isset($_GET['p']) && $_GET['p'] === '1') { - header('HTTP/1.0 404 ' . $errorMsg); + header('HTTP/1.0 403 ' . $errorMsg); } // check if ajax request if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') { \OCP\JSON::error(array('data' => array('message' => $errorMsg))); } else { - header('HTTP/1.0 404 ' . $errorMsg); + header('HTTP/1.0 403 ' . $errorMsg); $tmpl = new OC_Template('files_encryption', 'invalid_private_key', 'guest'); $tmpl->assign('message', $errorMsg); - $tmpl->assign('init', $init); + $tmpl->assign('errorCode', $errorCode); $tmpl->printPage(); } diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index 2df860a8e57..09d5687e226 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -30,11 +30,20 @@ use OC\Files\Filesystem; */
class Hooks {
+ // file for which we want to rename the keys after the rename operation was successful
+ private static $renamedFiles = array();
+
/**
* @brief Startup encryption backend upon user login
* @note This method should never be called for users using client side encryption
*/
public static function login($params) {
+
+ if (\OCP\App::isEnabled('files_encryption') === false) {
+ return true;
+ }
+
+
$l = new \OC_L10N('files_encryption');
$view = new \OC_FilesystemView('/');
@@ -92,8 +101,6 @@ class Hooks { }
// Encrypt existing user files:
- // This serves to upgrade old versions of the encryption
- // app (see appinfo/spec.txt)
if (
$util->encryptAll('/' . $params['uid'] . '/' . 'files', $session->getLegacyKey(), $params['password'])
) {
@@ -119,11 +126,12 @@ class Hooks { * @note This method should never be called for users using client side encryption
*/
public static function postCreateUser($params) {
- $view = new \OC_FilesystemView('/');
-
- $util = new Util($view, $params['uid']);
- Helper::setupUser($util, $params['password']);
+ if (\OCP\App::isEnabled('files_encryption')) {
+ $view = new \OC_FilesystemView('/');
+ $util = new Util($view, $params['uid']);
+ Helper::setupUser($util, $params['password']);
+ }
}
/**
@@ -131,26 +139,31 @@ class Hooks { * @note This method should never be called for users using client side encryption
*/
public static function postDeleteUser($params) {
- $view = new \OC_FilesystemView('/');
- // cleanup public key
- $publicKey = '/public-keys/' . $params['uid'] . '.public.key';
+ if (\OCP\App::isEnabled('files_encryption')) {
+ $view = new \OC_FilesystemView('/');
- // Disable encryption proxy to prevent recursive calls
- $proxyStatus = \OC_FileProxy::$enabled;
- \OC_FileProxy::$enabled = false;
+ // cleanup public key
+ $publicKey = '/public-keys/' . $params['uid'] . '.public.key';
- $view->unlink($publicKey);
+ // Disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
- \OC_FileProxy::$enabled = $proxyStatus;
+ $view->unlink($publicKey);
+
+ \OC_FileProxy::$enabled = $proxyStatus;
+ }
}
/**
* @brief If the password can't be changed within ownCloud, than update the key password in advance.
*/
public static function preSetPassphrase($params) {
- if ( ! \OC_User::canUserChangePassword($params['uid']) ) {
- self::setPassphrase($params);
+ if (\OCP\App::isEnabled('files_encryption')) {
+ if ( ! \OC_User::canUserChangePassword($params['uid']) ) {
+ self::setPassphrase($params);
+ }
}
}
@@ -159,14 +172,19 @@ class Hooks { * @param array $params keys: uid, password
*/
public static function setPassphrase($params) {
+
+ if (\OCP\App::isEnabled('files_encryption') === false) {
+ return true;
+ }
+
// Only attempt to change passphrase if server-side encryption
// is in use (client-side encryption does not have access to
// the necessary keys)
if (Crypt::mode() === 'server') {
- if ($params['uid'] === \OCP\User::getUser()) {
+ $view = new \OC_FilesystemView('/');
- $view = new \OC_FilesystemView('/');
+ if ($params['uid'] === \OCP\User::getUser()) {
$session = new \OCA\Encryption\Session($view);
@@ -187,36 +205,41 @@ class Hooks { } else { // admin changed the password for a different user, create new keys and reencrypt file keys
$user = $params['uid'];
- $recoveryPassword = $params['recoveryPassword'];
- $newUserPassword = $params['password'];
+ $util = new Util($view, $user);
+ $recoveryPassword = isset($params['recoveryPassword']) ? $params['recoveryPassword'] : null;
- $view = new \OC_FilesystemView('/');
+ if (($util->recoveryEnabledForUser() && $recoveryPassword)
+ || !$util->userKeysExists()) {
- // make sure that the users home is mounted
- \OC\Files\Filesystem::initMountPoints($user);
+ $recoveryPassword = $params['recoveryPassword'];
+ $newUserPassword = $params['password'];
- $keypair = Crypt::createKeypair();
+ // make sure that the users home is mounted
+ \OC\Files\Filesystem::initMountPoints($user);
- // Disable encryption proxy to prevent recursive calls
- $proxyStatus = \OC_FileProxy::$enabled;
- \OC_FileProxy::$enabled = false;
+ $keypair = Crypt::createKeypair();
- // Save public key
- $view->file_put_contents('/public-keys/' . $user . '.public.key', $keypair['publicKey']);
+ // Disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
- // Encrypt private key empty passphrase
- $encryptedPrivateKey = Crypt::symmetricEncryptFileContent($keypair['privateKey'], $newUserPassword);
+ // Save public key
+ $view->file_put_contents('/public-keys/' . $user . '.public.key', $keypair['publicKey']);
- // Save private key
- $view->file_put_contents(
- '/' . $user . '/files_encryption/' . $user . '.private.key', $encryptedPrivateKey);
+ // Encrypt private key empty passphrase
+ $encryptedPrivateKey = Crypt::symmetricEncryptFileContent($keypair['privateKey'], $newUserPassword);
- if ($recoveryPassword) { // if recovery key is set we can re-encrypt the key files
- $util = new Util($view, $user);
- $util->recoverUsersFiles($recoveryPassword);
- }
+ // Save private key
+ $view->file_put_contents(
+ '/' . $user . '/files_encryption/' . $user . '.private.key', $encryptedPrivateKey);
+
+ if ($recoveryPassword) { // if recovery key is set we can re-encrypt the key files
+ $util = new Util($view, $user);
+ $util->recoverUsersFiles($recoveryPassword);
+ }
- \OC_FileProxy::$enabled = $proxyStatus;
+ \OC_FileProxy::$enabled = $proxyStatus;
+ }
}
}
}
@@ -229,6 +252,10 @@ class Hooks { */
public static function preShared($params) {
+ if (\OCP\App::isEnabled('files_encryption') === false) {
+ return true;
+ }
+
$l = new \OC_L10N('files_encryption');
$users = array();
$view = new \OC\Files\View('/public-keys/');
@@ -280,6 +307,10 @@ class Hooks { // [run] => whether emitting script should continue to run
// TODO: Should other kinds of item be encrypted too?
+ if (\OCP\App::isEnabled('files_encryption') === false) {
+ return true;
+ }
+
if ($params['itemType'] === 'file' || $params['itemType'] === 'folder') {
$view = new \OC_FilesystemView('/');
@@ -295,8 +326,8 @@ class Hooks { // get the parent from current share
$parent = $util->getShareParent($params['parent']);
- // if parent is file the it is an 1:1 share
- if ($parent['item_type'] === 'file') {
+ // if parent has the same type than the child it is a 1:1 share
+ if ($parent['item_type'] === $params['itemType']) {
// prefix path with Shared
$path = '/Shared' . $parent['file_target'];
@@ -374,6 +405,10 @@ class Hooks { // [shareWith] => test1
// [itemParent] =>
+ if (\OCP\App::isEnabled('files_encryption') === false) {
+ return true;
+ }
+
if ($params['itemType'] === 'file' || $params['itemType'] === 'folder') {
$view = new \OC_FilesystemView('/');
@@ -448,6 +483,18 @@ class Hooks { }
/**
+ * @brief mark file as renamed so that we know the original source after the file was renamed
+ * @param array $params with the old path and the new path
+ */
+ public static function preRename($params) {
+ $util = new Util(new \OC_FilesystemView('/'), \OCP\User::getUser());
+ list($ownerOld, $pathOld) = $util->getUidAndFilename($params['oldpath']);
+ self::$renamedFiles[$params['oldpath']] = array(
+ 'uid' => $ownerOld,
+ 'path' => $pathOld);
+ }
+
+ /**
* @brief after a file is renamed, rename its keyfile and share-keys also fix the file size and fix also the sharing
* @param array with oldpath and newpath
*
@@ -455,6 +502,11 @@ class Hooks { * of the stored versions along the actual file
*/
public static function postRename($params) {
+
+ if (\OCP\App::isEnabled('files_encryption') === false) {
+ return true;
+ }
+
// Disable encryption proxy to prevent recursive calls
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
@@ -464,19 +516,32 @@ class Hooks { $userId = \OCP\User::getUser();
$util = new Util($view, $userId);
+ if (isset(self::$renamedFiles[$params['oldpath']]['uid']) &&
+ isset(self::$renamedFiles[$params['oldpath']]['path'])) {
+ $ownerOld = self::$renamedFiles[$params['oldpath']]['uid'];
+ $pathOld = self::$renamedFiles[$params['oldpath']]['path'];
+ } else {
+ \OCP\Util::writeLog('Encryption library', "can't get path and owner from the file before it was renamed", \OCP\Util::ERROR);
+ return false;
+ }
+
+ list($ownerNew, $pathNew) = $util->getUidAndFilename($params['newpath']);
+
// Format paths to be relative to user files dir
- if ($util->isSystemWideMountPoint($params['oldpath'])) {
- $baseDir = 'files_encryption/';
- $oldKeyfilePath = $baseDir . 'keyfiles/' . $params['oldpath'];
+ if ($util->isSystemWideMountPoint($pathOld)) {
+ $oldKeyfilePath = 'files_encryption/keyfiles/' . $pathOld;
+ $oldShareKeyPath = 'files_encryption/share-keys/' . $pathOld;
} else {
- $baseDir = $userId . '/' . 'files_encryption/';
- $oldKeyfilePath = $baseDir . 'keyfiles/' . $params['oldpath'];
+ $oldKeyfilePath = $ownerOld . '/' . 'files_encryption/keyfiles/' . $pathOld;
+ $oldShareKeyPath = $ownerOld . '/' . 'files_encryption/share-keys/' . $pathOld;
}
- if ($util->isSystemWideMountPoint($params['newpath'])) {
- $newKeyfilePath = $baseDir . 'keyfiles/' . $params['newpath'];
+ if ($util->isSystemWideMountPoint($pathNew)) {
+ $newKeyfilePath = 'files_encryption/keyfiles/' . $pathNew;
+ $newShareKeyPath = 'files_encryption/share-keys/' . $pathNew;
} else {
- $newKeyfilePath = $baseDir . 'keyfiles/' . $params['newpath'];
+ $newKeyfilePath = $ownerNew . '/files_encryption/keyfiles/' . $pathNew;
+ $newShareKeyPath = $ownerNew . '/files_encryption/share-keys/' . $pathNew;
}
// add key ext if this is not an folder
@@ -485,11 +550,11 @@ class Hooks { $newKeyfilePath .= '.key';
// handle share-keys
- $localKeyPath = $view->getLocalFile($baseDir . 'share-keys/' . $params['oldpath']);
+ $localKeyPath = $view->getLocalFile($oldShareKeyPath);
$escapedPath = Helper::escapeGlobPattern($localKeyPath);
$matches = glob($escapedPath . '*.shareKey');
foreach ($matches as $src) {
- $dst = \OC\Files\Filesystem::normalizePath(str_replace($params['oldpath'], $params['newpath'], $src));
+ $dst = \OC\Files\Filesystem::normalizePath(str_replace($pathOld, $pathNew, $src));
// create destination folder if not exists
if (!file_exists(dirname($dst))) {
@@ -501,15 +566,13 @@ class Hooks { } else {
// handle share-keys folders
- $oldShareKeyfilePath = $baseDir . 'share-keys/' . $params['oldpath'];
- $newShareKeyfilePath = $baseDir . 'share-keys/' . $params['newpath'];
// create destination folder if not exists
- if (!$view->file_exists(dirname($newShareKeyfilePath))) {
- $view->mkdir(dirname($newShareKeyfilePath), 0750, true);
+ if (!$view->file_exists(dirname($newShareKeyPath))) {
+ $view->mkdir(dirname($newShareKeyPath), 0750, true);
}
- $view->rename($oldShareKeyfilePath, $newShareKeyfilePath);
+ $view->rename($oldShareKeyPath, $newShareKeyPath);
}
// Rename keyfile so it isn't orphaned
@@ -524,18 +587,17 @@ class Hooks { }
// build the path to the file
- $newPath = '/' . $userId . '/files' . $params['newpath'];
- $newPathRelative = $params['newpath'];
+ $newPath = '/' . $ownerNew . '/files' . $pathNew;
if ($util->fixFileSize($newPath)) {
// get sharing app state
$sharingEnabled = \OCP\Share::isEnabled();
// get users
- $usersSharing = $util->getSharingUsersArray($sharingEnabled, $newPathRelative);
+ $usersSharing = $util->getSharingUsersArray($sharingEnabled, $pathNew);
// update sharing-keys
- $util->setSharedFileKeyfiles($session, $usersSharing, $newPathRelative);
+ $util->setSharedFileKeyfiles($session, $usersSharing, $pathNew);
}
\OC_FileProxy::$enabled = $proxyStatus;
@@ -557,4 +619,15 @@ class Hooks { }
}
+ /**
+ * set the init status to 'NOT_INITIALIZED' (0) if the app gets enabled
+ * @param array $params contains the app ID
+ */
+ public static function postEnable($params) {
+ if ($params['app'] === 'files_encryption') {
+ $session = new \OCA\Encryption\Session(new \OC\Files\View('/'));
+ $session->setInitialized(\OCA\Encryption\Session::NOT_INITIALIZED);
+ }
+ }
+
}
diff --git a/apps/files_encryption/js/detect-migration.js b/apps/files_encryption/js/detect-migration.js new file mode 100644 index 00000000000..301e77f24f7 --- /dev/null +++ b/apps/files_encryption/js/detect-migration.js @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2013 + * Bjoern Schiessle <schiessle@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or later. + * See the COPYING-README file. + */ + + +$(document).ready(function(){ + $('form[name="login"]').on('submit', function() { + var user = $('#user').val(); + var password = $('#password').val(); + $.ajax({ + type: 'POST', + url: OC.linkTo('files_encryption', 'ajax/getMigrationStatus.php'), + dataType: 'json', + data: {user: user, password: password}, + async: false, + success: function(response) { + if (response.data.migrationCompleted === false) { + var message = t('files_encryption', 'Initial encryption started... This can take some time. Please wait.'); + $('#messageText').text(message); + $('#message').removeClass('hidden').addClass('update'); + } + } + }); + }); + +}); diff --git a/apps/files_encryption/l10n/ca.php b/apps/files_encryption/l10n/ca.php index 14d7992ad5d..33d2754483c 100644 --- a/apps/files_encryption/l10n/ca.php +++ b/apps/files_encryption/l10n/ca.php @@ -8,22 +8,27 @@ $TRANSLATIONS = array( "Could not change the password. Maybe the old password was not correct." => "No s'ha pogut canviar la contrasenya. Potser la contrasenya anterior no era correcta.", "Private key password successfully updated." => "La contrasenya de la clau privada s'ha actualitzat.", "Could not update the private key password. Maybe the old password was not correct." => "No s'ha pogut actualitzar la contrasenya de la clau privada. Potser la contrasenya anterior no era correcta.", -"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "La clau privada no és vàlida! Probablement la contrasenya va ser canviada des de fora del sistema ownCloud (per exemple, en el directori de l'empresa). Vostè pot actualitzar la contrasenya de clau privada en la seva configuració personal per poder recuperar l'accés en els arxius xifrats.", +"Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." => "L'aplicació d'encriptació no està inicialitzada! Potser l'aplicació d'encriptació ha estat reiniciada durant la sessió. Intenteu sortir i acreditar-vos de nou per reinicialitzar l'aplicació d'encriptació.", +"Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "La clau privada no és vàlida! Probablement la contrasenya va ser canviada des de fora de %s (per exemple, en el directori de l'empresa). Vostè pot actualitzar la contrasenya de clau privada en la seva configuració personal per poder recuperar l'accés en els arxius xifrats.", +"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "No es pot desencriptar aquest fitxer, probablement és un fitxer compartit. Demaneu al propietari del fitxer que el comparteixi de nou amb vós.", +"Unknown error please check your system settings or contact your administrator" => "Error desconegut. Comproveu l'arranjament del sistema o contacteu amb l'administrador", "Missing requirements." => "Manca de requisits.", "Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Assegureu-vos que teniu instal·lat PHP 5.3.3 o una versió superior i que està activat Open SSL i habilitada i configurada correctament l'extensió de PHP. De moment, l'aplicació d'encriptació s'ha desactivat.", "Following users are not set up for encryption:" => "Els usuaris següents no estan configurats per a l'encriptació:", +"Initial encryption started... This can take some time. Please wait." => "La encriptació inicial ha començat... Pot trigar una estona, espereu.", "Saving..." => "Desant...", -"Your private key is not valid! Maybe the your password was changed from outside." => "La vostra clau privada no és vàlida! Potser la vostra contrasenya ha canviat des de fora.", -"You can unlock your private key in your " => "Podeu desbloquejar la clau privada en el vostre", +"Go directly to your " => "Vés directament a", "personal settings" => "arranjament personal", "Encryption" => "Xifrat", "Enable recovery key (allow to recover users files in case of password loss):" => "Activa la clau de recuperació (permet recuperar fitxers d'usuaris en cas de pèrdua de contrasenya):", "Recovery key password" => "Clau de recuperació de la contrasenya", +"Repeat Recovery key password" => "Repetiu la clau de recuperació de contrasenya", "Enabled" => "Activat", "Disabled" => "Desactivat", "Change recovery key password:" => "Canvia la clau de recuperació de contrasenya:", "Old Recovery key password" => "Antiga clau de recuperació de contrasenya", "New Recovery key password" => "Nova clau de recuperació de contrasenya", +"Repeat New Recovery key password" => "Repetiu la nova clau de recuperació de contrasenya", "Change Password" => "Canvia la contrasenya", "Your private key password no longer match your log-in password:" => "La clau privada ja no es correspon amb la contrasenya d'accés:", "Set your old private key password to your current log-in password." => "Establiu la vostra contrasenya clau en funció de la contrasenya actual d'accés.", diff --git a/apps/files_encryption/l10n/cs_CZ.php b/apps/files_encryption/l10n/cs_CZ.php index 89f63cc1cdd..cf2776371df 100644 --- a/apps/files_encryption/l10n/cs_CZ.php +++ b/apps/files_encryption/l10n/cs_CZ.php @@ -8,22 +8,27 @@ $TRANSLATIONS = array( "Could not change the password. Maybe the old password was not correct." => "Změna hesla se nezdařila. Pravděpodobně nebylo stávající heslo zadáno správně.", "Private key password successfully updated." => "Heslo soukromého klíče úspěšně aktualizováno.", "Could not update the private key password. Maybe the old password was not correct." => "Nelze aktualizovat heslo soukromého klíče. Možná nebylo staré heslo správně.", -"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Váš soukromý klíč není platný! Pravděpodobně bylo heslo změněno vně systému ownCloud (např. ve vašem firemním adresáři). Heslo vašeho soukromého klíče můžete změnit ve svém osobním nastavení pro obnovení přístupu k vašim zašifrovaným souborům.", +"Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." => "Aplikace pro šifrování není inicializována! Je možné, že aplikace byla znovu aktivována během vašeho přihlášení. Zkuste se prosím odhlásit a znovu přihlásit pro provedení inicializace šifrovací aplikace.", +"Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Váš soukromý klíč není platný! Pravděpodobně bylo vaše heslo změněno vně systému %s (např. ve vašem firemním adresáři). Heslo vašeho soukromého klíče můžete změnit ve svém osobním nastavení pro obnovení přístupu k vašim zašifrovaným souborům.", +"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "Tento soubor se nepodařilo dešifrovat, pravděpodobně je sdílený. Požádejte prosím majitele souboru, aby jej s vámi znovu sdílel.", +"Unknown error please check your system settings or contact your administrator" => "Neznámá chyba, zkontrolujte vaše systémová nastavení nebo kontaktujte vašeho správce", "Missing requirements." => "Nesplněné závislosti.", "Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Ujistěte se prosím, že máte nainstalované PHP 5.3.3 nebo novější a že máte povolené a správně nakonfigurované OpenSSL včetně jeho rozšíření pro PHP. Prozatím byla aplikace pro šifrování vypnuta.", "Following users are not set up for encryption:" => "Následující uživatelé nemají nastavené šifrování:", +"Initial encryption started... This can take some time. Please wait." => "Počáteční šifrování zahájeno... Toto může chvíli trvat. Počkejte prosím.", "Saving..." => "Ukládám...", -"Your private key is not valid! Maybe the your password was changed from outside." => "Váš soukromý klíč není platný! Pravděpodobně bylo vaše heslo změněno zvenčí.", -"You can unlock your private key in your " => "Můžete odemknout váš soukromý klíč ve vašem", +"Go directly to your " => "Běžte přímo do vašeho", "personal settings" => "osobní nastavení", "Encryption" => "Šifrování", "Enable recovery key (allow to recover users files in case of password loss):" => "Povolit klíč pro obnovu (umožňuje obnovu uživatelských souborů v případě ztráty hesla)", "Recovery key password" => "Heslo klíče pro obnovu", +"Repeat Recovery key password" => "Zopakujte heslo klíče pro obnovu", "Enabled" => "Povoleno", "Disabled" => "Zakázáno", "Change recovery key password:" => "Změna hesla klíče pro obnovu:", "Old Recovery key password" => "Původní heslo klíče pro obnovu", "New Recovery key password" => "Nové heslo klíče pro obnovu", +"Repeat New Recovery key password" => "Zopakujte nové heslo klíče pro obnovu", "Change Password" => "Změnit heslo", "Your private key password no longer match your log-in password:" => "Heslo vašeho soukromého klíče se již neshoduje s vaším přihlašovacím heslem:", "Set your old private key password to your current log-in password." => "Změňte heslo vaše soukromého klíče na stejné jako vaše přihlašovací heslo.", diff --git a/apps/files_encryption/l10n/da.php b/apps/files_encryption/l10n/da.php index 1b7069b6784..9e4290534c0 100644 --- a/apps/files_encryption/l10n/da.php +++ b/apps/files_encryption/l10n/da.php @@ -8,22 +8,27 @@ $TRANSLATIONS = array( "Could not change the password. Maybe the old password was not correct." => "Kunne ikke ændre kodeordet. Måske var det gamle kodeord ikke korrekt.", "Private key password successfully updated." => "Privat nøgle kodeord succesfuldt opdateret.", "Could not update the private key password. Maybe the old password was not correct." => "Kunne ikke opdatere det private nøgle kodeord-. Måske var det gamle kodeord forkert.", -"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Din private nøgle er gyldig! Sandsynligvis blev dit kodeord ændre uden for ownCloud systemet (f.eks. dit firmas register). Du kan opdatere dit private nøgle kodeord under personlige indstillinger, for at generhverve adgang til dine krypterede filer.", +"Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." => "Krypteringsprogrammet er ikke igangsat. Det kan skyldes at krypteringsprogrammet er blevet genaktiveret under din session. Prøv at logge ud og ind igen for at aktivere krypteringsprogrammet. ", +"Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Din private nøgle er ikke gyldig. Sandsynligvis er dit kodeord blevet ændret uden for %s (f.eks dit firmas adressebog). Du kan opdatere din private nøglekode i dine personlige indstillinger for at genskabe adgang til dine krypterede filer.", +"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "Kan ikke kryptere denne fil, sandsynligvis fordi felen er delt. Bed venligst filens ejer om at dele den med dig på ny.", +"Unknown error please check your system settings or contact your administrator" => "Ukendt fejl. Kontroller venligst dit system eller kontakt din administrator", "Missing requirements." => "Manglende betingelser.", "Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Sørg for at PHP 5.3.3 eller nyere er installeret og at OpenSSL sammen med PHP-udvidelsen er aktiveret og korrekt konfigureret. Indtil videre er krypteringsprogrammet deaktiveret.", "Following users are not set up for encryption:" => "Følgende brugere er ikke sat op til kryptering:", +"Initial encryption started... This can take some time. Please wait." => "Førstegangskryptering er påbegyndt... Dette kan tage nogen tid. Vent venligst.", "Saving..." => "Gemmer...", -"Your private key is not valid! Maybe the your password was changed from outside." => "Din private nøgle er ikke gyldig. Måske blev dit kodeord ændre udefra.", -"You can unlock your private key in your " => "Du kan låse din private nøgle op i din ", +"Go directly to your " => "Gå direkte til din ", "personal settings" => "Personlige indstillinger", "Encryption" => "Kryptering", "Enable recovery key (allow to recover users files in case of password loss):" => "Aktiver gendannelsesnøgle (Tillad gendannelse af brugerfiler i tilfælde af tab af kodeord):", "Recovery key password" => "Gendannelsesnøgle kodeord", +"Repeat Recovery key password" => "Gentag gendannelse af nøglekoden", "Enabled" => "Aktiveret", "Disabled" => "Deaktiveret", "Change recovery key password:" => "Skift gendannelsesnøgle kodeord:", "Old Recovery key password" => "Gammel Gendannelsesnøgle kodeord", "New Recovery key password" => "Ny Gendannelsesnøgle kodeord", +"Repeat New Recovery key password" => "Gentag dannelse af ny gendannaleses nøglekode", "Change Password" => "Skift Kodeord", "Your private key password no longer match your log-in password:" => "Dit private nøgle kodeord stemmer ikke længere overens med dit login kodeord:", "Set your old private key password to your current log-in password." => "Sæt dit gamle private nøgle kodeord til at være dit nuværende login kodeord. ", diff --git a/apps/files_encryption/l10n/de.php b/apps/files_encryption/l10n/de.php index 4c36d31ed6b..3ba50f074b9 100644 --- a/apps/files_encryption/l10n/de.php +++ b/apps/files_encryption/l10n/de.php @@ -1,38 +1,43 @@ <?php $TRANSLATIONS = array( "Recovery key successfully enabled" => "Wiederherstellungsschlüssel wurde erfolgreich aktiviert", -"Could not enable recovery key. Please check your recovery key password!" => "Der Wiederherstellungsschlüssel konnte nicht aktiviert werden. Überprüfen Sie Ihr Wiederherstellungspasswort!", +"Could not enable recovery key. Please check your recovery key password!" => "Der Wiederherstellungsschlüssel konnte nicht aktiviert werden. Überprüfe Dein Wiederherstellungspasswort!", "Recovery key successfully disabled" => "Wiederherstellungsschlüssel deaktiviert.", -"Could not disable recovery key. Please check your recovery key password!" => "Der Wiederherstellungsschlüssel konnte nicht deaktiviert werden. Überprüfen Sie Ihr Wiederherstellungspasswort!", +"Could not disable recovery key. Please check your recovery key password!" => "Der Wiederherstellungsschlüssel konnte nicht deaktiviert werden. Überprüfe Dein Wiederherstellungspasswort!", "Password successfully changed." => "Dein Passwort wurde geändert.", "Could not change the password. Maybe the old password was not correct." => "Das Passwort konnte nicht geändert werden. Vielleicht war das alte Passwort falsch.", "Private key password successfully updated." => "Passwort des privaten Schlüssels erfolgreich aktualisiert", "Could not update the private key password. Maybe the old password was not correct." => "Das Passwort des privaten Schlüssels konnte nicht aktualisiert werden. Eventuell war das alte Passwort falsch.", -"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Dein privater Schlüssel ist ungültig. Möglicher Weise wurde von außerhalb Dein Passwort geändert (z.B. in deinem gemeinsamen Verzeichnis). Du kannst das Passwort deines privaten Schlüssels in den persönlichen Einstellungen aktualisieren, um wieder an deine Dateien zu gelangen.", +"Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." => "Verschlüsselung-App ist nicht initialisiert! Vielleicht wurde die Verschlüsselung-App in der aktuellen Sitzung reaktiviert. Bitte versuche Dich ab- und wieder anzumelden, um die Verschlüsselung-App zu initialisieren.", +"Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Dein privater Schlüssel ist ungültig. Möglicher Weise wurde außerhalb von %s Dein Passwort geändert (z.B. in Deinem gemeinsamen Verzeichnis). Du kannst das Passwort Deines privaten Schlüssels in den persönlichen Einstellungen aktualisieren, um wieder an Deine Dateien zu gelangen.", +"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "Die Datei kann nicht entschlüsselt werden, da die Datei möglicherweise eine geteilte Datei ist. Bitte frage den Dateibesitzer, ob er die Datei nochmals mit Dir teilt.", +"Unknown error please check your system settings or contact your administrator" => "Unbekannter Fehler, bitte prüfe Deine Systemeinstellungen oder kontaktiere Deinen Administrator", "Missing requirements." => "Fehlende Vorraussetzungen", "Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Bitte stelle sicher, dass PHP 5.3.3 oder neuer installiert und das OpenSSL zusammen mit der PHP-Erweiterung aktiviert und richtig konfiguriert ist. Zur Zeit ist die Verschlüsselungs-App deaktiviert.", "Following users are not set up for encryption:" => "Für folgende Nutzer ist keine Verschlüsselung eingerichtet:", +"Initial encryption started... This can take some time. Please wait." => "Initialverschlüsselung gestartet... Dies kann einige Zeit dauern. Bitte warten.", "Saving..." => "Speichern...", -"Your private key is not valid! Maybe the your password was changed from outside." => "Ihr privater Schlüssel ist ungültig! Eventuell wurde Ihr Passwort von außerhalb geändert.", -"You can unlock your private key in your " => "Du kannst den privaten Schlüssel ändern und zwar in deinem", +"Go directly to your " => "Direkt wechseln zu Deinem", "personal settings" => "Private Einstellungen", "Encryption" => "Verschlüsselung", "Enable recovery key (allow to recover users files in case of password loss):" => "Wiederherstellungsschlüssel aktivieren (ermöglicht das Wiederherstellen von Dateien, falls das Passwort vergessen wurde):", "Recovery key password" => "Wiederherstellungsschlüssel-Passwort", +"Repeat Recovery key password" => "Schlüssel-Passwort zur Wiederherstellung wiederholen", "Enabled" => "Aktiviert", "Disabled" => "Deaktiviert", "Change recovery key password:" => "Wiederherstellungsschlüssel-Passwort ändern:", "Old Recovery key password" => "Altes Wiederherstellungsschlüssel-Passwort", "New Recovery key password" => "Neues Wiederherstellungsschlüssel-Passwort", +"Repeat New Recovery key password" => "Neues Schlüssel-Passwort zur Wiederherstellung wiederholen", "Change Password" => "Passwort ändern", -"Your private key password no longer match your log-in password:" => "Ihr Passwort für ihren privaten Schlüssel stimmt nicht mehr mit ihrem Loginpasswort überein.", -"Set your old private key password to your current log-in password." => "Setzen Sie ihr altes Passwort für ihren privaten Schlüssel auf ihr aktuelles Login-Passwort", -" If you don't remember your old password you can ask your administrator to recover your files." => "Wenn Sie Ihr altes Passwort vergessen haben, können Sie den Administrator bitten, Ihre Daten wiederherzustellen.", -"Old log-in password" => "Altes login Passwort", +"Your private key password no longer match your log-in password:" => "Das Passwort für Deinen privaten Schlüssel stimmt nicht mehr mit Deinem Loginpasswort überein.", +"Set your old private key password to your current log-in password." => "Setze Dein altes Passwort für Deinen privaten Schlüssel auf Dein aktuelles Login-Passwort", +" If you don't remember your old password you can ask your administrator to recover your files." => "Wenn Du Dein altes Passwort vergessen hast, könntest Du Deinen Administrator bitten, Deine Daten wiederherzustellen.", +"Old log-in password" => "Altes Login Passwort", "Current log-in password" => "Aktuelles Passwort", "Update Private Key Password" => "Passwort für den privaten Schlüssel aktualisieren", -"Enable password recovery:" => "Passwortwiederherstellung aktivvieren:", -"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "Wenn Sie diese Option aktivieren, können Sie Ihre verschlüsselten Dateien wiederherstellen, falls Sie Ihr Passwort vergessen", +"Enable password recovery:" => "Passwortwiederherstellung aktivieren:", +"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "Wenn Du diese Option aktivierst, kannst Du Deine verschlüsselten Dateien wiederherstellen, falls Du Dein Passwort vergisst", "File recovery settings updated" => "Einstellungen zur Wiederherstellung von Dateien wurden aktualisiert", "Could not update file recovery" => "Dateiwiederherstellung konnte nicht aktualisiert werden" ); diff --git a/apps/files_encryption/l10n/de_CH.php b/apps/files_encryption/l10n/de_CH.php index aa867645c8d..a31e82a666f 100644 --- a/apps/files_encryption/l10n/de_CH.php +++ b/apps/files_encryption/l10n/de_CH.php @@ -8,13 +8,10 @@ $TRANSLATIONS = array( "Could not change the password. Maybe the old password was not correct." => "Das Passwort konnte nicht geändert werden. Vielleicht war das alte Passwort nicht richtig.", "Private key password successfully updated." => "Das Passwort des privaten Schlüssels wurde erfolgreich aktualisiert.", "Could not update the private key password. Maybe the old password was not correct." => "Das Passwort des privaten Schlüssels konnte nicht aktualisiert werden. Vielleicht war das alte Passwort nicht richtig.", -"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Ihr privater Schlüssel ist ungültig. Möglicher Weise wurde von ausserhalb Ihr Passwort geändert (z.B. in Ihrem gemeinsamen Verzeichnis). Sie können das Passwort Ihres privaten Schlüssels in den persönlichen Einstellungen aktualisieren, um wieder an Ihre Dateien zu gelangen.", "Missing requirements." => "Fehlende Voraussetzungen", "Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Bitte stellen Sie sicher, dass PHP 5.3.3 oder neuer installiert und das OpenSSL zusammen mit der PHP-Erweiterung aktiviert und richtig konfiguriert ist. Zur Zeit ist die Verschlüsselungs-App deaktiviert.", "Following users are not set up for encryption:" => "Für folgende Nutzer ist keine Verschlüsselung eingerichtet:", "Saving..." => "Speichern...", -"Your private key is not valid! Maybe the your password was changed from outside." => "Ihr privater Schlüssel ist ungültig! Vielleicht wurde Ihr Passwort von ausserhalb geändert.", -"You can unlock your private key in your " => "Sie können den privaten Schlüssel ändern und zwar in Ihrem", "personal settings" => "Persönliche Einstellungen", "Encryption" => "Verschlüsselung", "Enable recovery key (allow to recover users files in case of password loss):" => "Aktivieren Sie den Wiederherstellungsschlüssel (erlaubt die Wiederherstellung des Zugangs zu den Benutzerdateien, wenn das Passwort verloren geht).", diff --git a/apps/files_encryption/l10n/de_DE.php b/apps/files_encryption/l10n/de_DE.php index 200001e6ebf..6184fd8a898 100644 --- a/apps/files_encryption/l10n/de_DE.php +++ b/apps/files_encryption/l10n/de_DE.php @@ -8,22 +8,27 @@ $TRANSLATIONS = array( "Could not change the password. Maybe the old password was not correct." => "Das Passwort konnte nicht geändert werden. Vielleicht war das alte Passwort nicht richtig.", "Private key password successfully updated." => "Das Passwort des privaten Schlüssels wurde erfolgreich aktualisiert.", "Could not update the private key password. Maybe the old password was not correct." => "Das Passwort des privaten Schlüssels konnte nicht aktualisiert werden. Vielleicht war das alte Passwort nicht richtig.", -"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Ihr privater Schlüssel ist ungültig. Möglicher Weise wurde von außerhalb Ihr Passwort geändert (z.B. in Ihrem gemeinsamen Verzeichnis). Sie können das Passwort Ihres privaten Schlüssels in den persönlichen Einstellungen aktualisieren, um wieder an Ihre Dateien zu gelangen.", +"Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." => "Verschlüsselung-App ist nicht initialisiert! Vielleicht wurde die Verschlüsselung-App in der aktuellen Sitzung reaktiviert. Bitte versuchen Sie sich ab- und wieder anzumelden, um die Verschlüsselung-App zu initialisieren.", +"Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Ihr privater Schlüssel ist ungültig. Möglicher Weise wurde außerhalb von %s Ihr Passwort geändert (z.B. in Ihrem gemeinsamen Verzeichnis). Sie können das Passwort Ihres privaten Schlüssels in den persönlichen Einstellungen aktualisieren, um wieder an Ihre Dateien zu gelangen.", +"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "Die Datei kann nicht entschlüsselt werden, da die Datei möglicherweise eine geteilte Datei ist. Bitte fragen Sie den Datei-Besitzer, dass er die Datei nochmals mit Ihnen teilt.", +"Unknown error please check your system settings or contact your administrator" => "Unbekannter Fehler, bitte prüfen Sie die Systemeinstellungen oder kontaktieren Sie Ihren Administrator", "Missing requirements." => "Fehlende Voraussetzungen", "Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Bitte stellen Sie sicher, dass PHP 5.3.3 oder neuer installiert und das OpenSSL zusammen mit der PHP-Erweiterung aktiviert und richtig konfiguriert ist. Zur Zeit ist die Verschlüsselungs-App deaktiviert.", "Following users are not set up for encryption:" => "Für folgende Nutzer ist keine Verschlüsselung eingerichtet:", +"Initial encryption started... This can take some time. Please wait." => "Initialverschlüsselung gestartet... Dies kann einige Zeit dauern. Bitte warten.", "Saving..." => "Speichern...", -"Your private key is not valid! Maybe the your password was changed from outside." => "Ihr privater Schlüssel ist ungültig! Vielleicht wurde Ihr Passwort von außerhalb geändert.", -"You can unlock your private key in your " => "Sie können den privaten Schlüssel ändern und zwar in Ihrem", +"Go directly to your " => "Direkt wechseln zu Ihrem", "personal settings" => "Persönliche Einstellungen", "Encryption" => "Verschlüsselung", "Enable recovery key (allow to recover users files in case of password loss):" => "Aktivieren Sie den Wiederherstellungsschlüssel (erlaubt die Wiederherstellung des Zugangs zu den Benutzerdateien, wenn das Passwort verloren geht).", "Recovery key password" => "Wiederherstellungschlüsselpasswort", +"Repeat Recovery key password" => "Schlüssel-Passwort zur Wiederherstellung wiederholen", "Enabled" => "Aktiviert", "Disabled" => "Deaktiviert", "Change recovery key password:" => "Wiederherstellungsschlüsselpasswort ändern", "Old Recovery key password" => "Altes Wiederherstellungsschlüsselpasswort", "New Recovery key password" => "Neues Wiederherstellungsschlüsselpasswort ", +"Repeat New Recovery key password" => "Neues Schlüssel-Passwort zur Wiederherstellung wiederholen", "Change Password" => "Passwort ändern", "Your private key password no longer match your log-in password:" => "Das Privatschlüsselpasswort darf nicht länger mit den Login-Passwort übereinstimmen.", "Set your old private key password to your current log-in password." => "Setzen Sie Ihr altes Privatschlüsselpasswort auf Ihr aktuelles LogIn-Passwort.", diff --git a/apps/files_encryption/l10n/el.php b/apps/files_encryption/l10n/el.php index 70f778f0a50..22c1095e284 100644 --- a/apps/files_encryption/l10n/el.php +++ b/apps/files_encryption/l10n/el.php @@ -1,13 +1,44 @@ <?php $TRANSLATIONS = array( +"Recovery key successfully enabled" => "Επιτυχής ενεργοποίηση κλειδιού ανάκτησης", +"Could not enable recovery key. Please check your recovery key password!" => "Αποτυχία ενεργοποίησης κλειδιού ανάκτησης. Παρακαλώ ελέγξτε τον κωδικό του κλειδιού ανάκτησής σας!", +"Recovery key successfully disabled" => "Επιτυχής απενεργοποίηση κλειδιού ανάκτησης", +"Could not disable recovery key. Please check your recovery key password!" => "Αποτυχία απενεργοποίησης κλειδιού ανάκτησης. Παρακαλώ ελέγξτε τον κωδικό του κλειδιού ανάκτησής σας!", "Password successfully changed." => "Ο κωδικός αλλάχτηκε επιτυχώς.", "Could not change the password. Maybe the old password was not correct." => "Αποτυχία αλλαγής κωδικού ίσως ο παλιός κωδικός να μην ήταν σωστός.", +"Private key password successfully updated." => "Το Προσωπικό κλειδί πρόσβασης ενημερώθηκε επιτυχώς", +"Could not update the private key password. Maybe the old password was not correct." => "Αποτυχία ενημέρωσης του κωδικού για το προσωπικό κλειδί. Ενδεχομένως ο παλιός κωδικός δεν ήταν σωστός.", +"Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." => "Η εφαρμογή κρυπτογράφησης δεν έχει εκκινήσει! Ίσως η εφαρμογή κρυπτογράφησης επανενεργοποιήθηκε κατά τη διάρκεια της τρέχουσας σύνδεσής σας. Παρακαλώ προσπαθήστε να αποσυνδεθείτε και να ξανασυνδεθείτε για να εκκινήσετε την εφαρμογή κρυπτογράφησης.", +"Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Το προσωπικό σας κλειδί δεν είναι έγκυρο! Πιθανόν ο κωδικός σας να άλλαξε έξω από το %s (π.χ. τη λίστα διευθύνσεων της εταιρείας σας). Μπορείτε να ενημερώσετε το προσωπικό σας κλειδί επαναφοράς κωδικού στις προσωπικές σας ρυθμίσεις για να επανακτήσετε πρόσβαση στα κρυπτογραφημένα σας αρχεία.", +"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "Δεν ήταν δυνατό να αποκρυπτογραφηθεί αυτό το αρχείο, πιθανόν πρόκειται για κοινόχρηστο αρχείο. Παρακαλώ ζητήστε από τον ιδιοκτήτη του αρχείου να το ξαναμοιραστεί μαζί σας.", +"Unknown error please check your system settings or contact your administrator" => "Άγνωστο σφάλμα, παρακαλώ ελέγξτε τις ρυθμίσεις συστήματος ή επικοινωνήστε με τον διαχειριστή σας ", +"Missing requirements." => "Προαπαιτούμενα που απουσιάζουν.", +"Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Παρακαλώ επιβεβαιώστε ότι η PHP 5.3.3 ή νεότερη είναι εγκατεστημένη και ότι το OpenSSL μαζί με το PHP extension είναι ενεργοποιήμένο και έχει ρυθμιστεί σωστά. Προς το παρόν, η εφαρμογή κρυπτογράφησης είναι απενεργοποιημένη.", +"Following users are not set up for encryption:" => "Οι κάτωθι χρήστες δεν έχουν ρυθμιστεί για κρυπογράφηση:", +"Initial encryption started... This can take some time. Please wait." => "Η αρχική κρυπτογράφηση άρχισε... Αυτό μπορεί να πάρει κάποια ώρα. Παρακαλώ περιμένετε.", "Saving..." => "Γίνεται αποθήκευση...", +"Go directly to your " => "Πηγαίνε απευθείας στο ", "personal settings" => "προσωπικές ρυθμίσεις", "Encryption" => "Κρυπτογράφηση", +"Enable recovery key (allow to recover users files in case of password loss):" => "Ενεργοποίηση κλειδιού ανάκτησης (επιτρέψτε την ανάκτηση αρχείων χρηστών σε περίπτωση απώλειας κωδικού):", +"Recovery key password" => "Επαναφορά κωδικού κλειδιού", +"Repeat Recovery key password" => "Επαναλάβετε το κλειδί επαναφοράς κωδικού", "Enabled" => "Ενεργοποιημένο", "Disabled" => "Απενεργοποιημένο", +"Change recovery key password:" => "Αλλαγή κλειδιού επαναφοράς κωδικού:", +"Old Recovery key password" => "Παλιό κλειδί επαναφοράς κωδικού", +"New Recovery key password" => "Νέο κλειδί επαναφοράς κωδικού", +"Repeat New Recovery key password" => "Επαναλάβετε νέο κλειδί επαναφοράς κωδικού", "Change Password" => "Αλλαγή Κωδικού Πρόσβασης", -"File recovery settings updated" => "Οι ρυθμίσεις επαναφοράς αρχείων ανανεώθηκαν" +"Your private key password no longer match your log-in password:" => "Ο κωδικός του προσωπικού κλειδιού δεν ταιριάζει πλέον με τον κωδικό σύνδεσής σας:", +"Set your old private key password to your current log-in password." => "Ορίστε το παλιό σας προσωπικό κλειδί ως τον τρέχων κωδικό πρόσβασης.", +" If you don't remember your old password you can ask your administrator to recover your files." => "Εάν δεν θυμάστε τον παλιό σας κωδικό μπορείτε να ζητήσετε από τον διαχειριστή σας να επανακτήσει τα αρχεία σας.", +"Old log-in password" => "Παλαιό συνθηματικό εισόδου", +"Current log-in password" => "Τρέχον συνθηματικό πρόσβασης", +"Update Private Key Password" => "Ενημέρωση Προσωπικού Κλειδού Πρόσβασης", +"Enable password recovery:" => "Ενεργοποιήστε την ανάκτηση κωδικού πρόσβασης", +"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "Η ενεργοποίηση αυτής της επιλογής θα σας επιτρέψει να επανακτήσετε πρόσβαση στα κρυπτογραφημένα σας αρχεία σε περίπτωση απώλειας του κωδικού σας", +"File recovery settings updated" => "Οι ρυθμίσεις επαναφοράς αρχείων ανανεώθηκαν", +"Could not update file recovery" => "Αποτυχία ενημέρωσης ανάκτησης αρχείων" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_encryption/l10n/en_GB.php b/apps/files_encryption/l10n/en_GB.php index c220a4bdf04..55d56b9533e 100644 --- a/apps/files_encryption/l10n/en_GB.php +++ b/apps/files_encryption/l10n/en_GB.php @@ -8,24 +8,29 @@ $TRANSLATIONS = array( "Could not change the password. Maybe the old password was not correct." => "Could not change the password. Maybe the old password was incorrect.", "Private key password successfully updated." => "Private key password updated successfully.", "Could not update the private key password. Maybe the old password was not correct." => "Could not update the private key password. Maybe the old password was not correct.", -"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files.", +"Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." => "Encryption app not initialised! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialise the encryption app.", +"Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files.", +"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "Cannot decrypt this file, which is probably a shared file. Please ask the file owner to reshare the file with you.", +"Unknown error please check your system settings or contact your administrator" => "Unknown error. Please check your system settings or contact your administrator", "Missing requirements." => "Missing requirements.", "Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled.", "Following users are not set up for encryption:" => "Following users are not set up for encryption:", +"Initial encryption started... This can take some time. Please wait." => "Initial encryption started... This can take some time. Please wait.", "Saving..." => "Saving...", -"Your private key is not valid! Maybe the your password was changed from outside." => "Your private key is not valid! Maybe the your password was changed externally.", -"You can unlock your private key in your " => "You can unlock your private key in your ", +"Go directly to your " => "Go directly to your ", "personal settings" => "personal settings", "Encryption" => "Encryption", "Enable recovery key (allow to recover users files in case of password loss):" => "Enable recovery key (allow to recover users files in case of password loss):", "Recovery key password" => "Recovery key password", +"Repeat Recovery key password" => "Repeat recovery key password", "Enabled" => "Enabled", "Disabled" => "Disabled", "Change recovery key password:" => "Change recovery key password:", -"Old Recovery key password" => "Old Recovery key password", -"New Recovery key password" => "New Recovery key password", +"Old Recovery key password" => "Old recovery key password", +"New Recovery key password" => "New recovery key password", +"Repeat New Recovery key password" => "Repeat new recovery key password", "Change Password" => "Change Password", -"Your private key password no longer match your log-in password:" => "Your private key password no longer match your login password:", +"Your private key password no longer match your log-in password:" => "Your private key password no longer matches your login password:", "Set your old private key password to your current log-in password." => "Set your old private key password to your current login password.", " If you don't remember your old password you can ask your administrator to recover your files." => " If you don't remember your old password you can ask your administrator to recover your files.", "Old log-in password" => "Old login password", diff --git a/apps/files_encryption/l10n/eo.php b/apps/files_encryption/l10n/eo.php index d6881253022..e14c7cd7ac9 100644 --- a/apps/files_encryption/l10n/eo.php +++ b/apps/files_encryption/l10n/eo.php @@ -3,7 +3,9 @@ $TRANSLATIONS = array( "Password successfully changed." => "La pasvorto sukcese ŝanĝiĝis.", "Could not change the password. Maybe the old password was not correct." => "Ne eblis ŝanĝi la pasvorton. Eble la malnova pasvorto malĝustis.", "Private key password successfully updated." => "La pasvorto de la malpublika klavo sukcese ĝisdatiĝis.", +"Missing requirements." => "Mankas neproj.", "Saving..." => "Konservante...", +"Go directly to your " => "Iri direkte al via", "personal settings" => "persona agordo", "Encryption" => "Ĉifrado", "Enabled" => "Kapabligita", diff --git a/apps/files_encryption/l10n/es.php b/apps/files_encryption/l10n/es.php index 2d644708c59..53453986883 100644 --- a/apps/files_encryption/l10n/es.php +++ b/apps/files_encryption/l10n/es.php @@ -8,22 +8,27 @@ $TRANSLATIONS = array( "Could not change the password. Maybe the old password was not correct." => "No se pudo cambiar la contraseña. Compruebe que la contraseña actual sea correcta.", "Private key password successfully updated." => "Contraseña de clave privada actualizada con éxito.", "Could not update the private key password. Maybe the old password was not correct." => "No se pudo cambiar la contraseña. Puede que la contraseña antigua no sea correcta.", -"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "¡Su clave privada no es válida! Tal vez su contraseña ha sido cambiada desde fuera. Puede actualizar su clave privada en sus opciones personales para recuperar el acceso a sus ficheros.", +"Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." => "¡La aplicación de cifrado no ha sido inicializada! Quizá fue restablecida durante tu sesión. Por favor intenta cerrar la sesión y volver a iniciarla para inicializar la aplicación de cifrado.", +"Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "¡Su clave privada no es válida! Tal vez su contraseña ha sido cambiada desde fuera. de %s (Ej:Su directorio corporativo). Puede actualizar la contraseña de su clave privada en sus opciones personales para recuperar el acceso a sus archivos.", +"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "No fue posible descifrar este archivo, probablemente se trate de un archivo compartido. Solicite al propietario del mismo que vuelva a compartirlo con usted.", +"Unknown error please check your system settings or contact your administrator" => "Error desconocido. Verifique la configuración de su sistema o póngase en contacto con su administrador", "Missing requirements." => "Requisitos incompletos.", "Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Por favor, asegúrese de que PHP 5.3.3 o posterior está instalado y que la extensión OpenSSL de PHP está habilitada y configurada correctamente. Por el momento, la aplicación de cifrado ha sido deshabilitada.", "Following users are not set up for encryption:" => "Los siguientes usuarios no han sido configurados para el cifrado:", +"Initial encryption started... This can take some time. Please wait." => "Encriptación iniciada..... Esto puede tomar un tiempo. Por favor espere.", "Saving..." => "Guardando...", -"Your private key is not valid! Maybe the your password was changed from outside." => "¡Su clave privada no es válida! Tal vez su contraseña ha sido cambiada desde fuera.", -"You can unlock your private key in your " => "Puede desbloquear su clave privada en su", +"Go directly to your " => "Ir directamente a su", "personal settings" => "opciones personales", "Encryption" => "Cifrado", "Enable recovery key (allow to recover users files in case of password loss):" => "Habilitar la clave de recuperación (permite recuperar los ficheros del usuario en caso de pérdida de la contraseña);", "Recovery key password" => "Contraseña de clave de recuperación", +"Repeat Recovery key password" => "Repite la contraseña de clave de recuperación", "Enabled" => "Habilitar", "Disabled" => "Deshabilitado", "Change recovery key password:" => "Cambiar la contraseña de la clave de recuperación", "Old Recovery key password" => "Antigua clave de recuperación", "New Recovery key password" => "Nueva clave de recuperación", +"Repeat New Recovery key password" => "Repetir la nueva clave de recuperación", "Change Password" => "Cambiar contraseña", "Your private key password no longer match your log-in password:" => "Su contraseña de clave privada ya no coincide con su contraseña de acceso:", "Set your old private key password to your current log-in password." => "Establecer la contraseña de su antigua clave privada a su contraseña actual de acceso.", diff --git a/apps/files_encryption/l10n/es_AR.php b/apps/files_encryption/l10n/es_AR.php index 666ea59687c..df5bd649d67 100644 --- a/apps/files_encryption/l10n/es_AR.php +++ b/apps/files_encryption/l10n/es_AR.php @@ -8,13 +8,10 @@ $TRANSLATIONS = array( "Could not change the password. Maybe the old password was not correct." => "No se pudo cambiar la contraseña. Comprobá que la contraseña actual sea correcta.", "Private key password successfully updated." => "Contraseña de clave privada actualizada con éxito.", "Could not update the private key password. Maybe the old password was not correct." => "No fue posible actualizar la contraseña de clave privada. Tal vez la contraseña anterior no es correcta.", -"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "¡Tu clave privada no es válida! Tal vez tu contraseña fue cambiada desde fuera del sistema de ownCloud (por ej. desde tu cuenta de sistema). Podés actualizar tu clave privada en la sección de \"configuración personal\", para recuperar el acceso a tus archivos.", "Missing requirements." => "Requisitos incompletos.", "Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Por favor, asegúrese de que PHP 5.3.3 o una versión más reciente esté instalado y que OpenSSL junto con la extensión PHP esté habilitado y configurado apropiadamente. Por ahora, la aplicación de encriptación ha sido deshabilitada.", "Following users are not set up for encryption:" => "Los siguientes usuarios no fueron configurados para encriptar:", "Saving..." => "Guardando...", -"Your private key is not valid! Maybe the your password was changed from outside." => "¡Tu clave privada no es válida! Tal vez tu contraseña fue cambiada desde afuera.", -"You can unlock your private key in your " => "Podés desbloquear tu clave privada en tu", "personal settings" => "Configuración personal", "Encryption" => "Encriptación", "Enable recovery key (allow to recover users files in case of password loss):" => "Habilitar clave de recuperación (te permite recuperar los archivos de usuario en el caso que pierdas la contraseña):", diff --git a/apps/files_encryption/l10n/es_MX.php b/apps/files_encryption/l10n/es_MX.php new file mode 100644 index 00000000000..3906e3cacbe --- /dev/null +++ b/apps/files_encryption/l10n/es_MX.php @@ -0,0 +1,44 @@ +<?php +$TRANSLATIONS = array( +"Recovery key successfully enabled" => "Se ha habilitado la recuperación de archivos", +"Could not enable recovery key. Please check your recovery key password!" => "No se pudo habilitar la clave de recuperación. Por favor compruebe su contraseña.", +"Recovery key successfully disabled" => "Clave de recuperación deshabilitada", +"Could not disable recovery key. Please check your recovery key password!" => "No se pudo deshabilitar la clave de recuperación. Por favor compruebe su contraseña!", +"Password successfully changed." => "Su contraseña ha sido cambiada", +"Could not change the password. Maybe the old password was not correct." => "No se pudo cambiar la contraseña. Compruebe que la contraseña actual sea correcta.", +"Private key password successfully updated." => "Contraseña de clave privada actualizada con éxito.", +"Could not update the private key password. Maybe the old password was not correct." => "No se pudo cambiar la contraseña. Puede que la contraseña antigua no sea correcta.", +"Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." => "¡La aplicación de cifrado no ha sido inicializada! Quizá fue restablecida durante tu sesión. Por favor intenta cerrar la sesión y volver a iniciarla para inicializar la aplicación de cifrado.", +"Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "¡Su clave privada no es válida! Tal vez su contraseña ha sido cambiada desde fuera. de %s (Ej:Su directorio corporativo). Puede actualizar la contraseña de su clave privada en sus opciones personales para recuperar el acceso a sus archivos.", +"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "No fue posible descifrar este archivo, probablemente se trate de un archivo compartido. Solicite al propietario del mismo que vuelva a compartirlo con usted.", +"Unknown error please check your system settings or contact your administrator" => "Error desconocido. Verifique la configuración de su sistema o póngase en contacto con su administrador", +"Missing requirements." => "Requisitos incompletos.", +"Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Por favor, asegúrese de que PHP 5.3.3 o posterior está instalado y que la extensión OpenSSL de PHP está habilitada y configurada correctamente. Por el momento, la aplicación de cifrado ha sido deshabilitada.", +"Following users are not set up for encryption:" => "Los siguientes usuarios no han sido configurados para el cifrado:", +"Initial encryption started... This can take some time. Please wait." => "Encriptación iniciada... Esto puede tomar un tiempo. Por favor espere.", +"Saving..." => "Guardando...", +"Go directly to your " => "Ir directamente a su", +"personal settings" => "opciones personales", +"Encryption" => "Cifrado", +"Enable recovery key (allow to recover users files in case of password loss):" => "Habilitar la clave de recuperación (permite recuperar los archivos del usuario en caso de pérdida de la contraseña);", +"Recovery key password" => "Contraseña de clave de recuperación", +"Repeat Recovery key password" => "Repite la contraseña de clave de recuperación", +"Enabled" => "Habilitar", +"Disabled" => "Deshabilitado", +"Change recovery key password:" => "Cambiar la contraseña de la clave de recuperación", +"Old Recovery key password" => "Antigua clave de recuperación", +"New Recovery key password" => "Nueva clave de recuperación", +"Repeat New Recovery key password" => "Repetir la nueva clave de recuperación", +"Change Password" => "Cambiar contraseña", +"Your private key password no longer match your log-in password:" => "Su contraseña de clave privada ya no coincide con su contraseña de acceso:", +"Set your old private key password to your current log-in password." => "Establecer la contraseña de su antigua clave privada a su contraseña actual de acceso.", +" If you don't remember your old password you can ask your administrator to recover your files." => "Si no recuerda su antigua contraseña puede pedir a su administrador que le recupere sus archivos.", +"Old log-in password" => "Contraseña de acceso antigua", +"Current log-in password" => "Contraseña de acceso actual", +"Update Private Key Password" => "Actualizar Contraseña de Clave Privada", +"Enable password recovery:" => "Habilitar la recuperación de contraseña:", +"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "Habilitar esta opción le permitirá volver a tener acceso a sus archivos cifrados en caso de pérdida de contraseña", +"File recovery settings updated" => "Opciones de recuperación de archivos actualizada", +"Could not update file recovery" => "No se pudo actualizar la recuperación de archivos" +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_encryption/l10n/et_EE.php b/apps/files_encryption/l10n/et_EE.php index 3edb7299c20..9182c5ef196 100644 --- a/apps/files_encryption/l10n/et_EE.php +++ b/apps/files_encryption/l10n/et_EE.php @@ -8,22 +8,27 @@ $TRANSLATIONS = array( "Could not change the password. Maybe the old password was not correct." => "Ei suutnud vahetada parooli. Võib-olla on vana parool valesti sisestatud.", "Private key password successfully updated." => "Privaatse võtme parool edukalt uuendatud.", "Could not update the private key password. Maybe the old password was not correct." => "Ei suutnud uuendada privaatse võtme parooli. Võib-olla polnud vana parool õige.", -"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Sinu privaatne võti pole toimiv! Tõenäoliselt on sinu parool muutunud väljaspool ownCloud süsteemi (näiteks ettevõtte keskhaldus). Sa saad uuendada oma privaatse võtme parooli seadete all taastamaks ligipääsu oma krüpteeritud failidele.", +"Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." => "Krüpteerimise rakend pole käivitatud. Võib-olla krüpteerimise rakend taaskäivitati sinu sessiooni kestel. Palun proovi logida välja ning uuesti sisse käivitamaks krüpteerimise rakendit.", +"Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Sinu provaatne võti pole kehtiv! Tõenäoliselt mudueti parooli väljaspool kausta %s (nt. sinu ettevõtte kaust). Sa saad uuendada oma privaatse võtme parooli oma isiklikes seadetes, et taastada ligipääs sinu krüpteeritud failidele.", +"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "Sa ei saa seda faili dekrüpteerida, see on tõenäoliselt jagatud fail. Palun lase omanikul seda faili sinuga uuesti jagada.", +"Unknown error please check your system settings or contact your administrator" => "Tundmatu tõrge. Palun kontrolli süsteemi seadeid või võta ühendust oma süsteemi administraatoriga", "Missing requirements." => "Nõutavad on puudu.", "Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Palun veendu, et on paigaldatud PHP 5.3.3 või uuem ning PHP OpenSSL laiendus on lubatud ning seadistatud korrektselt. Hetkel krüpteerimise rakendus on peatatud.", "Following users are not set up for encryption:" => "Järgmised kasutajad pole seadistatud krüpteeringuks:", +"Initial encryption started... This can take some time. Please wait." => "Algne krüpteerimine käivitati... See võib võtta natuke aega. Palun oota.", "Saving..." => "Salvestamine...", -"Your private key is not valid! Maybe the your password was changed from outside." => "Sinu privaatne võti ei ole õige. Võib-olla on parool vahetatud süsteemi väliselt.", -"You can unlock your private key in your " => "Saad avada oma privaatse võtme oma", +"Go directly to your " => "Liigu otse oma", "personal settings" => "isiklikes seadetes", "Encryption" => "Krüpteerimine", -"Enable recovery key (allow to recover users files in case of password loss):" => "Luba taastevõti (võimada kasutaja failide taastamine parooli kaotuse puhul):", +"Enable recovery key (allow to recover users files in case of password loss):" => "Luba taastevõti (võimalda kasutaja failide taastamine parooli kaotuse puhul):", "Recovery key password" => "Taastevõtme parool", +"Repeat Recovery key password" => "Korda taastevõtme parooli", "Enabled" => "Sisse lülitatud", "Disabled" => "Väljalülitatud", "Change recovery key password:" => "Muuda taastevõtme parooli:", "Old Recovery key password" => "Vana taastevõtme parool", "New Recovery key password" => "Uus taastevõtme parool", +"Repeat New Recovery key password" => "Korda uut taastevõtme parooli", "Change Password" => "Muuda parooli", "Your private key password no longer match your log-in password:" => "Sinu privaatse võtme parool ei ühti enam sinu sisselogimise parooliga:", "Set your old private key password to your current log-in password." => "Pane oma vana privaatvõtme parooliks oma praegune sisselogimise parool.", diff --git a/apps/files_encryption/l10n/eu.php b/apps/files_encryption/l10n/eu.php index e750c850688..6b1bafdda1a 100644 --- a/apps/files_encryption/l10n/eu.php +++ b/apps/files_encryption/l10n/eu.php @@ -8,20 +8,27 @@ $TRANSLATIONS = array( "Could not change the password. Maybe the old password was not correct." => "Ezin izan da pasahitza aldatu. Agian pasahitz zaharra okerrekoa da.", "Private key password successfully updated." => "Gako pasahitz pribatu behar bezala eguneratu da.", "Could not update the private key password. Maybe the old password was not correct." => "Ezin izan da gako pribatu pasahitza eguneratu. Agian pasahitz zaharra okerrekoa da.", -"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Zure gako pribatua ez da egokia! Seguruaski zure pasahitza ownCloud sistematik kanpo aldatu da (adb. zure direktorio korporatiboa). Zure gako pribatuaren pasahitza eguneratu dezakezu zure ezarpen pertsonaletan zure enkriptatutako fitxategiak berreskuratzeko.", +"Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." => "Enkriptazio aplikazioa ez dago hasieratuta! Agian aplikazioa birgaitu egin da zure saioa bitartean. Mesdez atear eta sartu berriz enkriptazio aplikazioa hasierarazteko.", +"Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Zure gako pribatua ez da egokia! Seguruaski zure pasahitza %s-tik kanpo aldatu da (adb. zure direktorio korporatiboa). Zure gako pribatuaren pasahitza eguneratu dezakezu zure ezarpen pertsonaletan zure enkriptatutako fitxategiak berreskuratzeko.", +"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "Ezin izan da fitxategi hau deszifratu, ziurrenik elkarbanatutako fitxategi bat da. Mesdez, eskatu fitxategiaren jabeari fitxategia zurekin berriz elkarbana dezan.", +"Unknown error please check your system settings or contact your administrator" => "Errore ezezaguna mesedez egiaztatu zure sistemaren ezarpenak edo harremanetan jarri zure administradorearekin", "Missing requirements." => "Eskakizun batzuk ez dira betetzen.", +"Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Mesedez ziurtatu PHP 5.3.3 edo berriago bat instalatuta dagoela eta OpenSSL PHP hedapenarekin gaitua eta ongi konfiguratuta dagoela. Oraingoz, enkriptazio aplikazioa desgaituta dago.", +"Following users are not set up for encryption:" => "Hurrengo erabiltzaileak ez daude enktriptatzeko konfiguratutak:", +"Initial encryption started... This can take some time. Please wait." => "Hasierako enkriptazioa hasi da... Honek denbora har dezake. Mesedez itxaron.", "Saving..." => "Gordetzen...", -"Your private key is not valid! Maybe the your password was changed from outside." => "Zure gako pribatua ez da egokia! Agian zure pasahitza kanpotik aldatu da.", -"You can unlock your private key in your " => "Zure gako pribatua desblokeatu dezakezu zure", +"Go directly to your " => "Joan zuzenean zure", "personal settings" => "ezarpen pertsonalak", "Encryption" => "Enkriptazioa", "Enable recovery key (allow to recover users files in case of password loss):" => "Gaitu berreskurapen gakoa (erabiltzaileen fitxategiak berreskuratzea ahalbidetzen du pasahitza galtzen badute ere):", "Recovery key password" => "Berreskuratze gako pasahitza", +"Repeat Recovery key password" => "Errepikatu berreskuratze gakoaren pasahitza", "Enabled" => "Gaitua", "Disabled" => "Ez-gaitua", "Change recovery key password:" => "Aldatu berreskuratze gako pasahitza:", "Old Recovery key password" => "Berreskuratze gako pasahitz zaharra", "New Recovery key password" => "Berreskuratze gako pasahitz berria", +"Repeat New Recovery key password" => "Errepikatu berreskuratze gako berriaren pasahitza", "Change Password" => "Aldatu Pasahitza", "Your private key password no longer match your log-in password:" => "Zure gako pribatuaren pasahitza ez da dagoeneko zure sarrera pasahitza:", "Set your old private key password to your current log-in password." => "Ezarri zure gako pribatu zaharraren pasahitza zure oraingo sarrerako psahitzara.", diff --git a/apps/files_encryption/l10n/fa.php b/apps/files_encryption/l10n/fa.php index 461ec2b92cb..ed044a4158e 100644 --- a/apps/files_encryption/l10n/fa.php +++ b/apps/files_encryption/l10n/fa.php @@ -8,11 +8,8 @@ $TRANSLATIONS = array( "Could not change the password. Maybe the old password was not correct." => "رمزعبور را نمیتواند تغییر دهد. شاید رمزعبورقدیمی صحیح نمی باشد.", "Private key password successfully updated." => "رمزعبور کلید خصوصی با موفقیت به روز شد.", "Could not update the private key password. Maybe the old password was not correct." => "رمزعبور کلید خصوصی را نمی تواند به روز کند. شاید رمزعبور قدیمی صحیح نمی باشد.", -"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "کلید خصوصی شما معتبر نمی باشد! ظاهرا رمزعبور شما بیرون از سیستم ownCloud تغییر یافته است( به عنوان مثال پوشه سازمان شما ). شما میتوانید رمزعبور کلید خصوصی خود را در تنظیمات شخصیتان به روز کنید تا بتوانید به فایل های رمزگذاری شده خود را دسترسی داشته باشید.", "Missing requirements." => "نیازمندی های گمشده", "Saving..." => "در حال ذخیره سازی...", -"Your private key is not valid! Maybe the your password was changed from outside." => "کلید خصوصی شما معتبر نیست! شاید رمزعبوراز بیرون تغییر یافته است.", -"You can unlock your private key in your " => "شما میتوانید کلید خصوصی خود را باز نمایید.", "personal settings" => "تنظیمات شخصی", "Encryption" => "رمزگذاری", "Enable recovery key (allow to recover users files in case of password loss):" => "فعال کردن کلید بازیابی(اجازه بازیابی فایل های کاربران در صورت از دست دادن رمزعبور):", diff --git a/apps/files_encryption/l10n/fr.php b/apps/files_encryption/l10n/fr.php index 358937441e2..dbccbf74dcd 100644 --- a/apps/files_encryption/l10n/fr.php +++ b/apps/files_encryption/l10n/fr.php @@ -8,22 +8,27 @@ $TRANSLATIONS = array( "Could not change the password. Maybe the old password was not correct." => "Ne peut pas changer le mot de passe. L'ancien mot de passe est peut-être incorrect.", "Private key password successfully updated." => "Mot de passe de la clé privé mis à jour avec succès.", "Could not update the private key password. Maybe the old password was not correct." => "Impossible de mettre à jour le mot de passe de la clé privé. Peut-être que l'ancien mot de passe n'était pas correcte.", -"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Votre clé de sécurité privée n'est pas valide! Il est probable que votre mot de passe ait été changé sans passer par le système ownCloud (par éxemple: le serveur de votre entreprise). Ain d'avoir à nouveau accès à vos fichiers cryptés, vous pouvez mettre à jour votre clé de sécurité privée dans les paramètres personnels de votre compte.", +"Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." => "L'application de chiffrement n'est pas initialisée ! Peut-être que cette application a été réactivée pendant votre session. Veuillez essayer de vous déconnecter et ensuite de vous reconnecter pour initialiser l'application de chiffrement.", +"Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Votre clef privée est invalide ! Votre mot de passe a probablement été modifié hors de %s (ex. votre annuaire d'entreprise). Vous pouvez mettre à jour le mot de passe de votre clef privée dans les paramètres personnels pour pouvoir récupérer l'accès à vos fichiers chiffrés.", +"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "Impossible de déchiffrer ce fichier, il s'agit probablement d'un fichier partagé. Veuillez demander au propriétaire de ce fichier de le repartager avec vous.", +"Unknown error please check your system settings or contact your administrator" => "Erreur inconnue. Veuillez vérifier vos paramètres système ou contacter votre administrateur.", "Missing requirements." => "Système minimum requis non respecté.", "Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Veuillez vous assurer qu'une version de PHP 5.3.3 ou supérieure est installée et qu'OpenSSL et son extension PHP sont activés et configurés correctement. En attendant, l'application de chiffrement été désactivée.", "Following users are not set up for encryption:" => "Les utilisateurs suivants ne sont pas configurés pour le chiffrement :", +"Initial encryption started... This can take some time. Please wait." => "Chiffrement initial démarré... Cela peut prendre un certain temps. Veuillez patienter.", "Saving..." => "Enregistrement...", -"Your private key is not valid! Maybe the your password was changed from outside." => "Votre clef privée est invalide ! Votre mot de passe a peut-être été modifié depuis l'extérieur.", -"You can unlock your private key in your " => "Vous pouvez déverrouiller votre clé privée dans votre", +"Go directly to your " => "Allez directement à votre", "personal settings" => "paramètres personnel", "Encryption" => "Chiffrement", "Enable recovery key (allow to recover users files in case of password loss):" => "Activer la clef de récupération (permet de récupérer les fichiers des utilisateurs en cas de perte de mot de passe).", "Recovery key password" => "Mot de passe de la clef de récupération", +"Repeat Recovery key password" => "Répétez le mot de passe de la clé de récupération", "Enabled" => "Activer", "Disabled" => "Désactiver", "Change recovery key password:" => "Modifier le mot de passe de la clef de récupération :", "Old Recovery key password" => "Ancien mot de passe de la clef de récupération", "New Recovery key password" => "Nouveau mot de passe de la clef de récupération", +"Repeat New Recovery key password" => "Répétez le nouveau mot de passe de la clé de récupération", "Change Password" => "Changer de mot de passe", "Your private key password no longer match your log-in password:" => "Le mot de passe de votre clef privée ne correspond plus à votre mot de passe de connexion :", "Set your old private key password to your current log-in password." => "Configurez le mot de passe de votre ancienne clef privée avec votre mot de passe courant de connexion. ", diff --git a/apps/files_encryption/l10n/gl.php b/apps/files_encryption/l10n/gl.php index abf12d73d57..7b3c899d1f5 100644 --- a/apps/files_encryption/l10n/gl.php +++ b/apps/files_encryption/l10n/gl.php @@ -8,22 +8,27 @@ $TRANSLATIONS = array( "Could not change the password. Maybe the old password was not correct." => "Non foi posíbel cambiar o contrasinal. Probabelmente o contrasinal antigo non é o correcto.", "Private key password successfully updated." => "A chave privada foi actualizada correctamente.", "Could not update the private key password. Maybe the old password was not correct." => "Non foi posíbel actualizar o contrasinal da chave privada. É probábel que o contrasinal antigo non sexa correcto.", -"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "A chave privada non é correcta! É probábel que o seu contrasinal teña sido cambiado desde o exterior (p.ex. o seu directorio corporativo). Vostede pode actualizar o contrasinal da súa chave privada nos seus axustes persoais para recuperar o acceso aos seus ficheiros", +"Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." => "Non se iniciou o aplicativo de cifrado! Quizais volva a activarse durante a sesión. Tente pechar a sesión e volver iniciala que tamén se inicie o aplicativo de cifrado.", +"Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "A chave privada non é correcta! É probábel que o seu contrasinal teña sido cambiado desde o exterior do %s (p.ex. o seu directorio corporativo). Vostede pode actualizar o contrasinal da súa chave privada nos seus axustes persoais para recuperar o acceso aos seus ficheiros", +"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "Non foi posíbel descifrar o ficheiro, probabelmente tratase dun ficheiro compartido. Pidalle ao propietario do ficheiro que volva compartir o ficheiro con vostede.", +"Unknown error please check your system settings or contact your administrator" => "Produciuse un erro descoñecido. Comprobe os axustes do sistema ou póñase en contacto co administrador", "Missing requirements." => "Non se cumpren os requisitos.", "Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Asegúrese de que está instalado o PHP 5.3.3 ou posterior e de o OpenSSL xunto coa extensión PHP estean activados e configurados correctamente. Polo de agora foi desactivado o aplicativo de cifrado.", "Following users are not set up for encryption:" => "Os seguintes usuarios non teñen configuración para o cifrado:", +"Initial encryption started... This can take some time. Please wait." => "Comezou o cifrado inicial... Isto pode levar bastante tempo. Agarde.", "Saving..." => "Gardando...", -"Your private key is not valid! Maybe the your password was changed from outside." => "A chave privada non é correcta! É probábel que o seu contrasinal teña sido cambiado desde o exterior. ", -"You can unlock your private key in your " => "Pode desbloquear a chave privada nos seus", +"Go directly to your " => "Vaia directamente ao seu", "personal settings" => "axustes persoais", "Encryption" => "Cifrado", "Enable recovery key (allow to recover users files in case of password loss):" => "Activar a chave de recuperación (permitirá recuperar os ficheiros dos usuarios no caso de perda do contrasinal):", "Recovery key password" => "Contrasinal da chave de recuperación", +"Repeat Recovery key password" => "Repita o contrasinal da chave da recuperación", "Enabled" => "Activado", "Disabled" => "Desactivado", "Change recovery key password:" => "Cambiar o contrasinal da chave de la recuperación:", "Old Recovery key password" => "Antigo contrasinal da chave de recuperación", "New Recovery key password" => "Novo contrasinal da chave de recuperación", +"Repeat New Recovery key password" => "Repita o novo contrasinal da chave da recuperación", "Change Password" => "Cambiar o contrasinal", "Your private key password no longer match your log-in password:" => "O seu contrasinal da chave privada non coincide co seu contrasinal de acceso.", "Set your old private key password to your current log-in password." => "Estabeleza o seu contrasinal antigo da chave de recuperación ao seu contrasinal de acceso actual", diff --git a/apps/files_encryption/l10n/hu_HU.php b/apps/files_encryption/l10n/hu_HU.php index 323291bbfbe..163011ff80b 100644 --- a/apps/files_encryption/l10n/hu_HU.php +++ b/apps/files_encryption/l10n/hu_HU.php @@ -1,18 +1,44 @@ <?php $TRANSLATIONS = array( -"Recovery key successfully disabled" => "Visszaállítási kulcs sikeresen kikapcsolva", -"Password successfully changed." => "Jelszó sikeresen megváltoztatva.", +"Recovery key successfully enabled" => "A helyreállítási kulcs sikeresen bekapcsolva", +"Could not enable recovery key. Please check your recovery key password!" => "A helyreállítási kulcsot nem lehetett engedélyezni. Ellenőrizze a helyreállítási kulcsa jelszavát!", +"Recovery key successfully disabled" => "A helyreállítási kulcs sikeresen kikapcsolva", +"Could not disable recovery key. Please check your recovery key password!" => "A helyreállítási kulcsot nem lehetett kikapcsolni. Ellenőrizze a helyreállítási kulcsa jelszavát!", +"Password successfully changed." => "A jelszót sikeresen megváltoztattuk.", "Could not change the password. Maybe the old password was not correct." => "A jelszót nem lehet megváltoztatni! Lehet, hogy hibás volt a régi jelszó.", -"Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Kérlek győződj meg arról, hogy PHP 5.3.3 vagy annál frissebb van telepítve, valamint a PHP-hez tartozó OpenSSL bővítmény be van-e kapcsolva és az helyesen van-e konfigurálva! Ki lett kapcsolva ideiglenesen a titkosító alkalmazás.", +"Private key password successfully updated." => "A személyes kulcsának jelszava frissítésre került.", +"Could not update the private key password. Maybe the old password was not correct." => "A személyes kulcsa jelszavát nem lehetett frissíteni. Lehet, hogy hibás volt a régi jelszó.", +"Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." => "A titkosítási modul nincs elindítva! Talán a munkafolyamat közben került engedélyezésre. Kérjük jelentkezzen ki majd ismét jelentkezzen be, hogy a titkosítási modul megfelelően elinduljon!", +"Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Az állományok titkosításához használt titkos kulcsa érvénytelen. Valószínűleg a %s rendszeren kívül változtatta meg a jelszavát (pl. a munkahelyi címtárban). A személyes beállításoknál frissítheti a titkos kulcsát, hogy ismét elérhesse a titkosított állományait.", +"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "Az állományt nem sikerült dekódolni, valószínűleg ez egy megosztott fájl. Kérje meg az állomány tulajdonosát, hogy újra ossza meg Önnel ezt az állományt!", +"Unknown error please check your system settings or contact your administrator" => "Ismeretlen hiba. Ellenőrizze a rendszer beállításait vagy forduljon a rendszergazdához!", +"Missing requirements." => "Hiányzó követelmények.", +"Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Kérem gondoskodjon arról, hogy PHP 5.3.3 vagy annál frissebb legyen telepítve, továbbá az OpenSSL a megfelelő PHP-bővítménnyel együtt rendelkezésre álljon és helyesen legyen konfigurálva! A titkosító modul egyelőre kikapcsolásra került.", +"Following users are not set up for encryption:" => "A következő felhasználók nem állították be a titkosítást:", +"Initial encryption started... This can take some time. Please wait." => "A titkosítási folyamat megkezdődött... Ez hosszabb ideig is eltarthat. Kérem várjon.", "Saving..." => "Mentés...", +"Go directly to your " => "Ugrás ide:", "personal settings" => "személyes beállítások", "Encryption" => "Titkosítás", +"Enable recovery key (allow to recover users files in case of password loss):" => "A helyreállítási kulcs beállítása (lehetővé teszi a felhasználók állományainak visszaállítását, ha elfelejtik a jelszavukat):", +"Recovery key password" => "A helyreállítási kulcs jelszava", +"Repeat Recovery key password" => "Ismételje meg a helyreállítási kulcs jelszavát", "Enabled" => "Bekapcsolva", "Disabled" => "Kikapcsolva", +"Change recovery key password:" => "A helyreállítási kulcs jelszavának módosítása:", +"Old Recovery key password" => "Régi Helyreállítási Kulcs Jelszava", +"New Recovery key password" => "Új Helyreállítási kulcs jelszava", +"Repeat New Recovery key password" => "Ismételje meg az új helyreállítási kulcs jelszavát", "Change Password" => "Jelszó megváltoztatása", +"Your private key password no longer match your log-in password:" => "A személyes kulcs jelszava mostantól nem azonos a belépési jelszavával:", +"Set your old private key password to your current log-in password." => "Állítsuk be a személyes kulcs jelszavát a jelenlegi bejelentkezési jelszavunkra.", +" If you don't remember your old password you can ask your administrator to recover your files." => "Ha nem emlékszik a régi jelszavára akkor megkérheti a rendszergazdát, hogy állítsa vissza az állományait.", "Old log-in password" => "Régi bejelentkezési jelszó", "Current log-in password" => "Jelenlegi bejelentkezési jelszó", -"Update Private Key Password" => "Privát kulcs jelszó frissítése", -"Enable password recovery:" => "Jelszó-visszaállítás bekapcsolása" +"Update Private Key Password" => "A személyest kulcs jelszó frissítése", +"Enable password recovery:" => "Jelszó-visszaállítás bekapcsolása", +"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "Ez az opció lehetővé teszi, hogy a titkosított állományok tartalmát visszanyerjük abban az esetben, ha elfelejti a jelszavát", +"File recovery settings updated" => "A fájlhelyreállítási beállítások frissültek", +"Could not update file recovery" => "A fájlhelyreállítás nem frissíthető" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_encryption/l10n/id.php b/apps/files_encryption/l10n/id.php index 32c348bd8ba..a719d445820 100644 --- a/apps/files_encryption/l10n/id.php +++ b/apps/files_encryption/l10n/id.php @@ -1,6 +1,41 @@ <?php $TRANSLATIONS = array( +"Recovery key successfully enabled" => "Kunci pemulihan berhasil diaktifkan", +"Could not enable recovery key. Please check your recovery key password!" => "Tidak dapat mengaktifkan kunci pemulihan. Silakan periksa sandi kunci pemulihan Anda!", +"Recovery key successfully disabled" => "Kunci pemulihan berhasil dinonaktifkan", +"Could not disable recovery key. Please check your recovery key password!" => "Tidak dapat menonaktifkan kunci pemulihan. Silakan periksa sandi kunci pemulihan Anda!", +"Password successfully changed." => "Sandi berhasil diubah", +"Could not change the password. Maybe the old password was not correct." => "Tidak dapat mengubah sandi. Kemungkinan sandi lama yang dimasukkan salah.", +"Private key password successfully updated." => "Sandi kunci privat berhasil diperbarui.", +"Could not update the private key password. Maybe the old password was not correct." => "Tidak dapat memperbarui sandi kunci privat. Kemungkinan sandi lama yang Anda masukkan salah.", +"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "Tidak dapat mendekripsi berkas ini, mungkin ini adalah berkas bersama. Silakan meminta pemilik berkas ini untuk membagikan kembali dengan Anda.", +"Unknown error please check your system settings or contact your administrator" => "Kesalahan tak dikenal, silakan periksa pengaturan sistem Anda atau hubungi admin.", +"Missing requirements." => "Persyaratan yang hilang.", +"Following users are not set up for encryption:" => "Pengguna berikut belum diatur untuk enkripsi:", +"Initial encryption started... This can take some time. Please wait." => "Inisial enskripsi dijalankan... Ini dapat memakan waktu. Silakan tunggu.", "Saving..." => "Menyimpan...", -"Encryption" => "Enkripsi" +"Go directly to your " => "Langsung ke anda", +"personal settings" => "pengaturan pribadi", +"Encryption" => "Enkripsi", +"Enable recovery key (allow to recover users files in case of password loss):" => "Aktifkan kunci pemulihan (memungkinkan pengguna untuk memulihkan berkas dalam kasus kehilangan sandi):", +"Recovery key password" => "Sandi kunci pemulihan", +"Repeat Recovery key password" => "Ulangi sandi kunci Pemulihan", +"Enabled" => "Diaktifkan", +"Disabled" => "Dinonaktifkan", +"Change recovery key password:" => "Ubah sandi kunci pemulihan:", +"Old Recovery key password" => "Sandi kunci Pemulihan Lama", +"New Recovery key password" => "Sandi kunci Pemulihan Baru", +"Repeat New Recovery key password" => "Ulangi sandi kunci Pemulihan baru", +"Change Password" => "Ubah sandi", +"Your private key password no longer match your log-in password:" => "Sandi kunci privat Anda tidak lagi cocok dengan sandi masuk:", +"Set your old private key password to your current log-in password." => "Atur sandi kunci privat lama Anda sebagai sandi masuk Anda saat ini.", +" If you don't remember your old password you can ask your administrator to recover your files." => "Jika Anda tidak ingat sandi lama, Anda dapat meminta administrator Anda untuk memulihkan berkas.", +"Old log-in password" => "Sandi masuk yang lama", +"Current log-in password" => "Sandi masuk saat ini", +"Update Private Key Password" => "Perbarui Sandi Kunci Privat", +"Enable password recovery:" => "Aktifkan sandi pemulihan:", +"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "Mengaktifkan opsi ini memungkinkan Anda untuk mendapatkan kembali akses ke berkas terenkripsi Anda dalam kasus kehilangan sandi", +"File recovery settings updated" => "Pengaturan pemulihan berkas diperbarui", +"Could not update file recovery" => "Tidak dapat memperbarui pemulihan berkas" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/files_encryption/l10n/it.php b/apps/files_encryption/l10n/it.php index f9534d7eca3..fc1aaffc025 100644 --- a/apps/files_encryption/l10n/it.php +++ b/apps/files_encryption/l10n/it.php @@ -8,22 +8,27 @@ $TRANSLATIONS = array( "Could not change the password. Maybe the old password was not correct." => "Impossibile cambiare la password. Forse la vecchia password non era corretta.", "Private key password successfully updated." => "Password della chiave privata aggiornata correttamente.", "Could not update the private key password. Maybe the old password was not correct." => "Impossibile aggiornare la password della chiave privata. Forse la vecchia password non era corretta.", -"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "La chiave privata non è valida! Forse la password è stata cambiata esternamente al sistema di ownCloud (ad es. la directory aziendale). Puoi aggiornare la password della chiave privata nelle impostazioni personali per ottenere nuovamente l'accesso ai file.", +"Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." => "Applicazione di cifratura non inizializzata. Forse l'applicazione è stata riabilitata durante la tua sessione. Prova a disconnetterti e ad effettuare nuovamente l'accesso per inizializzarla.", +"Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "La tua chiave privata non è valida! Forse la password è stata cambiata al di fuori di %s (ad es. la directory aziendale). Puoi aggiornare la password della chiave privata nelle impostazioni personali per ottenere nuovamente l'accesso ai file cifrati.", +"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "Impossibile decifrare questo file, probabilmente è un file condiviso. Chiedi al proprietario del file di condividere nuovamente il file con te.", +"Unknown error please check your system settings or contact your administrator" => "Errore sconosciuto, controlla le impostazioni di sistema o contatta il tuo amministratore", "Missing requirements." => "Requisiti mancanti.", "Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Assicurati che sia installato PHP 5.3.3 o versioni successive e che l'estensione OpenSSL di PHP sia abilitata e configurata correttamente. Per ora, l'applicazione di cifratura è disabilitata.", "Following users are not set up for encryption:" => "I seguenti utenti non sono configurati per la cifratura:", +"Initial encryption started... This can take some time. Please wait." => "Cifratura iniziale avviata... Potrebbe richiedere del tempo. Attendi.", "Saving..." => "Salvataggio in corso...", -"Your private key is not valid! Maybe the your password was changed from outside." => "La tua chiave privata non è valida! Forse è stata modifica dall'esterno.", -"You can unlock your private key in your " => "Puoi sbloccare la chiave privata nelle tue", +"Go directly to your " => "Passa direttamente a", "personal settings" => "impostazioni personali", "Encryption" => "Cifratura", "Enable recovery key (allow to recover users files in case of password loss):" => "Abilita la chiave di recupero (permette di recuperare i file utenti in caso di perdita della password):", "Recovery key password" => "Password della chiave di recupero", +"Repeat Recovery key password" => "Ripeti la password della chiave di recupero", "Enabled" => "Abilitata", "Disabled" => "Disabilitata", "Change recovery key password:" => "Cambia la password della chiave di recupero:", "Old Recovery key password" => "Vecchia password della chiave di recupero", "New Recovery key password" => "Nuova password della chiave di recupero", +"Repeat New Recovery key password" => "Ripeti la nuova password della chiave di recupero", "Change Password" => "Modifica password", "Your private key password no longer match your log-in password:" => "La password della chiave privata non corrisponde più alla password di accesso:", "Set your old private key password to your current log-in password." => "Imposta la vecchia password della chiave privata sull'attuale password di accesso.", diff --git a/apps/files_encryption/l10n/ja_JP.php b/apps/files_encryption/l10n/ja_JP.php index d1f8303bda7..1206969746b 100644 --- a/apps/files_encryption/l10n/ja_JP.php +++ b/apps/files_encryption/l10n/ja_JP.php @@ -8,22 +8,27 @@ $TRANSLATIONS = array( "Could not change the password. Maybe the old password was not correct." => "パスワードを変更できませんでした。古いパスワードが間違っているかもしれません。", "Private key password successfully updated." => "秘密鍵のパスワードが正常に更新されました。", "Could not update the private key password. Maybe the old password was not correct." => "秘密鍵のパスワードを更新できませんでした。古いパスワードが正確でない場合があります。", -"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "秘密鍵が有効ではありません。パスワードがownCloudシステムの外部(例えば、企業ディレクトリ)から変更された恐れがあります。個人設定で秘密鍵のパスワードを更新して、暗号化されたファイルを回復出来ます。", +"Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." => "暗号化アプリが初期化されていません。暗号化アプリが接続中に再度有効かされた可能性があります。暗号化アプリを初期化する為に、1回ログアウトしてログインしなおしてください。", +"Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "プライベートキーが有効ではありません!パスワードが%sの外部で変更された(例: 共同ディレクトリ)と思われます。個人設定でプライベートキーのパスワードを更新して、暗号化ファイルへのアクセスを回復することができます。", +"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "このファイルを復号化できません、共有ファイルの可能性があります。ファイルの所有者にお願いして、ファイルを共有しなおしてもらってください。", +"Unknown error please check your system settings or contact your administrator" => "不明なエラーです。システム設定を確認するか、管理者に問い合わせてください。", "Missing requirements." => "必要要件が満たされていません。", "Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "必ず、PHP 5.3.3もしくはそれ以上をインストールし、同時にOpenSSLのPHP拡張を有効にした上でOpenSSLも同様にインストール、適切に設定してください。現時点では暗号化アプリは無効になっています。", "Following users are not set up for encryption:" => "以下のユーザーは、暗号化設定がされていません:", +"Initial encryption started... This can take some time. Please wait." => "暗号化の初期化作業を開始しました... この処理にはしばらく時間がかかります。今しばらくお待ちください。", "Saving..." => "保存中...", -"Your private key is not valid! Maybe the your password was changed from outside." => "秘密鍵が有効ではありません。パスワードが外部から変更された恐れがあります。", -"You can unlock your private key in your " => "個人設定で", +"Go directly to your " => "あなたのディレクトリへ", "personal settings" => "秘密鍵をアンロックできます", "Encryption" => "暗号化", "Enable recovery key (allow to recover users files in case of password loss):" => "復旧キーを有効化 (万一パスワードを亡くした場合もユーザーのファイルを回復できる):", "Recovery key password" => "復旧キーのパスワード", +"Repeat Recovery key password" => "復旧キーのパスワードをもう一度入力", "Enabled" => "有効", "Disabled" => "無効", "Change recovery key password:" => "復旧キーのパスワードを変更:", "Old Recovery key password" => "古い復旧キーのパスワード", "New Recovery key password" => "新しい復旧キーのパスワード", +"Repeat New Recovery key password" => "新しい復旧キーのパスワードをもう一度入力", "Change Password" => "パスワードを変更", "Your private key password no longer match your log-in password:" => "もはや秘密鍵はログインパスワードと一致しません:", "Set your old private key password to your current log-in password." => "古い秘密鍵のパスワードを現在のログインパスワードに設定する。", diff --git a/apps/files_encryption/l10n/ko.php b/apps/files_encryption/l10n/ko.php index cfe9f99fa19..d91e861ca5d 100644 --- a/apps/files_encryption/l10n/ko.php +++ b/apps/files_encryption/l10n/ko.php @@ -1,20 +1,44 @@ <?php $TRANSLATIONS = array( +"Recovery key successfully enabled" => "복구 키가 성공적으로 활성화되었습니다", +"Could not enable recovery key. Please check your recovery key password!" => "복구 키를 활성화 할 수 없습니다. 복구 키의 암호를 확인해 주세요!", +"Recovery key successfully disabled" => "복구 키가 성공적으로 비활성화 되었습니다", +"Could not disable recovery key. Please check your recovery key password!" => "복구 키를 비활성화 할 수 없습니다. 복구 키의 암호를 확인해주세요!", "Password successfully changed." => "암호가 성공적으로 변경되었습니다", -"Could not change the password. Maybe the old password was not correct." => "암호를 변경할수 없습니다. 아마도 예전 암호가 정확하지 않은것 같습니다.", -"Private key password successfully updated." => "개인키 암호가 성공적으로 업데이트 됨.", +"Could not change the password. Maybe the old password was not correct." => "암호를 변경할 수 없습니다. 예전 암호가 정확하지 않은 것 같습니다.", +"Private key password successfully updated." => "개인 키 암호가 성공적으로 업데이트 됨.", +"Could not update the private key password. Maybe the old password was not correct." => "개인 키 암호를 업데이트할 수 없습니다. 이전 암호가 올바르지 않은 것 같습니다.", +"Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." => "암호화 앱이 초기화되지 않았습니다! 암호화 앱이 다시 활성화된 것 같습니다. 암호화 앱을 초기화하려면 로그아웃했다 다시 로그인하십시오.", +"Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "개인 키가 올바르지 않습니다! 암호가 %s(예: 회사 디렉터리) 외부에서 변경된 것 같습니다. 암호화된 파일에 다시 접근하려면 개인 설정에서 개인 키 암호를 수정하십시오.", +"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "이 파일을 복호화할 수 없습니다. 공유된 파일일 수도 있습니다. 파일 소유자에게 공유를 다시 요청하십시오.", +"Unknown error please check your system settings or contact your administrator" => "알 수 없는 오류. 시스템 설정을 확인하거나 관리자에게 문의하십시오.", +"Missing requirements." => "요구 사항이 부족합니다.", +"Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "PHP 5.3.3 이상 설치 여부, PHP의 OpenSSL 확장 기능 활성화 및 설정 여부를 확인하십시오. 암호화 앱이 비활성화 되었습니다.", +"Following users are not set up for encryption:" => "다음 사용자는 암호화를 사용할 수 없습니다:", +"Initial encryption started... This can take some time. Please wait." => "초기 암호화가 시작되었습니다... 시간이 걸릴 수도 있으니 기다려 주십시오.", "Saving..." => "저장 중...", +"Go directly to your " => "다음으로 바로 가기: ", "personal settings" => "개인 설정", "Encryption" => "암호화", -"Recovery key password" => "키 비밀번호 복구", -"Change recovery key password:" => "복구 키 비밀번호 변경", -"Old Recovery key password" => "예전 복구 키 비밀번호", -"New Recovery key password" => "새 복구 키 비밀번호", +"Enable recovery key (allow to recover users files in case of password loss):" => "복구 키 사용 (암호를 잊었을 때 파일을 복구할 수 있도록 함):", +"Recovery key password" => "복구 키 암호", +"Repeat Recovery key password" => "복구 키 암호 재입력", +"Enabled" => "활성화", +"Disabled" => "비활성화", +"Change recovery key password:" => "복구 키 암호 변경:", +"Old Recovery key password" => "이전 복구 키 암호", +"New Recovery key password" => "새 복구 키 암호", +"Repeat New Recovery key password" => "새 복구 키 암호 재입력", "Change Password" => "암호 변경", -"Old log-in password" => "예전 로그인 암호", +"Your private key password no longer match your log-in password:" => "개인 키 암호와 로그인 암호가 일치하지 않습니다:", +"Set your old private key password to your current log-in password." => "이전 개인 키 암호를 현재 로그인 암호로 설정하십시오.", +" If you don't remember your old password you can ask your administrator to recover your files." => " 이전 암호가 기억나지 않으면 시스템 관리자에게 파일 복구를 요청하십시오.", +"Old log-in password" => "이전 로그인 암호", "Current log-in password" => "현재 로그인 암호", "Update Private Key Password" => "개인 키 암호 업데이트", +"Enable password recovery:" => "암호 복구 사용:", +"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "이 옵션을 사용하면 암호를 잊었을 때 암호화된 파일에 다시 접근할 수 있습니다", "File recovery settings updated" => "파일 복구 설정 업데이트됨", -"Could not update file recovery" => "파일 복구를 업데이트 할수 없습니다" +"Could not update file recovery" => "파일 복구를 업데이트할 수 없습니다" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/files_encryption/l10n/lt_LT.php b/apps/files_encryption/l10n/lt_LT.php index 4ededb716f4..993e03388d9 100644 --- a/apps/files_encryption/l10n/lt_LT.php +++ b/apps/files_encryption/l10n/lt_LT.php @@ -8,22 +8,25 @@ $TRANSLATIONS = array( "Could not change the password. Maybe the old password was not correct." => "Slaptažodis nebuvo pakeistas. Gali būti, kad buvo neteisingai suvestas senasis.", "Private key password successfully updated." => "Privataus rakto slaptažodis buvo sėkmingai atnaujintas.", "Could not update the private key password. Maybe the old password was not correct." => "Nepavyko atnaujinti privataus rakto slaptažodžio. Gali būti, kad buvo neteisingai suvestas senasis.", -"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Jūsų privatus raktas yra netinkamas! Panašu, kad Jūsų slaptažodis buvo pakeistas išorėje ownCloud sistemos (pvz. Jūsų organizacijos kataloge). Galite atnaujinti savo privataus rakto slaptažodį savo asmeniniuose nustatymuose, kad atkurti prieigą prie savo šifruotų failų.", +"Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." => "Šifravimo programa nepaleista! Galbūt šifravimo programa buvo įjungta dar kartą Jūsų sesijos metu. Prašome atsijungti ir vėl prisijungti, kad paleisti šifravimo programą.", +"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "Failo iššifruoti nepavyko, gali būti jog jis yra pasidalintas su jumis. Paprašykite failo savininko, kad jums iš naujo pateiktų šį failą.", +"Unknown error please check your system settings or contact your administrator" => "Neatpažinta klaida, patikrinkite sistemos nustatymus arba kreipkitės į savo sistemos aministratorių", "Missing requirements." => "Trūkstami laukai.", "Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Prašome įsitikinti, kad PHP 5.3.3 ar naujesnė yra įdiegta ir kad OpenSSL kartu su PHP plėtiniu yra šjungti ir teisingai sukonfigūruoti. Kol kas šifravimo programa bus išjungta.", "Following users are not set up for encryption:" => "Sekantys naudotojai nenustatyti šifravimui:", "Saving..." => "Saugoma...", -"Your private key is not valid! Maybe the your password was changed from outside." => "Jūsų privatus raktas yra netinkamas! Galbūt Jūsų slaptažodis buvo pakeistas iš išorės?", -"You can unlock your private key in your " => "Galite atrakinti savo privatų raktą savo", +"Go directly to your " => "Eiti tiesiai į Jūsų", "personal settings" => "asmeniniai nustatymai", "Encryption" => "Šifravimas", "Enable recovery key (allow to recover users files in case of password loss):" => "Įjunkite atkūrimo raktą, (leisti atkurti naudotojų failus praradus slaptažodį):", "Recovery key password" => "Atkūrimo rakto slaptažodis", +"Repeat Recovery key password" => "Pakartokite atkūrimo rakto slaptažodį", "Enabled" => "Įjungta", "Disabled" => "Išjungta", "Change recovery key password:" => "Pakeisti atkūrimo rakto slaptažodį:", "Old Recovery key password" => "Senas atkūrimo rakto slaptažodis", "New Recovery key password" => "Naujas atkūrimo rakto slaptažodis", +"Repeat New Recovery key password" => "Pakartokite naują atkūrimo rakto slaptažodį", "Change Password" => "Pakeisti slaptažodį", "Your private key password no longer match your log-in password:" => "Privatus rakto slaptažodis daugiau neatitinka Jūsų prisijungimo slaptažodžio:", "Set your old private key password to your current log-in password." => "Nustatyti Jūsų privataus rakto slaptažodį į Jūsų dabartinį prisijungimo.", diff --git a/apps/files_encryption/l10n/mk.php b/apps/files_encryption/l10n/mk.php index fd8dd4e51c1..098f4d635ba 100644 --- a/apps/files_encryption/l10n/mk.php +++ b/apps/files_encryption/l10n/mk.php @@ -1,6 +1,20 @@ <?php $TRANSLATIONS = array( +"Password successfully changed." => "Лозинката е успешно променета.", +"Could not change the password. Maybe the old password was not correct." => "Лозинката не можеше да се промени. Можеби старата лозинка не беше исправна.", +"Missing requirements." => "Барања кои недостасуваат.", "Saving..." => "Снимам...", -"Encryption" => "Енкрипција" +"Go directly to your " => "Одете директно на вашиот", +"personal settings" => "лични подесувања", +"Encryption" => "Енкрипција", +"Repeat Recovery key password" => "Повтори ја лозинката за клучот на обновување", +"Enabled" => "Овозможен", +"Disabled" => "Оневозможен", +"Old Recovery key password" => "Старата лозинка за клучот на обновување ", +"Repeat New Recovery key password" => "Повтори ја лозинката за клучот на обновувањето", +"Change Password" => "Смени лозинка", +"Old log-in password" => "Старата лозинка за најавување", +"Current log-in password" => "Тековната лозинка за најавување", +"Enable password recovery:" => "Овозможи го обновувањето на лозинката:" ); $PLURAL_FORMS = "nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;"; diff --git a/apps/files_encryption/l10n/nl.php b/apps/files_encryption/l10n/nl.php index e37ccf54d6d..081e46a785c 100644 --- a/apps/files_encryption/l10n/nl.php +++ b/apps/files_encryption/l10n/nl.php @@ -8,22 +8,27 @@ $TRANSLATIONS = array( "Could not change the password. Maybe the old password was not correct." => "Kon wachtwoord niet wijzigen. Wellicht oude wachtwoord niet juist ingevoerd.", "Private key password successfully updated." => "Privésleutel succesvol bijgewerkt.", "Could not update the private key password. Maybe the old password was not correct." => "Kon het wachtwoord van de privésleutel niet wijzigen. Misschien was het oude wachtwoord onjuist.", -"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Uw privésleutel is niet geldig! Misschien was uw wachtwoord van buitenaf gewijzigd. U kunt het wachtwoord van uw privésleutel aanpassen in uw persoonlijke instellingen om toegang tot uw versleutelde bestanden te vergaren.", +"Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." => "Crypto app niet geïnitialiseerd. Misschien werd de crypto app geheractiveerd tijdens de sessie. Log uit en log daarna opnieuw in om de crypto app te initialiseren.", +"Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Uw privésleutel is niet geldig! Waarschijnlijk is uw wachtwoord gewijzigd buiten %s (bijv. uw corporate directory). U kunt uw privésleutel wachtwoord in uw persoonlijke instellingen bijwerken om toegang te krijgen tot uw versleutelde bestanden.", +"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "Kan dit bestand niet ontcijferen, waarschijnlijk is het een gedeeld bestand, Vraag de eigenaar om het bestand opnieuw met u te delen.", +"Unknown error please check your system settings or contact your administrator" => "Onbekende fout, Controleer uw systeeminstellingen of neem contact op met uw systeembeheerder", "Missing requirements." => "Missende benodigdheden.", "Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Wees er zeker van dat PHP5.3.3 of nieuwer is geïstalleerd en dat de OpenSSL PHP extensie is ingeschakeld en correct geconfigureerd. De versleutel-app is voorlopig uitgeschakeld.", "Following users are not set up for encryption:" => "De volgende gebruikers hebben geen configuratie voor encryptie:", +"Initial encryption started... This can take some time. Please wait." => "initiële versleuteling gestart... Dit kan even duren, geduld a.u.b.", "Saving..." => "Opslaan", -"Your private key is not valid! Maybe the your password was changed from outside." => "Uw privésleutel is niet geldig. Misschien was uw wachtwoord van buitenaf gewijzigd.", -"You can unlock your private key in your " => "U kunt uw privésleutel deblokkeren in uw", +"Go directly to your " => "Ga meteen naar uw", "personal settings" => "persoonlijke instellingen", "Encryption" => "Versleuteling", "Enable recovery key (allow to recover users files in case of password loss):" => "Activeren herstelsleutel (maakt het mogelijk om gebruikersbestanden terug te halen in geval van verlies van het wachtwoord):", "Recovery key password" => "Wachtwoord herstelsleulel", +"Repeat Recovery key password" => "Herhaal het herstelsleutel wachtwoord", "Enabled" => "Geactiveerd", "Disabled" => "Gedeactiveerd", "Change recovery key password:" => "Wijzig wachtwoord herstelsleutel:", "Old Recovery key password" => "Oude wachtwoord herstelsleutel", "New Recovery key password" => "Nieuwe wachtwoord herstelsleutel", +"Repeat New Recovery key password" => "Herhaal het nieuwe herstelsleutel wachtwoord", "Change Password" => "Wijzigen wachtwoord", "Your private key password no longer match your log-in password:" => "Het wachtwoord van uw privésleutel komt niet meer overeen met uw inlogwachtwoord:", "Set your old private key password to your current log-in password." => "Stel het wachtwoord van uw oude privésleutel in op uw huidige inlogwachtwoord.", diff --git a/apps/files_encryption/l10n/pl.php b/apps/files_encryption/l10n/pl.php index ca4502ff6aa..b768bd46f8c 100644 --- a/apps/files_encryption/l10n/pl.php +++ b/apps/files_encryption/l10n/pl.php @@ -8,22 +8,27 @@ $TRANSLATIONS = array( "Could not change the password. Maybe the old password was not correct." => "Nie można zmienić hasła. Może stare hasło nie było poprawne.", "Private key password successfully updated." => "Pomyślnie zaktualizowano hasło klucza prywatnego.", "Could not update the private key password. Maybe the old password was not correct." => "Nie można zmienić prywatnego hasła. Może stare hasło nie było poprawne.", -"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Klucz prywatny nie jest ważny! Prawdopodobnie Twoje hasło zostało zmienione poza systemem ownCloud (np. w katalogu firmy). Aby odzyskać dostęp do zaszyfrowanych plików można zaktualizować hasło klucza prywatnego w ustawieniach osobistych.", +"Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." => "Szyfrowanie aplikacja nie została zainicjowane! Może szyfrowanie aplikacji zostało ponownie włączone podczas tej sesji. Spróbuj się wylogować i zalogować ponownie aby zainicjować szyfrowanie aplikacji.", +"Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Klucz prywatny nie jest poprawny! Prawdopodobnie Twoje hasło zostało zmienione poza %s (np. w katalogu firmy). Aby odzyskać dostęp do zaszyfrowanych plików można zaktualizować hasło klucza prywatnego w ustawieniach osobistych.", +"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "Nie można odszyfrować tego pliku, prawdopodobnie jest to plik udostępniony. Poproś właściciela pliku o ponowne udostępnianie pliku Tobie.", +"Unknown error please check your system settings or contact your administrator" => "Nieznany błąd proszę sprawdzić ustawienia systemu lub skontaktuj się z administratorem", "Missing requirements." => "Brak wymagań.", "Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Proszę upewnić się, że PHP 5.3.3 lub nowszy jest zainstalowany i że OpenSSL oraz rozszerzenie PHP jest włączone i poprawnie skonfigurowane. Obecnie szyfrowanie aplikacji zostało wyłączone.", "Following users are not set up for encryption:" => "Następujący użytkownicy nie mają skonfigurowanego szyfrowania:", +"Initial encryption started... This can take some time. Please wait." => "Rozpoczęto szyfrowanie... To może chwilę potrwać. Proszę czekać.", "Saving..." => "Zapisywanie...", -"Your private key is not valid! Maybe the your password was changed from outside." => "Klucz prywatny nie jest poprawny! Może Twoje hasło zostało zmienione z zewnątrz.", -"You can unlock your private key in your " => "Możesz odblokować swój klucz prywatny w swojej", +"Go directly to your " => "Przejdź bezpośrednio do", "personal settings" => "Ustawienia osobiste", "Encryption" => "Szyfrowanie", "Enable recovery key (allow to recover users files in case of password loss):" => "Włączhasło klucza odzyskiwania (pozwala odzyskać pliki użytkowników w przypadku utraty hasła):", "Recovery key password" => "Hasło klucza odzyskiwania", +"Repeat Recovery key password" => "Powtórz hasło klucza odzyskiwania", "Enabled" => "Włączone", "Disabled" => "Wyłączone", "Change recovery key password:" => "Zmień hasło klucza odzyskiwania", "Old Recovery key password" => "Stare hasło klucza odzyskiwania", "New Recovery key password" => "Nowe hasło klucza odzyskiwania", +"Repeat New Recovery key password" => "Powtórz nowe hasło klucza odzyskiwania", "Change Password" => "Zmień hasło", "Your private key password no longer match your log-in password:" => "Hasło klucza prywatnego nie pasuje do hasła logowania:", "Set your old private key password to your current log-in password." => "Podaj swoje stare prywatne hasło aby ustawić nowe", diff --git a/apps/files_encryption/l10n/pt_BR.php b/apps/files_encryption/l10n/pt_BR.php index 5b8a68657b7..2fce7fd13a5 100644 --- a/apps/files_encryption/l10n/pt_BR.php +++ b/apps/files_encryption/l10n/pt_BR.php @@ -8,22 +8,27 @@ $TRANSLATIONS = array( "Could not change the password. Maybe the old password was not correct." => "Não foi possível alterar a senha. Talvez a senha antiga não estava correta.", "Private key password successfully updated." => "Senha de chave privada atualizada com sucesso.", "Could not update the private key password. Maybe the old password was not correct." => "Não foi possível atualizar a senha de chave privada. Talvez a senha antiga esteja incorreta.", -"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Sua chave privada não é válida! Provavelmente sua senha foi alterada fora do sistema ownCloud (por exemplo, seu diretório corporativo). Você pode atualizar sua senha de chave privada em suas configurações pessoais para recuperar o acesso a seus arquivos criptografados.", +"Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." => "Aplicativo de criptografia não foi inicializado! Talvez o aplicativo de criptografia tenha sido reativado durante essa sessão. Por favor, tente fazer logoff e login novamente para inicializar o aplicativo de criptografia.", +"Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Sua chave privada não é válida! Provavelmente sua senha foi alterada fora de %s (por exemplo, seu diretório corporativo). Você pode atualizar sua senha de chave privada em suas configurações pessoais para recuperar o acesso a seus arquivos criptografados.", +"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "Este arquivo não pode ser decriptado, provavelmente este é um arquivo compartilhado. Poe favoe peça ao dono do arquivo para compartilha-lo com você.", +"Unknown error please check your system settings or contact your administrator" => "Erro desconhecido, por favor verifique suas configurações ou faça contato com o administrador", "Missing requirements." => "Requisitos não encontrados.", "Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Por favor, certifique-se que o PHP 5.3.3 ou mais recente está instalado e que a extensão PHP OpenSSL está habilitado e configurado corretamente. Por enquanto, o aplicativo de criptografia foi desativado.", "Following users are not set up for encryption:" => "Seguintes usuários não estão configurados para criptografia:", +"Initial encryption started... This can take some time. Please wait." => "Criptografia inicial inicializada... Isto pode tomar algum tempo. Por favor espere.", "Saving..." => "Salvando...", -"Your private key is not valid! Maybe the your password was changed from outside." => "Sua chave privada não é válida! Talvez sua senha tenha sido mudada.", -"You can unlock your private key in your " => "Você pode desbloquear sua chave privada nas suas", +"Go directly to your " => "Ir diretamente para o seu", "personal settings" => "configurações pessoais.", "Encryption" => "Criptografia", "Enable recovery key (allow to recover users files in case of password loss):" => "Habilitar chave de recuperação (permite recuperar arquivos de usuários em caso de perda de senha):", "Recovery key password" => "Senha da chave de recuperação", +"Repeat Recovery key password" => "Repita Recuperação de senha da chave", "Enabled" => "Habilitado", "Disabled" => "Desabilitado", "Change recovery key password:" => "Mudar a senha da chave de recuperação:", "Old Recovery key password" => "Senha antiga da chave de recuperação", "New Recovery key password" => "Nova senha da chave de recuperação", +"Repeat New Recovery key password" => "Repita Nova senha da chave de recuperação", "Change Password" => "Trocar Senha", "Your private key password no longer match your log-in password:" => "Sua senha de chave privada não coincide mais com sua senha de login:", "Set your old private key password to your current log-in password." => "Configure sua antiga senha de chave privada para sua atual senha de login.", diff --git a/apps/files_encryption/l10n/pt_PT.php b/apps/files_encryption/l10n/pt_PT.php index 53335ab7297..77424005c3e 100644 --- a/apps/files_encryption/l10n/pt_PT.php +++ b/apps/files_encryption/l10n/pt_PT.php @@ -7,8 +7,8 @@ $TRANSLATIONS = array( "Password successfully changed." => "Password alterada com sucesso.", "Could not change the password. Maybe the old password was not correct." => "Não foi possivel alterar a password. Possivelmente a password antiga não está correcta.", "Could not update the private key password. Maybe the old password was not correct." => "Não foi possível alterar a chave. Possivelmente a password antiga não está correcta.", -"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Chave privada não é válida! Provavelmente senha foi alterada fora do sistema ownCloud (exemplo, o diretório corporativo). Pode atualizar password da chave privada em configurações personalizadas para recuperar o acesso aos seus arquivos encriptados.", "Missing requirements." => "Faltam alguns requisitos.", +"Following users are not set up for encryption:" => "Os utilizadores seguintes não estão marcados para cifragem:", "Saving..." => "A guardar...", "personal settings" => "configurações personalizadas ", "Encryption" => "Encriptação", diff --git a/apps/files_encryption/l10n/ru.php b/apps/files_encryption/l10n/ru.php index e0d52399c73..e9744b3db4d 100644 --- a/apps/files_encryption/l10n/ru.php +++ b/apps/files_encryption/l10n/ru.php @@ -8,22 +8,27 @@ $TRANSLATIONS = array( "Could not change the password. Maybe the old password was not correct." => "Невозможно изменить пароль. Возможно старый пароль не был верен.", "Private key password successfully updated." => "Пароль секретного ключа успешно обновлён.", "Could not update the private key password. Maybe the old password was not correct." => "Невозможно обновить пароль от секретного ключа. Возможно, старый пароль указан неверно.", -"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Ваш секретный ключ не действителен! Вероятно, ваш пароль был изменен вне системы OwnCloud (например, корпоративный каталог). Вы можете обновить секретный ключ в личных настройках на странице восстановления доступа к зашифрованным файлам. ", +"Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." => "Приложение шифрации не инициализированно! Возможно приложение шифрации было реактивировано во время вашей сессии. Пожалуйста, попробуйте выйти и войти снова чтобы проинициализировать приложение шифрации.", +"Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Ваш секретный ключ не действителен! Вероятно, ваш пароль был изменен вне %s (например, корпоративный каталог). Вы можете обновить секретный ключ в личных настройках на странице восстановления доступа к зашифрованным файлам. ", +"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "Не могу расшифровать файл, возможно это опубликованный файл. Пожалуйста, попросите владельца файла поделиться им с вами еще раз.", +"Unknown error please check your system settings or contact your administrator" => "Неизвестная ошибка, пожалуйста, проверьте системные настройки или свяжитесь с администратором", "Missing requirements." => "Требования отсутствуют.", "Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Пожалуйста, убедитесь, что версия PHP 5.3.3 или новее, а также, что OpenSSL и соответствующее расширение PHP включены и правильно настроены. На данный момент приложение шифрования отключено.", "Following users are not set up for encryption:" => "Для следующих пользователей шифрование не настроено:", +"Initial encryption started... This can take some time. Please wait." => "Начато начальное шифрование... Это может занять какое-то время. Пожалуйста, подождите.", "Saving..." => "Сохранение...", -"Your private key is not valid! Maybe the your password was changed from outside." => "Секретный ключ недействителен! Возможно, Ваш пароль был изменён в другой программе.", -"You can unlock your private key in your " => "Вы можете разблокировать закрытый ключ в своём ", +"Go directly to your " => "Перейти прямо в", "personal settings" => "персональные настройки", "Encryption" => "Шифрование", "Enable recovery key (allow to recover users files in case of password loss):" => "Включить ключ восстановления (позволяет пользователям восстановить файлы при потере пароля):", "Recovery key password" => "Пароль для ключа восстановления", +"Repeat Recovery key password" => "Повторите пароль восстановления ключа", "Enabled" => "Включено", "Disabled" => "Отключено", "Change recovery key password:" => "Сменить пароль для ключа восстановления:", "Old Recovery key password" => "Старый пароль для ключа восстановления", "New Recovery key password" => "Новый пароль для ключа восстановления", +"Repeat New Recovery key password" => "Повторите новый пароль восстановления ключа", "Change Password" => "Изменить пароль", "Your private key password no longer match your log-in password:" => "Пароль от секретного ключа больше не соответствует паролю входа:", "Set your old private key password to your current log-in password." => "Замените старый пароль от секретного ключа на новый пароль входа.", diff --git a/apps/files_encryption/l10n/sk_SK.php b/apps/files_encryption/l10n/sk_SK.php index a80eb3e6521..9e2c01eba33 100644 --- a/apps/files_encryption/l10n/sk_SK.php +++ b/apps/files_encryption/l10n/sk_SK.php @@ -8,22 +8,27 @@ $TRANSLATIONS = array( "Could not change the password. Maybe the old password was not correct." => "Nemožno zmeniť heslo. Pravdepodobne nebolo staré heslo zadané správne.", "Private key password successfully updated." => "Heslo súkromného kľúča je úspešne aktualizované.", "Could not update the private key password. Maybe the old password was not correct." => "Nemožno aktualizovať heslo súkromného kľúča. Možno nebolo staré heslo správne.", -"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Váš privátny kľúč je nesprávny! Pravdepodobne bolo zmenené vaše heslo mimo systému ownCloud (napr. váš korporátny adresár). Môžte aktualizovať vaše heslo privátneho kľúča v osobných nastaveniach za účelom obnovenia prístupu k zašifrovaným súborom.", +"Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." => "Šifrovacia aplikácia nie je inicializovaná. Je možné, že aplikácia bola znova aktivovaná počas vášho prihlasovania. Pokúste sa odhlásiť a znova prihlásiť pre inicializáciu šifrovania.", +"Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Váš súkromný kľúč nie je platný! Možno bolo vaše heslo zmenené mimo %s (napr. firemný priečinok). Môžete si aktualizovať heslo svojho súkromného kľúča vo vašom osobnom nastavení, ak si chcete obnoviť prístup k šifrovaným súborom.", +"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "Tento súbor sa nepodarilo dešifrovať, pravdepodobne je zdieľaný. Požiadajte majiteľa súboru, aby ho s vami znovu vyzdieľal.", +"Unknown error please check your system settings or contact your administrator" => "Neznáma chyba, skontrolujte si vaše systémové nastavenia alebo kontaktujte administrátora", "Missing requirements." => "Chýbajúce požiadavky.", "Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Prosím uistite sa, že PHP verzie 5.3.3 alebo novšej je nainštalované a tiež, že OpenSSL knižnica spolu z PHP rozšírením je povolená a konfigurovaná správne. Nateraz bola aplikácia šifrovania zablokovaná.", "Following users are not set up for encryption:" => "Nasledujúci používatelia nie sú nastavení pre šifrovanie:", +"Initial encryption started... This can take some time. Please wait." => "Počiatočné šifrovanie započalo ... To môže nejakú dobu trvať. Čakajte prosím.", "Saving..." => "Ukladám...", -"Your private key is not valid! Maybe the your password was changed from outside." => "Váš súkromný kľúč je neplatný. Možno bolo Vaše heslo zmenené z vonku.", -"You can unlock your private key in your " => "Môžte odomknúť váš privátny kľúč v", +"Go directly to your " => "Choďte priamo do vášho", "personal settings" => "osobné nastavenia", "Encryption" => "Šifrovanie", "Enable recovery key (allow to recover users files in case of password loss):" => "Povoliť obnovovací kľúč (umožňuje obnoviť používateľské súbory v prípade straty hesla):", "Recovery key password" => "Heslo obnovovacieho kľúča", +"Repeat Recovery key password" => "Zopakujte heslo kľúča pre obnovu", "Enabled" => "Povolené", "Disabled" => "Zakázané", "Change recovery key password:" => "Zmeniť heslo obnovovacieho kľúča:", "Old Recovery key password" => "Staré heslo obnovovacieho kľúča", "New Recovery key password" => "Nové heslo obnovovacieho kľúča", +"Repeat New Recovery key password" => "Zopakujte nové heslo kľúča pre obnovu", "Change Password" => "Zmeniť heslo", "Your private key password no longer match your log-in password:" => "Vaše heslo súkromného kľúča je rovnaké ako Vaše prihlasovacie heslo:", "Set your old private key password to your current log-in password." => "Nastavte si staré heslo súkromného kľúča k Vášmu súčasnému prihlasovaciemu heslu.", diff --git a/apps/files_encryption/l10n/sl.php b/apps/files_encryption/l10n/sl.php index 8b2f264c62e..60faf34cf88 100644 --- a/apps/files_encryption/l10n/sl.php +++ b/apps/files_encryption/l10n/sl.php @@ -1,39 +1,44 @@ <?php $TRANSLATIONS = array( -"Recovery key successfully enabled" => "Ključ za obnovitev gesla je bil uspešno nastavljen", -"Could not enable recovery key. Please check your recovery key password!" => "Ključa za obnovitev gesla ni bilo mogoče nastaviti. Preverite ključ!", -"Recovery key successfully disabled" => "Ključ za obnovitev gesla je bil uspešno onemogočen", -"Could not disable recovery key. Please check your recovery key password!" => "Ključa za obnovitev gesla ni bilo mogoče onemogočiti. Preverite ključ!", -"Password successfully changed." => "Geslo je bilo uspešno spremenjeno.", -"Could not change the password. Maybe the old password was not correct." => "Gesla ni bilo mogoče spremeniti. Morda vnos starega gesla ni bil pravilen.", -"Private key password successfully updated." => "Zasebni ključ za geslo je bil uspešno posodobljen.", -"Could not update the private key password. Maybe the old password was not correct." => "Zasebnega ključa za geslo ni bilo mogoče posodobiti. Morda vnos starega gesla ni bil pravilen.", -"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Vaš zasebni ključ ni veljaven. Morda je bilo vaše geslo spremenjeno zunaj sistema ownCloud (npr. v skupnem imeniku). Svoj zasebni ključ, ki vam bo omogočil dostop do šifriranih dokumentov, lahko posodobite v osebnih nastavitvah.", +"Recovery key successfully enabled" => "Ključ za obnovitev gesla je uspešno nastavljen", +"Could not enable recovery key. Please check your recovery key password!" => "Ključa za obnovitev gesla ni mogoče nastaviti. Preverite ključ!", +"Recovery key successfully disabled" => "Ključ za obnovitev gesla je uspešno onemogočen", +"Could not disable recovery key. Please check your recovery key password!" => "Ključa za obnovitev gesla ni mogoče onemogočiti. Preverite ključ!", +"Password successfully changed." => "Geslo je uspešno spremenjeno.", +"Could not change the password. Maybe the old password was not correct." => "Gesla ni mogoče spremeniti. Morda vnos starega gesla ni pravilen.", +"Private key password successfully updated." => "Zasebni ključ za geslo je uspešno posodobljen.", +"Could not update the private key password. Maybe the old password was not correct." => "Zasebnega ključa za geslo ni mogoče posodobiti. Morda vnos starega gesla ni bil pravilen.", +"Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." => "Program za šifriranje ni začet. Morda je bil program ponovno omogočen šele med zagonom trenutne seje. Odjavite se in se nato prijavite nazaj. S tem morda razrešite napako.", +"Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Zasebni ključ ni veljaven. Najverjetneje je bilo geslo spremenjeno izven %s (najverjetneje je to poslovna mapa). Geslo lahko posodobite med osebnimi nastavitvami in s tem obnovite dostop do šifriranih datotek.", +"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "Te datoteke ni mogoče šifrirati, ker je to najverjetneje datoteka v souporabi. Prosite lastnika datoteke, da jo da ponovno v souporabo.", +"Unknown error please check your system settings or contact your administrator" => "Prišlo je do neznane napake. Preverite nastavitve sistema ali pa stopite v stik s skrbnikom sistema.", "Missing requirements." => "Manjkajoče zahteve", -"Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Preverite, da imate na strežniku nameščen paket PHP 5.3.3 ali novejši in da je omogočen in pravilno nastavljen PHP OpenSSL . Zaenkrat je šifriranje onemogočeno.", -"Following users are not set up for encryption:" => "Naslednji uporabniki še nimajo nastavljenega šifriranja:", +"Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Preverite, ali je na strežniku nameščen paket PHP 5.3.3 ali novejši, da je omogočen in pravilno nastavljen PHP OpenSSL. Z obstoječimi možnostmi šifriranje ni mogoče.", +"Following users are not set up for encryption:" => "Navedeni uporabniki še nimajo nastavljenega šifriranja:", +"Initial encryption started... This can take some time. Please wait." => "Začetno šifriranje je začeto ... Opravilo je lahko dolgotrajno.", "Saving..." => "Poteka shranjevanje ...", -"Your private key is not valid! Maybe the your password was changed from outside." => "Vaš zasebni ključ ni veljaven. Morda je bilo vaše geslo spremenjeno.", -"You can unlock your private key in your " => "Svoj zasebni ključ lahko odklenite v", +"Go directly to your " => "Skočite neposredno na", "personal settings" => "osebne nastavitve", "Encryption" => "Šifriranje", -"Enable recovery key (allow to recover users files in case of password loss):" => "Omogoči ključ za obnovitev datotek (v primeru izgube gesla)", +"Enable recovery key (allow to recover users files in case of password loss):" => "Omogoči ključ za obnovitev datotek (v primeru izgube gesla):", "Recovery key password" => "Ključ za obnovitev gesla", +"Repeat Recovery key password" => "Ponovi ključ za obnovitev gesla", "Enabled" => "Omogočeno", "Disabled" => "Onemogočeno", "Change recovery key password:" => "Spremeni ključ za obnovitev gesla:", "Old Recovery key password" => "Stari ključ za obnovitev gesla", -"New Recovery key password" => "Nov ključ za obnovitev gesla", +"New Recovery key password" => "Novi ključ za obnovitev gesla", +"Repeat New Recovery key password" => "Ponovi novi ključ za obnovitev gesla", "Change Password" => "Spremeni geslo", -"Your private key password no longer match your log-in password:" => "Vaš zasebni ključ za geslo se ne ujema z vnešenim geslom ob prijavi:", -"Set your old private key password to your current log-in password." => "Nastavite svoj star zasebni ključ v geslo, vnešeno ob prijavi.", -" If you don't remember your old password you can ask your administrator to recover your files." => "Če ste svoje geslo pozabili, lahko vaše datoteke obnovi skrbnik sistema.", +"Your private key password no longer match your log-in password:" => "Vaš zasebni ključ za geslo se ne ujema z geslom, vnesenim ob prijavi:", +"Set your old private key password to your current log-in password." => "Nastavite svoj star zasebni ključ v geslo, vneseno ob prijavi.", +" If you don't remember your old password you can ask your administrator to recover your files." => "Če ste pozabili svoje geslo, lahko vaše datoteke obnovi le skrbnik sistema.", "Old log-in password" => "Staro geslo", "Current log-in password" => "Trenutno geslo", "Update Private Key Password" => "Posodobi zasebni ključ", "Enable password recovery:" => "Omogoči obnovitev gesla:", -"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "Nastavitev te možnosti omogoča ponovno pridobitev dostopa do šifriranih datotek, v primeru da boste geslo pozabili.", -"File recovery settings updated" => "Nastavitve obnavljanja dokumentov so bile posodobljene", -"Could not update file recovery" => "Nastavitev za obnavljanje dokumentov ni bilo mogoče posodobiti" +"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "Nastavitev te možnosti omogoča ponovno pridobitev dostopa do šifriranih datotek, v primeru, da boste geslo pozabili.", +"File recovery settings updated" => "Nastavitve obnavljanja dokumentov so posodobljene", +"Could not update file recovery" => "Nastavitev za obnavljanje dokumentov ni mogoče posodobiti" ); $PLURAL_FORMS = "nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);"; diff --git a/apps/files_encryption/l10n/sq.php b/apps/files_encryption/l10n/sq.php new file mode 100644 index 00000000000..dc156ff3bf0 --- /dev/null +++ b/apps/files_encryption/l10n/sq.php @@ -0,0 +1,5 @@ +<?php +$TRANSLATIONS = array( +"Saving..." => "Duke ruajtur..." +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_encryption/l10n/sv.php b/apps/files_encryption/l10n/sv.php index 88ba6b47159..1e509ea08e7 100644 --- a/apps/files_encryption/l10n/sv.php +++ b/apps/files_encryption/l10n/sv.php @@ -6,31 +6,35 @@ $TRANSLATIONS = array( "Could not disable recovery key. Please check your recovery key password!" => "Kunde inte inaktivera återställningsnyckeln. Vänligen kontrollera ditt lösenord för återställningsnyckeln!", "Password successfully changed." => "Ändringen av lösenordet lyckades.", "Could not change the password. Maybe the old password was not correct." => "Kunde inte ändra lösenordet. Kanske det gamla lösenordet inte var rätt.", -"Private key password successfully updated." => "Den privata lösenordsnyckeln uppdaterades utan problem.", -"Could not update the private key password. Maybe the old password was not correct." => "Kunde inte uppdatera den privata lösenordsnyckeln. Kanske var det gamla lösenordet fel.", -"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Din privata lösenordsnyckel är inte giltig! Troligen har ditt lösenord ändrats utanför ownCloud (t.ex. i företagets katalogtjänst). Du kan uppdatera den privata lösenordsnyckeln under dina personliga inställningar för att återfå tillgång till dina filer.", +"Private key password successfully updated." => "Den privata nyckelns lösenord uppdaterades utan problem.", +"Could not update the private key password. Maybe the old password was not correct." => "Kunde inte uppdatera lösenordet för den privata nyckeln. Kanske var det gamla lösenordet fel.", +"Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." => "Krypteringsprogrammet kunde inte initieras! Möjligen blev krypteringsprogrammet återaktiverad under din session. Försök med att logga ut och in igen för att initiera krypteringsprogrammet.", +"Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Din privata lösenordsnyckel är inte giltig! Troligen har ditt lösenord ändrats utanför %s (t.ex. i företagets katalogtjänst). Du kan uppdatera den privata lösenordsnyckeln under dina personliga inställningar för att återfå tillgång till dina filer.", +"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "Kan ej dekryptera denna fil, förmodligen är det en delad fil. Be ägaren av filen att dela den med dig.", +"Unknown error please check your system settings or contact your administrator" => "Oväntat fel, kolla dina system inställningar eller kontakta din administratör", "Missing requirements." => "Krav som saknas", "Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "Kontrollera att PHP 5.3.3 eller senare är installerad och att tillägget OpenSSL PHP är aktiverad och korrekt konfigurerad. Kryptering är tillsvidare inaktiverad.", "Following users are not set up for encryption:" => "Följande användare har inte aktiverat kryptering:", "Saving..." => "Sparar...", -"Your private key is not valid! Maybe the your password was changed from outside." => "Din privata lösenordsnyckel är inte giltig! Kanske byttes ditt lösenord från utsidan.", -"You can unlock your private key in your " => "Du kan låsa upp din privata nyckel i dina", +"Go directly to your " => "Gå direkt till din", "personal settings" => "personliga inställningar", "Encryption" => "Kryptering", -"Enable recovery key (allow to recover users files in case of password loss):" => "Aktivera lösenordsnyckel (för att kunna återfå användarens filer vid glömt eller förlorat lösenord):", -"Recovery key password" => "Lösenordsnyckel", +"Enable recovery key (allow to recover users files in case of password loss):" => "Aktivera återställningsnyckel (för att kunna återfå användarens filer vid glömt eller förlorat lösenord):", +"Recovery key password" => "Lösenord för återställningsnyckel", +"Repeat Recovery key password" => "Upprepa återställningsnyckelns lösenord", "Enabled" => "Aktiverad", "Disabled" => "Inaktiverad", -"Change recovery key password:" => "Ändra lösenordsnyckel:", -"Old Recovery key password" => "Gammal lösenordsnyckel", -"New Recovery key password" => "Ny lösenordsnyckel", +"Change recovery key password:" => "Ändra lösenord för återställningsnyckel:", +"Old Recovery key password" => "Gammalt lösenord för återställningsnyckel", +"New Recovery key password" => "Nytt lösenord för återställningsnyckel", +"Repeat New Recovery key password" => "Upprepa lösenord för ny återställningsnyckel", "Change Password" => "Byt lösenord", -"Your private key password no longer match your log-in password:" => "Din privata lösenordsnyckel stämmer inte längre överrens med ditt inloggningslösenord:", -"Set your old private key password to your current log-in password." => "Ställ in din gamla privata lösenordsnyckel till ditt aktuella inloggningslösenord.", +"Your private key password no longer match your log-in password:" => "Lösenordet till din privata nyckel stämmer inte längre överens med ditt inloggningslösenord:", +"Set your old private key password to your current log-in password." => "Använd din gamla privata nyckels lösenord som ditt aktuella inloggningslösenord.", " If you don't remember your old password you can ask your administrator to recover your files." => "Om du inte kommer ihåg ditt gamla lösenord kan du be din administratör att återställa dina filer.", "Old log-in password" => "Gammalt inloggningslösenord", "Current log-in password" => "Nuvarande inloggningslösenord", -"Update Private Key Password" => "Uppdatera den privata lösenordsnyckeln", +"Update Private Key Password" => "Uppdatera lösenordet för din privata nyckel", "Enable password recovery:" => "Aktivera lösenordsåterställning", "Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "Genom att aktivera detta alternativ kommer du kunna återfå tillgång till dina krypterade filer om du skulle förlora/glömma ditt lösenord", "File recovery settings updated" => "Inställningarna för filåterställning har uppdaterats", diff --git a/apps/files_encryption/l10n/tr.php b/apps/files_encryption/l10n/tr.php index 7fdda1a5bf6..b8289ab71f9 100644 --- a/apps/files_encryption/l10n/tr.php +++ b/apps/files_encryption/l10n/tr.php @@ -4,13 +4,40 @@ $TRANSLATIONS = array( "Could not enable recovery key. Please check your recovery key password!" => "Kurtarma anahtarı etkinleştirilemedi. Lütfen kurtarma anahtarı parolanızı kontrol edin!", "Recovery key successfully disabled" => "Kurtarma anahtarı başarıyla devre dışı bırakıldı", "Could not disable recovery key. Please check your recovery key password!" => "Kurtarma anahtarı devre dışı bırakılamadı. Lütfen kurtarma anahtarı parolanızı kontrol edin!", -"Password successfully changed." => "Şifreniz başarıyla değiştirildi.", -"Could not change the password. Maybe the old password was not correct." => "Parola değiştirilemedi. Eski parolanız doğru olmayabilir", +"Password successfully changed." => "Parola başarıyla değiştirildi.", +"Could not change the password. Maybe the old password was not correct." => "Parola değiştirilemedi. Eski parolanız doğru olmayabilir.", +"Private key password successfully updated." => "Gizli anahtar parolası başarıyla güncellendi", +"Could not update the private key password. Maybe the old password was not correct." => "Gizli anahtar parolası güncellenemedi. Eski parola hatalı olabilir.", +"Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." => "Şifreleme uygulaması başlatılamadı! Oturumunuz sırasında şifreleme uygulaması tekrar etkinleştirilmiş olabilir. Lütfen şifreleme uygulamasını başlatmak için oturumu kapatıp yeniden oturum açmayı deneyin.", +"Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "Gizli anahtarınız geçerli değil! Muhtemelen parolanız ownCloud sistemi %s dışarısında değiştirildi (örn. şirket dizininde). Gizli anahtar parolanızı kişisel ayarlarınızda güncelleyerek şifreli dosyalarınıza erişimi kurtarabilirsiniz.", +"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "Bu dosya muhtemelen bir paylaşılan dosya olduğundan şifresi çözülemiyor. Lütfen dosyayı sizinle bir daha paylaşması için dosya sahibi ile iletişime geçin.", +"Unknown error please check your system settings or contact your administrator" => "Bilinmeyen hata. Lütfen sistem ayarlarınızı denetleyin veya yöneticiniz ile iletişime geçin", +"Missing requirements." => "Gereklilikler eksik.", +"Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "PHP 5.3.3 veya daha sürümü ile birlikte OpenSSL ve OpenSSL PHP uzantısının birlikte etkin olduğunu ve doğru bir şekilde yapılandırıldığından emin olun. Şimdilik şifreleme uygulaması devre dışı bırakıldı", +"Following users are not set up for encryption:" => "Aşağıdaki kullanıcılar şifreleme için ayarlanmadılar:", +"Initial encryption started... This can take some time. Please wait." => "İlk şifreleme başladı... Bu biraz zaman alabilir. Lütfen bekleyin.", "Saving..." => "Kaydediliyor...", +"Go directly to your " => "Doğrudan şuraya gidin:", +"personal settings" => "kişisel ayarlar", "Encryption" => "Şifreleme", +"Enable recovery key (allow to recover users files in case of password loss):" => "Kurtarma anahtarını etkinleştir (parola kaybı durumunda kullanıcı dosyalarının kurtarılmasına izin verir):", +"Recovery key password" => "Kurtarma anahtarı parolası", +"Repeat Recovery key password" => "Kurtarma anahtarı parolasını yenileyin", "Enabled" => "Etkinleştirildi", "Disabled" => "Devre dışı", -"Change Password" => "Parola değiştir", +"Change recovery key password:" => "Kurtarma anahtarı parolasını değiştir:", +"Old Recovery key password" => "Eski Kurtarma anahtar parolası", +"New Recovery key password" => "Yeni Kurtarma anahtar parolası", +"Repeat New Recovery key password" => "Yeni Kurtarma anahtarı parolasını yenileyin", +"Change Password" => "Parola Değiştir", +"Your private key password no longer match your log-in password:" => "Özel anahtar parolanız artık oturum açma parolanızla eşleşmiyor:", +"Set your old private key password to your current log-in password." => "Eski özel anahtar parolanızı geçerli oturum açma parolanız olarak ayarlayın.", +" If you don't remember your old password you can ask your administrator to recover your files." => "Eğer eski parolanızı hatırlamıyorsanız, yöneticinizden dosyalarınızı kurtarmasını talep edebilirsiniz.", +"Old log-in password" => "Eski oturum açma parolası", +"Current log-in password" => "Geçerli oturum açma parolası", +"Update Private Key Password" => "Özel Anahtar Parolasını Güncelle", +"Enable password recovery:" => "Parola kurtarmayı etkinleştir:", +"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "Bu seçeneği etkinleştirmek, parola kaybı durumunda şifrelenmiş dosyalarınıza erişimi yeniden kazanmanızı sağlayacaktır", "File recovery settings updated" => "Dosya kurtarma ayarları güncellendi", "Could not update file recovery" => "Dosya kurtarma güncellenemedi" ); diff --git a/apps/files_encryption/l10n/zh_CN.php b/apps/files_encryption/l10n/zh_CN.php index c4c52f4ac2e..a51856aec94 100644 --- a/apps/files_encryption/l10n/zh_CN.php +++ b/apps/files_encryption/l10n/zh_CN.php @@ -8,10 +8,7 @@ $TRANSLATIONS = array( "Could not change the password. Maybe the old password was not correct." => "不能修改密码。旧密码可能不正确。", "Private key password successfully updated." => "私钥密码成功更新。", "Could not update the private key password. Maybe the old password was not correct." => "无法更新私钥密码。可能旧密码不正确。", -"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "您的私有密钥无效!也许是您在 ownCloud 系统外更改了密码 (比如,在您的公司目录)。您可以在个人设置里更新您的私钥密码来恢复访问你的加密文件。", "Saving..." => "保存中", -"Your private key is not valid! Maybe the your password was changed from outside." => "您的私钥不正确!可能您在别处更改了密码。", -"You can unlock your private key in your " => "您可以在这里解锁您的私钥:", "personal settings" => "个人设置", "Encryption" => "加密", "Enable recovery key (allow to recover users files in case of password loss):" => "启用恢复密钥(允许你在密码丢失后恢复文件):", diff --git a/apps/files_encryption/l10n/zh_TW.php b/apps/files_encryption/l10n/zh_TW.php index 02dc49cc3d9..8972490ea5a 100644 --- a/apps/files_encryption/l10n/zh_TW.php +++ b/apps/files_encryption/l10n/zh_TW.php @@ -1,16 +1,42 @@ <?php $TRANSLATIONS = array( +"Recovery key successfully enabled" => "還原金鑰已成功開啟", +"Could not enable recovery key. Please check your recovery key password!" => "無法啟用還原金鑰。請檢查您的還原金鑰密碼!", +"Recovery key successfully disabled" => "還原金鑰已成功停用", +"Could not disable recovery key. Please check your recovery key password!" => "無法停用還原金鑰。請檢查您的還原金鑰密碼!", "Password successfully changed." => "成功變更密碼。", "Could not change the password. Maybe the old password was not correct." => "無法變更密碼,或許是輸入的舊密碼不正確。", -"Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "您的私鑰不正確! 感覺像是密碼在 ownCloud 系統之外被改變(例:您的目錄)。 您可以在個人設定中更新私鑰密碼取回已加密的檔案。", +"Private key password successfully updated." => "私人金鑰密碼已成功更新。", +"Could not update the private key password. Maybe the old password was not correct." => "無法更新私人金鑰密碼。可能舊的密碼不正確。", +"Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app." => "加密功能未初始化!可能加密功能需要重新啟用在現在的連線上。請試著登出再登入來初始化加密功能。", +"Your private key is not valid! Likely your password was changed outside of %s (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files." => "您的私人金鑰不正確!可能您的密碼已經變更在外部的 %s (例如:您的企業目錄)。您可以在您的個人設定中更新私人金鑰密碼來還原存取您的加密檔案。", +"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." => "無法解密這個檔案,也許這是分享的檔案。請詢問檔案所有人重新分享檔案給您。", +"Unknown error please check your system settings or contact your administrator" => "未知錯誤請檢查您的系統設定或是聯絡您的管理員", +"Missing requirements." => "遺失必要條件。", +"Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled." => "請確認已安裝 PHP 5.3.3 或是更新的版本以及 OpenSSL 也一併安裝在 PHP extension 裡面並啟用及設置完成。現在,加密功能是停用的。", +"Following users are not set up for encryption:" => "以下的使用者無法設定加密:", "Saving..." => "儲存中...", +"Go directly to your " => "直接到您的", +"personal settings" => "個人設定", "Encryption" => "加密", +"Enable recovery key (allow to recover users files in case of password loss):" => "啟用還原金鑰 (因忘記密碼仍允許還原使用者檔案):", +"Recovery key password" => "還原金鑰密碼", +"Repeat Recovery key password" => "再輸入還原金鑰密碼一次", "Enabled" => "已啓用", "Disabled" => "已停用", +"Change recovery key password:" => "變更還原金鑰密碼:", +"Old Recovery key password" => "舊的還原金鑰密碼", +"New Recovery key password" => "新的還原金鑰密碼", +"Repeat New Recovery key password" => "再輸入新的還原金鑰密碼一次", "Change Password" => "變更密碼", +"Your private key password no longer match your log-in password:" => "您的私人金鑰密碼不符合您的登入密碼:", +"Set your old private key password to your current log-in password." => "設定您的舊私人金鑰密碼到您現在的登入密碼。", " If you don't remember your old password you can ask your administrator to recover your files." => "如果您忘記舊密碼,可以請求管理員協助取回檔案。", "Old log-in password" => "舊登入密碼", "Current log-in password" => "目前的登入密碼", +"Update Private Key Password" => "更新私人金鑰密碼", +"Enable password recovery:" => "啟用密碼還原:", +"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" => "啟用這個選項將會允許您因忘記密碼但需要存取您的加密檔案", "File recovery settings updated" => "檔案還原設定已更新", "Could not update file recovery" => "無法更新檔案還原設定" ); diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index c009718160a..9155d238c77 100755 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -33,6 +33,12 @@ require_once __DIR__ . '/../3rdparty/Crypt_Blowfish/Blowfish.php'; class Crypt {
+ const ENCRYPTION_UNKNOWN_ERROR = -1;
+ const ENCRYPTION_NOT_INITIALIZED_ERROR = 1;
+ const ENCRYPTION_PRIVATE_KEY_NOT_VALID_ERROR = 2;
+ const ENCRYPTION_NO_SHARE_KEY_FOUND = 3;
+
+
/**
* @brief return encryption mode client or server side encryption
* @param string $user name (use system wide setting if name=null)
@@ -183,8 +189,8 @@ class Crypt { // Fetch all file metadata from DB
$metadata = \OC\Files\Filesystem::getFileInfo($relPath, '');
- // If a file is flagged with encryption in DB, but isn't a
- // valid content + IV combination, it's probably using the
+ // If a file is flagged with encryption in DB, but isn't a
+ // valid content + IV combination, it's probably using the
// legacy encryption system
if (isset($metadata['encrypted'])
&& $metadata['encrypted'] === true
@@ -388,7 +394,7 @@ class Crypt { */
public static function multiKeyEncrypt($plainContent, array $publicKeys) {
- // openssl_seal returns false without errors if $plainContent
+ // openssl_seal returns false without errors if $plainContent
// is empty, so trigger our own error
if (empty($plainContent)) {
@@ -405,7 +411,7 @@ class Crypt { $i = 0;
- // Ensure each shareKey is labelled with its
+ // Ensure each shareKey is labelled with its
// corresponding userId
foreach ($publicKeys as $userId => $publicKey) {
@@ -476,7 +482,7 @@ class Crypt { }
- // We encode the iv purely for string manipulation
+ // We encode the iv purely for string manipulation
// purposes - it gets decoded before use
$iv = base64_encode($random);
diff --git a/apps/files_encryption/lib/helper.php b/apps/files_encryption/lib/helper.php index ebfc00157f7..5dcb05fa196 100755 --- a/apps/files_encryption/lib/helper.php +++ b/apps/files_encryption/lib/helper.php @@ -29,6 +29,8 @@ namespace OCA\Encryption; */ class Helper { + private static $tmpFileMapping; // Map tmp files to files in data/user/files + /** * @brief register share related hooks * @@ -59,6 +61,7 @@ class Helper { */ public static function registerFilesystemHooks() { + \OCP\Util::connectHook('OC_Filesystem', 'rename', 'OCA\Encryption\Hooks', 'preRename'); \OCP\Util::connectHook('OC_Filesystem', 'post_rename', 'OCA\Encryption\Hooks', 'postRename'); } @@ -69,6 +72,7 @@ class Helper { public static function registerAppHooks() { \OCP\Util::connectHook('OC_App', 'pre_disable', 'OCA\Encryption\Hooks', 'preDisable'); + \OCP\Util::connectHook('OC_App', 'post_disable', 'OCA\Encryption\Hooks', 'postEnable'); } /** @@ -156,6 +160,49 @@ class Helper { return $return; } + /** + * @brief Check if a path is a .part file + * @param string $path Path that may identify a .part file + * @return bool + */ + public static function isPartialFilePath($path) { + + $extension = pathinfo($path, PATHINFO_EXTENSION); + if ( $extension === 'part') { + return true; + } else { + return false; + } + + } + + + /** + * @brief Remove .path extension from a file path + * @param string $path Path that may identify a .part file + * @return string File path without .part extension + * @note this is needed for reusing keys + */ + public static function stripPartialFileExtension($path) { + $extension = pathinfo($path, PATHINFO_EXTENSION); + + if ( $extension === 'part') { + + $newLength = strlen($path) - 5; // 5 = strlen(".part") = strlen(".etmp") + $fPath = substr($path, 0, $newLength); + + // if path also contains a transaction id, we remove it too + $extension = pathinfo($fPath, PATHINFO_EXTENSION); + if(substr($extension, 0, 12) === 'ocTransferId') { // 12 = strlen("ocTransferId") + $newLength = strlen($fPath) - strlen($extension) -1; + $fPath = substr($fPath, 0, $newLength); + } + return $fPath; + + } else { + return $path; + } + } /** * @brief disable recovery @@ -181,10 +228,7 @@ class Helper { * @return bool */ public static function isPublicAccess() { - if (\OCP\USER::getUser() === false - || (isset($_GET['service']) && $_GET['service'] == 'files' - && isset($_GET['t'])) - ) { + if (\OCP\User::getUser() === false) { return true; } else { return false; @@ -212,39 +256,115 @@ class Helper { } /** - * @brief get path to the correspondig file in data/user/files - * @param string $path path to a version or a file in the trash - * @return string path to correspondig file relative to data/user/files + * @brief try to get the user from the path if no user is logged in + * @param string $path + * @return mixed user or false if we couldn't determine a user */ - public static function getPathToRealFile($path) { + public static function getUser($path) { + + $user = \OCP\User::getUser(); + + + // if we are logged in, then we return the userid + if ($user) { + return $user; + } + + // if no user is logged in we try to access a publicly shared files. + // In this case we need to try to get the user from the path + $trimmed = ltrim($path, '/'); $split = explode('/', $trimmed); - if (count($split) < 3 || $split[1] !== "files_versions") { + // it is not a file relative to data/user/files + if (count($split) < 2 || ($split[1] !== 'files' && $split[1] !== 'cache')) { return false; } - $sliced = array_slice($split, 2); - $realPath = implode('/', $sliced); - //remove the last .v - $realPath = substr($realPath, 0, strrpos($realPath, '.v')); + $user = $split[0]; - return $realPath; + if (\OCP\User::userExists($user)) { + return $user; + } + + return false; } /** - * @brief redirect to a error page + * @brief get path to the corresponding file in data/user/files if path points + * to a version or to a file in cache + * @param string $path path to a version or a file in the trash + * @return string path to corresponding file relative to data/user/files */ - public static function redirectToErrorPage($session) { + public static function getPathToRealFile($path) { + $trimmed = ltrim($path, '/'); + $split = explode('/', $trimmed); + $result = false; + + if (count($split) >= 3 && ($split[1] === "files_versions" || $split[1] === 'cache')) { + $sliced = array_slice($split, 2); + $result = implode('/', $sliced); + if ($split[1] === "files_versions") { + // we skip user/files + $sliced = array_slice($split, 2); + $relPath = implode('/', $sliced); + //remove the last .v + $result = substr($relPath, 0, strrpos($relPath, '.v')); + } + if ($split[1] === "cache") { + // we skip /user/cache/transactionId + $sliced = array_slice($split, 3); + $result = implode('/', $sliced); + //prepare the folders + self::mkdirr($path, new \OC\Files\View('/')); + } + } + + return $result; + } - $init = $session->getInitialized(); + /** + * @brief create directory recursively + * @param string $path + * @param \OC\Files\View $view + */ + public static function mkdirr($path, $view) { + $dirname = \OC_Filesystem::normalizePath(dirname($path)); + $dirParts = explode('/', $dirname); + $dir = ""; + foreach ($dirParts as $part) { + $dir = $dir . '/' . $part; + if (!$view->file_exists($dir)) { + $view->mkdir($dir); + } + } + } + + /** + * @brief redirect to a error page + */ + public static function redirectToErrorPage($session, $errorCode = null) { + + if ($errorCode === null) { + $init = $session->getInitialized(); + switch ($init) { + case \OCA\Encryption\Session::INIT_EXECUTED: + $errorCode = \OCA\Encryption\Crypt::ENCRYPTION_PRIVATE_KEY_NOT_VALID_ERROR; + break; + case \OCA\Encryption\Session::NOT_INITIALIZED: + $errorCode = \OCA\Encryption\Crypt::ENCRYPTION_NOT_INITIALIZED_ERROR; + break; + default: + $errorCode = \OCA\Encryption\Crypt::ENCRYPTION_UNKNOWN_ERROR; + } + } $location = \OC_Helper::linkToAbsolute('apps/files_encryption/files', 'error.php'); $post = 0; if(count($_POST) > 0) { $post = 1; } - header('Location: ' . $location . '?p=' . $post . '&i=' . $init); + header('Location: ' . $location . '?p=' . $post . '&errorCode=' . $errorCode); exit(); } @@ -306,5 +426,27 @@ class Helper { public static function escapeGlobPattern($path) { return preg_replace('/(\*|\?|\[)/', '[$1]', $path); } + + /** + * @brief remember from which file the tmp file (getLocalFile() call) was created + * @param string $tmpFile path of tmp file + * @param string $originalFile path of the original file relative to data/ + */ + public static function addTmpFileToMapper($tmpFile, $originalFile) { + self::$tmpFileMapping[$tmpFile] = $originalFile; + } + + /** + * @brief get the path of the original file + * @param string $tmpFile path of the tmp file + * @return mixed path of the original file or false + */ + public static function getPathFromTmpFile($tmpFile) { + if (isset(self::$tmpFileMapping[$tmpFile])) { + return self::$tmpFileMapping[$tmpFile]; + } + + return false; + } } diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index 7143fcff0f6..b2c756894b4 100755 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -112,21 +112,18 @@ class Keymanager { * @brief store file encryption key * * @param \OC_FilesystemView $view + * @param \OCA\Encryption\Util $util * @param string $path relative path of the file, including filename - * @param $userId - * @param $catfile - * @internal param string $key + * @param string $catfile keyfile content * @return bool true/false * @note The keyfile is not encrypted here. Client code must * asymmetrically encrypt the keyfile before passing it to this method */ - public static function setFileKey(\OC_FilesystemView $view, $path, $userId, $catfile) { + public static function setFileKey(\OC_FilesystemView $view, $util, $path, $catfile) { $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; - //here we need the currently logged in user, while userId can be a different user - $util = new Util($view, \OCP\User::getUser()); list($owner, $filename) = $util->getUidAndFilename($path); // in case of system wide mount points the keys are stored directly in the data directory @@ -152,10 +149,10 @@ class Keymanager { } // try reusing key file if part file - if (self::isPartialFilePath($targetPath)) { + if (Helper::isPartialFilePath($targetPath)) { $result = $view->file_put_contents( - $basePath . '/' . self::fixPartialFilePath($targetPath) . '.key', $catfile); + $basePath . '/' . Helper::stripPartialFileExtension($targetPath) . '.key', $catfile); } else { @@ -170,63 +167,20 @@ class Keymanager { } /** - * @brief Remove .path extension from a file path - * @param string $path Path that may identify a .part file - * @return string File path without .part extension - * @note this is needed for reusing keys - */ - public static function fixPartialFilePath($path) { - - if (preg_match('/\.part$/', $path) || preg_match('/\.etmp$/', $path)) { - - $newLength = strlen($path) - 5; - $fPath = substr($path, 0, $newLength); - - return $fPath; - - } else { - - return $path; - - } - - } - - /** - * @brief Check if a path is a .part file - * @param string $path Path that may identify a .part file - * @return bool - */ - public static function isPartialFilePath($path) { - - if (preg_match('/\.part$/', $path) || preg_match('/\.etmp$/', $path)) { - - return true; - - } else { - - return false; - - } - - } - - /** * @brief retrieve keyfile for an encrypted file * @param \OC_FilesystemView $view - * @param $userId + * @param \OCA\Encryption\Util $util * @param $filePath * @internal param \OCA\Encryption\file $string name * @return string file key or false * @note The keyfile returned is asymmetrically encrypted. Decryption * of the keyfile must be performed by client code */ - public static function getFileKey(\OC_FilesystemView $view, $userId, $filePath) { + public static function getFileKey($view, $util, $filePath) { - $util = new Util($view, \OCP\User::getUser()); list($owner, $filename) = $util->getUidAndFilename($filePath); - $filename = self::fixPartialFilePath($filename); + $filename = Helper::stripPartialFileExtension($filename); $filePath_f = ltrim($filename, '/'); // in case of system wide mount points the keys are stored directly in the data directory @@ -259,17 +213,17 @@ class Keymanager { * @brief Delete a keyfile * * @param \OC_FilesystemView $view - * @param string $userId username * @param string $path path of the file the key belongs to * @return bool Outcome of unlink operation * @note $path must be relative to data/user/files. e.g. mydoc.txt NOT * /data/admin/files/mydoc.txt */ - public static function deleteFileKey(\OC_FilesystemView $view, $userId, $path) { + public static function deleteFileKey(\OC_FilesystemView $view, $path) { $trimmed = ltrim($path, '/'); - $util = new Util($view, \OCP\User::getUser()); + $userId = Helper::getUser($path); + $util = new Util($view, $userId); if($util->isSystemWideMountPoint($path)) { $keyPath = '/files_encryption/keyfiles/' . $trimmed; @@ -358,16 +312,15 @@ class Keymanager { /** * @brief store multiple share keys for a single file * @param \OC_FilesystemView $view - * @param $path + * @param \OCA\Encryption\Util $util + * @param string $path * @param array $shareKeys * @return bool */ - public static function setShareKeys(\OC_FilesystemView $view, $path, array $shareKeys) { + public static function setShareKeys(\OC_FilesystemView $view, $util, $path, array $shareKeys) { // $shareKeys must be an array with the following format: // [userId] => [encrypted key] - // Here we need the currently logged in user, while userId can be a different user - $util = new Util($view, \OCP\User::getUser()); list($owner, $filename) = $util->getUidAndFilename($path); @@ -385,8 +338,8 @@ class Keymanager { foreach ($shareKeys as $userId => $shareKey) { // try reusing key file if part file - if (self::isPartialFilePath($shareKeyPath)) { - $writePath = $basePath . '/' . self::fixPartialFilePath($shareKeyPath) . '.' . $userId . '.shareKey'; + if (Helper::isPartialFilePath($shareKeyPath)) { + $writePath = $basePath . '/' . Helper::stripPartialFileExtension($shareKeyPath) . '.' . $userId . '.shareKey'; } else { $writePath = $basePath . '/' . $shareKeyPath . '.' . $userId . '.shareKey'; } @@ -406,23 +359,20 @@ class Keymanager { * @brief retrieve shareKey for an encrypted file * @param \OC_FilesystemView $view * @param string $userId + * @param \OCA\Encryption\Util $util * @param string $filePath - * @internal param \OCA\Encryption\file $string name * @return string file key or false * @note The sharekey returned is encrypted. Decryption * of the keyfile must be performed by client code */ - public static function getShareKey(\OC_FilesystemView $view, $userId, $filePath) { + public static function getShareKey(\OC_FilesystemView $view, $userId, $util, $filePath) { // try reusing key file if part file $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; - //here we need the currently logged in user, while userId can be a different user - $util = new Util($view, \OCP\User::getUser()); - list($owner, $filename) = $util->getUidAndFilename($filePath); - $filename = self::fixPartialFilePath($filename); + $filename = Helper::stripPartialFileExtension($filename); // in case of system wide mount points the keys are stored directly in the data directory if ($util->isSystemWideMountPoint($filename)) { $shareKeyPath = '/files_encryption/share-keys/' . $filename . '.' . $userId . '.shareKey'; @@ -487,8 +437,9 @@ class Keymanager { $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; - //here we need the currently logged in user, while userId can be a different user - $util = new Util($view, \OCP\User::getUser()); + $userId = Helper::getUser($filePath); + + $util = new Util($view, $userId); list($owner, $filename) = $util->getUidAndFilename($filePath); diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index 6f630c83a3f..4fe76b97711 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -38,8 +38,6 @@ class Proxy extends \OC_FileProxy { private static $blackList = null; //mimetypes blacklisted from encryption - private static $enableEncryption = null; - /** * Check if a file requires encryption * @param string $path @@ -49,46 +47,25 @@ class Proxy extends \OC_FileProxy { */ private static function shouldEncrypt($path) { - if (is_null(self::$enableEncryption)) { - if ( - \OCP\App::isEnabled('files_encryption') === true - && Crypt::mode() === 'server' - ) { - - self::$enableEncryption = true; - - } else { - - self::$enableEncryption = false; - - } - - } - - if (!self::$enableEncryption) { + $userId = Helper::getUser($path); + if (\OCP\App::isEnabled('files_encryption') === false || Crypt::mode() !== 'server' || + strpos($path, '/' . $userId . '/files') !== 0) { return false; - } if (is_null(self::$blackList)) { - self::$blackList = explode(',', \OCP\Config::getAppValue('files_encryption', 'type_blacklist', '')); - } if (Crypt::isCatfileContent($path)) { - return true; - } $extension = substr($path, strrpos($path, '.') + 1); if (array_search($extension, self::$blackList) === false) { - return true; - } return false; @@ -115,7 +92,13 @@ class Proxy extends \OC_FileProxy { return true; } - $handle = fopen('crypt://' . $path . '.etmp', 'w'); + // create random cache folder + $cacheFolder = rand(); + $path_slices = explode('/', \OC_Filesystem::normalizePath($path)); + $path_slices[2] = "cache/".$cacheFolder; + $tmpPath = implode('/', $path_slices); + + $handle = fopen('crypt://' . $tmpPath, 'w'); if (is_resource($handle)) { // write data to stream @@ -129,10 +112,19 @@ class Proxy extends \OC_FileProxy { \OC_FileProxy::$enabled = false; // get encrypted content - $data = $view->file_get_contents($path . '.etmp'); + $data = $view->file_get_contents($tmpPath); + + // update file cache for target file + $tmpFileInfo = $view->getFileInfo($tmpPath); + $fileInfo = $view->getFileInfo($path); + if (is_array($fileInfo) && is_array($tmpFileInfo)) { + $fileInfo['encrypted'] = true; + $fileInfo['unencrypted_size'] = $tmpFileInfo['size']; + $view->putFileInfo($path, $fileInfo); + } // remove our temp file - $view->unlink($path . '.etmp'); + $view->deleteAll('/' . \OCP\User::getUser() . '/cache/' . $cacheFolder); // re-enable proxy - our work is done \OC_FileProxy::$enabled = $proxyStatus; @@ -199,8 +191,11 @@ class Proxy extends \OC_FileProxy { */ public function preUnlink($path) { - // let the trashbin handle this - if (\OCP\App::isEnabled('files_trashbin')) { + $relPath = Helper::stripUserFilesPath($path); + + // skip this method if the trash bin is enabled or if we delete a file + // outside of /data/user/files + if (\OCP\App::isEnabled('files_trashbin') || $relPath === false) { return true; } @@ -214,13 +209,10 @@ class Proxy extends \OC_FileProxy { $util = new Util($view, $userId); - // get relative path - $relativePath = \OCA\Encryption\Helper::stripUserFilesPath($path); - - list($owner, $ownerPath) = $util->getUidAndFilename($relativePath); + list($owner, $ownerPath) = $util->getUidAndFilename($relPath); // Delete keyfile & shareKey so it isn't orphaned - if (!Keymanager::deleteFileKey($view, $owner, $ownerPath)) { + if (!Keymanager::deleteFileKey($view, $ownerPath)) { \OCP\Util::writeLog('Encryption library', 'Keyfile or shareKey could not be deleted for file "' . $ownerPath . '"', \OCP\Util::ERROR); } @@ -263,11 +255,8 @@ class Proxy extends \OC_FileProxy { // split the path parts $pathParts = explode('/', $path); - // get relative path - $relativePath = \OCA\Encryption\Helper::stripUserFilesPath($path); - - // FIXME: handling for /userId/cache used by webdav for chunking. The cache chunks are NOT encrypted - if (isset($pathParts[2]) && $pathParts[2] === 'cache') { + // don't try to encrypt/decrypt cache chunks or files in the trash bin + if (isset($pathParts[2]) && ($pathParts[2] === 'cache' || $pathParts[2] === 'files_trashbin')) { return $result; } @@ -279,7 +268,8 @@ class Proxy extends \OC_FileProxy { $view = new \OC_FilesystemView(''); - $util = new Util($view, \OCP\USER::getUser()); + $userId = Helper::getUser($path); + $util = new Util($view, $userId); // If file is already encrypted, decrypt using crypto protocol if ( @@ -342,6 +332,16 @@ class Proxy extends \OC_FileProxy { $view = new \OC_FilesystemView('/'); + $userId = Helper::getUser($path); + $util = new Util($view, $userId); + + // if encryption is no longer enabled or if the files aren't migrated yet + // we return the default file size + if(!\OCP\App::isEnabled('files_encryption') || + $util->getMigrationStatus() !== Util::MIGRATION_COMPLETED) { + return $size; + } + // if path is a folder do nothing if ($view->is_dir($path)) { return $size; @@ -357,12 +357,24 @@ class Proxy extends \OC_FileProxy { $fileInfo = false; // get file info from database/cache if not .part file - if (!Keymanager::isPartialFilePath($path)) { + if (!Helper::isPartialFilePath($path)) { + $proxyState = \OC_FileProxy::$enabled; + \OC_FileProxy::$enabled = false; $fileInfo = $view->getFileInfo($path); + \OC_FileProxy::$enabled = $proxyState; } // if file is encrypted return real file size if (is_array($fileInfo) && $fileInfo['encrypted'] === true) { + // try to fix unencrypted file size if it doesn't look plausible + if ((int)$fileInfo['size'] > 0 && (int)$fileInfo['unencrypted_size'] === 0 ) { + $fixSize = $util->getFileSize($path); + $fileInfo['unencrypted_size'] = $fixSize; + // put file info if not .part file + if (!Helper::isPartialFilePath($relativePath)) { + $view->putFileInfo($path, $fileInfo); + } + } $size = $fileInfo['unencrypted_size']; } else { // self healing if file was removed from file cache @@ -370,8 +382,6 @@ class Proxy extends \OC_FileProxy { $fileInfo = array(); } - $userId = \OCP\User::getUser(); - $util = new Util($view, $userId); $fixSize = $util->getFileSize($path); if ($fixSize > 0) { $size = $fixSize; @@ -380,7 +390,7 @@ class Proxy extends \OC_FileProxy { $fileInfo['unencrypted_size'] = $size; // put file info if not .part file - if (!Keymanager::isPartialFilePath($relativePath)) { + if (!Helper::isPartialFilePath($relativePath)) { $view->putFileInfo($path, $fileInfo); } } @@ -400,7 +410,7 @@ class Proxy extends \OC_FileProxy { $view = new \OC_FilesystemView('/'); $session = new \OCA\Encryption\Session($view); - $userId = \OCP\User::getUser(); + $userId = Helper::getUser($path); $util = new Util($view, $userId); // split the path parts diff --git a/apps/files_encryption/lib/stream.php b/apps/files_encryption/lib/stream.php index 02955bb064e..b3bf34ddb82 100644 --- a/apps/files_encryption/lib/stream.php +++ b/apps/files_encryption/lib/stream.php @@ -55,6 +55,7 @@ class Stream { private $rawPath; // The raw path relative to the data dir private $relPath; // rel path to users file dir private $userId; + private $keyId; private $handle; // Resource returned by fopen private $meta = array(); // Header / meta for source stream private $writeCache; @@ -63,10 +64,14 @@ class Stream { private $publicKey; private $encKeyfile; private $newFile; // helper var, we only need to write the keyfile for new files + private $isLocalTmpFile = false; // do we operate on a local tmp file + private $localTmpFile; // path of local tmp file + /** * @var \OC\Files\View */ private $rootView; // a fsview object set to '/' + /** * @var \OCA\Encryption\Session */ @@ -91,14 +96,24 @@ class Stream { $this->session = new \OCA\Encryption\Session($this->rootView); - $this->privateKey = $this->session->getPrivateKey($this->userId); + $this->privateKey = $this->session->getPrivateKey(); + + $normalizedPath = \OC\Files\Filesystem::normalizePath(str_replace('crypt://', '', $path)); + if ($originalFile = Helper::getPathFromTmpFile($normalizedPath)) { + $this->rawPath = $originalFile; + $this->isLocalTmpFile = true; + $this->localTmpFile = $normalizedPath; + } else { + $this->rawPath = $normalizedPath; + } - $util = new Util($this->rootView, \OCP\USER::getUser()); + $this->userId = Helper::getUser($this->rawPath); - $this->userId = $util->getUserId(); + $util = new Util($this->rootView, $this->userId); - // rawPath is relative to the data directory - $this->rawPath = \OC\Files\Filesystem::normalizePath(str_replace('crypt://', '', $path)); + // get the key ID which we want to use, can be the users key or the + // public share key + $this->keyId = $util->getKeyId(); // Strip identifier text from path, this gives us the path relative to data/<user>/files $this->relPath = Helper::stripUserFilesPath($this->rawPath); @@ -108,7 +123,7 @@ class Stream { } if($this->relPath === false) { - \OCP\Util::writeLog('Encryption library', 'failed to open file "' . $this->rawPath . '" expecting a path to user/files or to user/files_versions', \OCP\Util::ERROR); + \OCP\Util::writeLog('Encryption library', 'failed to open file "' . $this->rawPath . '" expecting a path to "files", "files_versions" or "cache"', \OCP\Util::ERROR); return false; } @@ -134,10 +149,14 @@ class Stream { \OCA\Encryption\Helper::redirectToErrorPage($this->session); } - $this->size = $this->rootView->filesize($this->rawPath, $mode); + $this->size = $this->rootView->filesize($this->rawPath); } - $this->handle = $this->rootView->fopen($this->rawPath, $mode); + if ($this->isLocalTmpFile) { + $this->handle = fopen($this->localTmpFile, $mode); + } else { + $this->handle = $this->rootView->fopen($this->rawPath, $mode); + } \OC_FileProxy::$enabled = $proxyStatus; @@ -157,14 +176,25 @@ class Stream { } /** + * @brief Returns the current position of the file pointer + * @return int position of the file pointer + */ + public function stream_tell() { + return ftell($this->handle); + } + + /** * @param $offset * @param int $whence + * @return bool true if fseek was successful, otherwise false */ public function stream_seek($offset, $whence = SEEK_SET) { $this->flush(); - fseek($this->handle, $offset, $whence); + // this wrapper needs to return "true" for success. + // the fseek call itself returns 0 on succeess + return !fseek($this->handle, $offset, $whence); } @@ -249,21 +279,26 @@ class Stream { // Fetch and decrypt keyfile // Fetch existing keyfile - $this->encKeyfile = Keymanager::getFileKey($this->rootView, $this->userId, $this->relPath); + $util = new \OCA\Encryption\Util($this->rootView, $this->userId); + $this->encKeyfile = Keymanager::getFileKey($this->rootView, $util, $this->relPath); // If a keyfile already exists if ($this->encKeyfile) { + $shareKey = Keymanager::getShareKey($this->rootView, $this->keyId, $util, $this->relPath); + // if there is no valid private key return false if ($this->privateKey === false) { - // if private key is not valid redirect user to a error page - \OCA\Encryption\Helper::redirectToErrorPage(); - + \OCA\Encryption\Helper::redirectToErrorPage($this->session); return false; } - $shareKey = Keymanager::getShareKey($this->rootView, $this->userId, $this->relPath); + if ($shareKey === false) { + // if no share key is available redirect user to a error page + \OCA\Encryption\Helper::redirectToErrorPage($this->session, \OCA\Encryption\Crypt::ENCRYPTION_NO_SHARE_KEY_FOUND); + return false; + } $this->plainKey = Crypt::multiKeyDecrypt($this->encKeyfile, $shareKey, $this->privateKey); @@ -465,7 +500,7 @@ class Stream { if ($this->privateKey === false) { // cleanup - if ($this->meta['mode'] !== 'r' && $this->meta['mode'] !== 'rb') { + if ($this->meta['mode'] !== 'r' && $this->meta['mode'] !== 'rb' && !$this->isLocalTmpFile) { // Disable encryption proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; @@ -480,13 +515,15 @@ class Stream { } // if private key is not valid redirect user to a error page - \OCA\Encryption\Helper::redirectToErrorPage(); + \OCA\Encryption\Helper::redirectToErrorPage($this->session); } if ( $this->meta['mode'] !== 'r' && $this->meta['mode'] !== 'rb' && - $this->size > 0 + $this->isLocalTmpFile === false && + $this->size > 0 && + $this->unencryptedSize > 0 ) { // only write keyfiles if it was a new file @@ -497,7 +534,7 @@ class Stream { \OC_FileProxy::$enabled = false; // Fetch user's public key - $this->publicKey = Keymanager::getPublicKey($this->rootView, $this->userId); + $this->publicKey = Keymanager::getPublicKey($this->rootView, $this->keyId); // Check if OC sharing api is enabled $sharingEnabled = \OCP\Share::isEnabled(); @@ -506,37 +543,40 @@ class Stream { // Get all users sharing the file includes current user $uniqueUserIds = $util->getSharingUsersArray($sharingEnabled, $this->relPath, $this->userId); + $checkedUserIds = $util->filterShareReadyUsers($uniqueUserIds); // Fetch public keys for all sharing users - $publicKeys = Keymanager::getPublicKeys($this->rootView, $uniqueUserIds); + $publicKeys = Keymanager::getPublicKeys($this->rootView, $checkedUserIds['ready']); // Encrypt enc key for all sharing users $this->encKeyfiles = Crypt::multiKeyEncrypt($this->plainKey, $publicKeys); // Save the new encrypted file key - Keymanager::setFileKey($this->rootView, $this->relPath, $this->userId, $this->encKeyfiles['data']); + Keymanager::setFileKey($this->rootView, $util, $this->relPath, $this->encKeyfiles['data']); // Save the sharekeys - Keymanager::setShareKeys($this->rootView, $this->relPath, $this->encKeyfiles['keys']); + Keymanager::setShareKeys($this->rootView, $util, $this->relPath, $this->encKeyfiles['keys']); // Re-enable proxy - our work is done \OC_FileProxy::$enabled = $proxyStatus; } + // we need to update the file info for the real file, not for the + // part file. + $path = Helper::stripPartialFileExtension($this->rawPath); + // get file info - $fileInfo = $this->rootView->getFileInfo($this->rawPath); - if (!is_array($fileInfo)) { - $fileInfo = array(); + $fileInfo = $this->rootView->getFileInfo($path); + if (is_array($fileInfo)) { + // set encryption data + $fileInfo['encrypted'] = true; + $fileInfo['size'] = $this->size; + $fileInfo['unencrypted_size'] = $this->unencryptedSize; + + // set fileinfo + $this->rootView->putFileInfo($path, $fileInfo); } - // set encryption data - $fileInfo['encrypted'] = true; - $fileInfo['size'] = $this->size; - $fileInfo['unencrypted_size'] = $this->unencryptedSize; - - // set fileinfo - $this->rootView->putFileInfo($this->rawPath, $fileInfo); - } return fclose($this->handle); diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index 53d58fbf40d..8a5dfabeec1 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -38,7 +38,8 @@ class Util { const MIGRATION_OPEN = 0; // user still needs to be migrated private $view; // OC_FilesystemView object for filesystem operations - private $userId; // ID of the currently logged-in user + private $userId; // ID of the user we use to encrypt/decrypt files + private $keyId; // ID of the key we want to manipulate private $client; // Client side encryption mode flag private $publicKeyDir; // Dir containing all public user keys private $encryptionDir; // Dir containing user's files_encryption @@ -58,47 +59,33 @@ class Util { public function __construct(\OC_FilesystemView $view, $userId, $client = false) { $this->view = $view; - $this->userId = $userId; $this->client = $client; - $this->isPublic = false; + $this->userId = $userId; $this->publicShareKeyId = \OC_Appconfig::getValue('files_encryption', 'publicShareKeyId'); $this->recoveryKeyId = \OC_Appconfig::getValue('files_encryption', 'recoveryKeyId'); - // if we are anonymous/public - if (\OCA\Encryption\Helper::isPublicAccess()) { - $this->userId = $this->publicShareKeyId; - - // only handle for files_sharing app - if (isset($GLOBALS['app']) && $GLOBALS['app'] === 'files_sharing') { - $this->userDir = '/' . $GLOBALS['fileOwner']; - $this->fileFolderName = 'files'; - $this->userFilesDir = '/' . $GLOBALS['fileOwner'] . '/' - . $this->fileFolderName; // TODO: Does this need to be user configurable? - $this->publicKeyDir = '/' . 'public-keys'; - $this->encryptionDir = '/' . $GLOBALS['fileOwner'] . '/' . 'files_encryption'; - $this->keyfilesPath = $this->encryptionDir . '/' . 'keyfiles'; - $this->shareKeysPath = $this->encryptionDir . '/' . 'share-keys'; - $this->publicKeyPath = - $this->publicKeyDir . '/' . $this->userId . '.public.key'; // e.g. data/public-keys/admin.public.key - $this->privateKeyPath = - '/owncloud_private_key/' . $this->userId . '.private.key'; // e.g. data/admin/admin.private.key - $this->isPublic = true; - } - - } else { - $this->userDir = '/' . $this->userId; - $this->fileFolderName = 'files'; - $this->userFilesDir = - '/' . $this->userId . '/' . $this->fileFolderName; // TODO: Does this need to be user configurable? - $this->publicKeyDir = '/' . 'public-keys'; - $this->encryptionDir = '/' . $this->userId . '/' . 'files_encryption'; - $this->keyfilesPath = $this->encryptionDir . '/' . 'keyfiles'; - $this->shareKeysPath = $this->encryptionDir . '/' . 'share-keys'; - $this->publicKeyPath = + $this->userDir = '/' . $this->userId; + $this->fileFolderName = 'files'; + $this->userFilesDir = + '/' . $userId . '/' . $this->fileFolderName; // TODO: Does this need to be user configurable? + $this->publicKeyDir = '/' . 'public-keys'; + $this->encryptionDir = '/' . $this->userId . '/' . 'files_encryption'; + $this->keyfilesPath = $this->encryptionDir . '/' . 'keyfiles'; + $this->shareKeysPath = $this->encryptionDir . '/' . 'share-keys'; + $this->publicKeyPath = $this->publicKeyDir . '/' . $this->userId . '.public.key'; // e.g. data/public-keys/admin.public.key - $this->privateKeyPath = + $this->privateKeyPath = $this->encryptionDir . '/' . $this->userId . '.private.key'; // e.g. data/admin/admin.private.key + // make sure that the owners home is mounted + \OC\Files\Filesystem::initMountPoints($userId); + + if (\OCA\Encryption\Helper::isPublicAccess()) { + $this->keyId = $this->publicShareKeyId; + $this->isPublic = true; + } else { + $this->keyId = $this->userId; + $this->isPublic = false; } } @@ -114,15 +101,24 @@ class Util { or !$this->view->file_exists($this->publicKeyPath) or !$this->view->file_exists($this->privateKeyPath) ) { - return false; - } else { - return true; - } + } + /** + * @brief check if the users private & public key exists + * @return boolean + */ + public function userKeysExists() { + if ( + $this->view->file_exists($this->privateKeyPath) && + $this->view->file_exists($this->publicKeyPath)) { + return true; + } else { + return false; + } } /** @@ -184,13 +180,13 @@ class Util { // check if public-key exists but private-key is missing if ($this->view->file_exists($this->publicKeyPath) && !$this->view->file_exists($this->privateKeyPath)) { \OCP\Util::writeLog('Encryption library', - 'public key exists but private key is missing for "' . $this->userId . '"', \OCP\Util::FATAL); + 'public key exists but private key is missing for "' . $this->keyId . '"', \OCP\Util::FATAL); return false; } else { if (!$this->view->file_exists($this->publicKeyPath) && $this->view->file_exists($this->privateKeyPath) ) { \OCP\Util::writeLog('Encryption library', - 'private key exists but public key is missing for "' . $this->userId . '"', \OCP\Util::FATAL); + 'private key exists but public key is missing for "' . $this->keyId . '"', \OCP\Util::FATAL); return false; } } @@ -205,7 +201,7 @@ class Util { $this->userId, 'server-side', 0, - 0 + self::MIGRATION_OPEN ); $query = \OCP\DB::prepare($sql); $query->execute($args); @@ -245,11 +241,9 @@ class Util { if (\OCP\DB::isError($result)) { \OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); } else { - if ($result->numRows() > 0) { - $row = $result->fetchRow(); - if (isset($row['recovery_enabled'])) { - $recoveryEnabled[] = $row['recovery_enabled']; - } + $row = $result->fetchRow(); + if ($row && isset($row['recovery_enabled'])) { + $recoveryEnabled[] = $row['recovery_enabled']; } } @@ -293,7 +287,7 @@ class Util { $sql = 'UPDATE `*PREFIX*encryption` SET `recovery_enabled` = ? WHERE `uid` = ?'; $args = array( - $enabled, + $enabled ? '1' : '0', $this->userId ); @@ -363,7 +357,7 @@ class Util { // scanning every file like this // will eat server resources :( if ( - Keymanager::getFileKey($this->view, $this->userId, $relPath) + Keymanager::getFileKey($this->view, $this, $relPath) && $isEncryptedPath ) { @@ -419,49 +413,6 @@ class Util { } /** - * @brief Fetch the last lines of a file efficiently - * @note Safe to use on large files; does not read entire file to memory - * @note Derivative of http://tekkie.flashbit.net/php/tail-functionality-in-php - */ - public function tail($filename, $numLines) { - - \OC_FileProxy::$enabled = false; - - $text = ''; - $pos = -1; - $handle = $this->view->fopen($filename, 'r'); - - while ($numLines > 0) { - - --$pos; - - if (fseek($handle, $pos, SEEK_END) !== 0) { - - rewind($handle); - $numLines = 0; - - } elseif (fgetc($handle) === "\n") { - - --$numLines; - - } - - $block_size = (-$pos) % 8192; - if ($block_size === 0 || $numLines === 0) { - - $text = fread($handle, ($block_size === 0 ? 8192 : $block_size)) . $text; - - } - } - - fclose($handle); - - \OC_FileProxy::$enabled = true; - - return $text; - } - - /** * @brief Check if a given path identifies an encrypted file * @param string $path * @return boolean @@ -476,15 +427,28 @@ class Util { // we only need 24 byte from the last chunk $data = ''; $handle = $this->view->fopen($path, 'r'); - if (is_resource($handle) && !fseek($handle, -24, SEEK_END)) { - $data = fgets($handle); + if (is_resource($handle)) { + // suppress fseek warining, we handle the case that fseek doesn't + // work in the else branch + if (@fseek($handle, -24, SEEK_END) === 0) { + $data = fgets($handle); + } else { + // if fseek failed on the storage we create a local copy from the file + // and read this one + fclose($handle); + $localFile = $this->view->getLocalFile($path); + $handle = fopen($localFile, 'r'); + if (is_resource($handle) && fseek($handle, -24, SEEK_END) === 0) { + $data = fgets($handle); + } + } + fclose($handle); } // re-enable proxy \OC_FileProxy::$enabled = $proxyStatus; return Crypt::isCatfileContent($data); - } /** @@ -508,11 +472,18 @@ class Util { ) { // get the size from filesystem - $fullPath = $this->view->getLocalFile($path); $size = $this->view->filesize($path); + // fast path, else the calculation for $lastChunkNr is bogus + if ($size === 0) { + \OC_FileProxy::$enabled = $proxyStatus; + return 0; + } + // calculate last chunk nr - $lastChunkNr = floor($size / 8192); + // next highest is end of chunks, one subtracted is last one + // we have to read the last chunk, we can't just calculate it (because of padding etc) + $lastChunkNr = ceil($size/ 8192) - 1; $lastChunkSize = $size - ($lastChunkNr * 8192); // open stream @@ -523,7 +494,20 @@ class Util { $lastChunckPos = ($lastChunkNr * 8192); // seek to end - fseek($stream, $lastChunckPos); + if (@fseek($stream, $lastChunckPos) === -1) { + // storage doesn't support fseek, we need a local copy + fclose($stream); + $localFile = $this->view->getLocalFile($path); + Helper::addTmpFileToMapper($localFile, $path); + $stream = fopen('crypt://' . $localFile, "r"); + if (fseek($stream, $lastChunckPos) === -1) { + // if fseek also fails on the local storage, than + // there is nothing we can do + fclose($stream); + \OCP\Util::writeLog('Encryption library', 'couldn\'t determine size of "' . $path, \OCP\Util::ERROR); + return $result; + } + } // get the content of the last chunk $lastChunkContent = fread($stream, $lastChunkSize); @@ -710,17 +694,17 @@ class Util { // Encrypt unencrypted files foreach ($found['encrypted'] as $encryptedFile) { - //get file info - $fileInfo = \OC\Files\Filesystem::getFileInfo($encryptedFile['path']); - //relative to data/<user>/file $relPath = Helper::stripUserFilesPath($encryptedFile['path']); + //get file info + $fileInfo = \OC\Files\Filesystem::getFileInfo($relPath); + //relative to /data $rawPath = $encryptedFile['path']; //get timestamp - $timestamp = $this->view->filemtime($rawPath); + $timestamp = $fileInfo['mtime']; //enable proxy to use OC\Files\View to access the original file \OC_FileProxy::$enabled = true; @@ -761,16 +745,16 @@ class Util { $this->view->rename($relPath . '.part', $relPath); - $this->view->chroot($fakeRoot); - //set timestamp - $this->view->touch($rawPath, $timestamp); + $this->view->touch($relPath, $timestamp); + + $this->view->chroot($fakeRoot); // Add the file to the cache \OC\Files\Filesystem::putFileInfo($relPath, array( 'encrypted' => false, 'size' => $size, - 'unencrypted_size' => $size, + 'unencrypted_size' => 0, 'etag' => $fileInfo['etag'] )); @@ -832,7 +816,7 @@ class Util { $rawPath = '/' . $this->userId . '/files/' . $plainFile['path']; // keep timestamp - $timestamp = $this->view->filemtime($rawPath); + $timestamp = $fileInfo['mtime']; // Open plain file handle for binary reading $plainHandle = $this->view->fopen($rawPath, 'rb'); @@ -840,32 +824,35 @@ class Util { // Open enc file handle for binary writing, with same filename as original plain file $encHandle = fopen('crypt://' . $rawPath . '.part', 'wb'); - // Move plain file to a temporary location - $size = stream_copy_to_stream($plainHandle, $encHandle); + if (is_resource($encHandle)) { + // Move plain file to a temporary location + $size = stream_copy_to_stream($plainHandle, $encHandle); - fclose($encHandle); - fclose($plainHandle); + fclose($encHandle); + fclose($plainHandle); - $fakeRoot = $this->view->getRoot(); - $this->view->chroot('/' . $this->userId . '/files'); + $fakeRoot = $this->view->getRoot(); + $this->view->chroot('/' . $this->userId . '/files'); - $this->view->rename($relPath . '.part', $relPath); + $this->view->rename($relPath . '.part', $relPath); - $this->view->chroot($fakeRoot); + // set timestamp + $this->view->touch($relPath, $timestamp); - // set timestamp - $this->view->touch($rawPath, $timestamp); + $encSize = $this->view->filesize($relPath); - // Add the file to the cache - \OC\Files\Filesystem::putFileInfo($relPath, array( - 'encrypted' => true, - 'size' => $size, - 'unencrypted_size' => $size, - 'etag' => $fileInfo['etag'] - )); + $this->view->chroot($fakeRoot); - $encryptedFiles[] = $relPath; + // Add the file to the cache + \OC\Files\Filesystem::putFileInfo($relPath, array( + 'encrypted' => true, + 'size' => $encSize, + 'unencrypted_size' => $size, + 'etag' => $fileInfo['etag'] + )); + $encryptedFiles[] = $relPath; + } } // Encrypt legacy encrypted files @@ -982,8 +969,8 @@ class Util { if (\OCP\DB::isError($result)) { \OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); } else { - if ($result->numRows() > 0) { - $row = $result->fetchRow(); + $row = $result->fetchRow(); + if ($row) { $path = substr($row['path'], strlen('files')); } } @@ -1048,10 +1035,10 @@ class Util { private function decryptKeyfile($filePath, $privateKey) { // Get the encrypted keyfile - $encKeyfile = Keymanager::getFileKey($this->view, $this->userId, $filePath); + $encKeyfile = Keymanager::getFileKey($this->view, $this, $filePath); // The file has a shareKey and must use it for decryption - $shareKey = Keymanager::getShareKey($this->view, $this->userId, $filePath); + $shareKey = Keymanager::getShareKey($this->view, $this->keyId, $this, $filePath); $plainKeyfile = Crypt::multiKeyDecrypt($encKeyfile, $shareKey, $privateKey); @@ -1102,8 +1089,8 @@ class Util { // Save the recrypted key to it's owner's keyfiles directory // Save new sharekeys to all necessary user directory if ( - !Keymanager::setFileKey($this->view, $filePath, $fileOwner, $multiEncKey['data']) - || !Keymanager::setShareKeys($this->view, $filePath, $multiEncKey['keys']) + !Keymanager::setFileKey($this->view, $this, $filePath, $multiEncKey['data']) + || !Keymanager::setShareKeys($this->view, $this, $filePath, $multiEncKey['keys']) ) { \OCP\Util::writeLog('Encryption library', @@ -1138,10 +1125,7 @@ class Util { // Make sure that a share key is generated for the owner too list($owner, $ownerPath) = $this->getUidAndFilename($filePath); - $pathinfo = pathinfo($ownerPath); - if(array_key_exists('extension', $pathinfo) && $pathinfo['extension'] === 'part') { - $ownerPath = $pathinfo['dirname'] . '/' . $pathinfo['filename']; - } + $ownerPath = \OCA\Encryption\Helper::stripPartialFileExtension($ownerPath); $userIds = array(); if ($sharingEnabled) { @@ -1257,7 +1241,6 @@ class Util { $sql = 'SELECT `migration_status` FROM `*PREFIX*encryption` WHERE `uid` = ?'; $args = array($this->userId); - $query = \OCP\DB::prepare($sql); $result = $query->execute($args); @@ -1267,20 +1250,32 @@ class Util { if (\OCP\DB::isError($result)) { \OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); } else { - if ($result->numRows() > 0) { - $row = $result->fetchRow(); - if (isset($row['migration_status'])) { - $migrationStatus[] = $row['migration_status']; - } + $row = $result->fetchRow(); + if ($row && isset($row['migration_status'])) { + $migrationStatus[] = $row['migration_status']; } } // If no record is found if (empty($migrationStatus)) { \OCP\Util::writeLog('Encryption library', "Could not get migration status for " . $this->userId . ", no record found", \OCP\Util::ERROR); - return false; - // If a record is found - } else { + // insert missing entry in DB with status open if the user exists + if (\OCP\User::userExists($this->userId)) { + $sql = 'INSERT INTO `*PREFIX*encryption` (`uid`,`mode`,`recovery_enabled`,`migration_status`) VALUES (?,?,?,?)'; + $args = array( + $this->userId, + 'server-side', + 0, + self::MIGRATION_OPEN + ); + $query = \OCP\DB::prepare($sql); + $query->execute($args); + + return self::MIGRATION_OPEN; + } else { + return false; + } + } else { // If a record is found return (int)$migrationStatus[0]; } @@ -1319,7 +1314,7 @@ class Util { // handle public access if ($this->isPublic) { $filename = $path; - $fileOwnerUid = $GLOBALS['fileOwner']; + $fileOwnerUid = $this->userId; return array( $fileOwnerUid, @@ -1437,9 +1432,7 @@ class Util { if (\OCP\DB::isError($result)) { \OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); } else { - if ($result->numRows() > 0) { - $row = $result->fetchRow(); - } + $row = $result->fetchRow(); } return $row; @@ -1463,9 +1456,7 @@ class Util { if (\OCP\DB::isError($result)) { \OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); } else { - if ($result->numRows() > 0) { - $row = $result->fetchRow(); - } + $row = $result->fetchRow(); } return $row; @@ -1484,18 +1475,16 @@ class Util { $result = $query->execute(array($id)); - $source = array(); + $source = null; if (\OCP\DB::isError($result)) { \OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); } else { - if ($result->numRows() > 0) { - $source = $result->fetchRow(); - } + $source = $result->fetchRow(); } $fileOwner = false; - if (isset($source['parent'])) { + if ($source && isset($source['parent'])) { $parent = $source['parent']; @@ -1505,16 +1494,14 @@ class Util { $result = $query->execute(array($parent)); - $item = array(); + $item = null; if (\OCP\DB::isError($result)) { \OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); } else { - if ($result->numRows() > 0) { - $item = $result->fetchRow(); - } + $item = $result->fetchRow(); } - if (isset($item['parent'])) { + if ($item && isset($item['parent'])) { $parent = $item['parent']; @@ -1547,6 +1534,13 @@ class Util { /** * @return string */ + public function getKeyId() { + return $this->keyId; + } + + /** + * @return string + */ public function getUserFilesDir() { return $this->userFilesDir; } diff --git a/apps/files_encryption/settings-admin.php b/apps/files_encryption/settings-admin.php index 53676058982..9ad9bfb8877 100644 --- a/apps/files_encryption/settings-admin.php +++ b/apps/files_encryption/settings-admin.php @@ -11,9 +11,7 @@ $tmpl = new OCP\Template('files_encryption', 'settings-admin'); // Check if an adminRecovery account is enabled for recovering files after lost pwd -$view = new OC_FilesystemView(''); - -$recoveryAdminEnabled = OC_Appconfig::getValue('files_encryption', 'recoveryAdminEnabled'); +$recoveryAdminEnabled = OC_Appconfig::getValue('files_encryption', 'recoveryAdminEnabled', '0'); $tmpl->assign('recoveryEnabled', $recoveryAdminEnabled); diff --git a/apps/files_encryption/templates/invalid_private_key.php b/apps/files_encryption/templates/invalid_private_key.php index 9af65f831b4..a3cae60b1da 100644 --- a/apps/files_encryption/templates/invalid_private_key.php +++ b/apps/files_encryption/templates/invalid_private_key.php @@ -4,7 +4,7 @@ <?php p($_['message']); ?> <br/> - <?php if($_['init']): ?> + <?php if($_['errorCode'] === \OCA\Encryption\Crypt::ENCRYPTION_PRIVATE_KEY_NOT_VALID_ERROR): ?> <?php>p($l->t('Go directly to your ')); ?> <a href="<?php echo $location?>"><?php p($l->t('personal settings')); ?>.</a> <?php endif; ?> <br/> diff --git a/apps/files_encryption/templates/settings-admin.php b/apps/files_encryption/templates/settings-admin.php index 3a6adc09f4b..231a68b6a58 100644 --- a/apps/files_encryption/templates/settings-admin.php +++ b/apps/files_encryption/templates/settings-admin.php @@ -1,10 +1,7 @@ <form id="encryption"> <fieldset class="personalblock"> - <p> - <strong><?php p($l->t('Encryption')); ?></strong> - <br/> - </p> + <h2><?php p($l->t('Encryption')); ?></h2> <p> <?php p($l->t("Enable recovery key (allow to recover users files in case of password loss):")); ?> diff --git a/apps/files_encryption/templates/settings-personal.php b/apps/files_encryption/templates/settings-personal.php index ff04556dd53..1b4239d82cd 100644 --- a/apps/files_encryption/templates/settings-personal.php +++ b/apps/files_encryption/templates/settings-personal.php @@ -1,10 +1,8 @@ <form id="encryption">
<fieldset class="personalblock">
- <legend>
- <?php p( $l->t( 'Encryption' ) ); ?>
- </legend>
+ <h2><?php p( $l->t( 'Encryption' ) ); ?></h2>
- <?php if ( ! $_["privateKeySet"] && $_["initialized"] ): ?>
+ <?php if ( $_["initialized"] === '1' ): ?>
<p>
<a name="changePKPasswd" />
<label for="changePrivateKeyPasswd">
@@ -38,9 +36,8 @@ </p>
<?php endif; ?>
- <br />
-
<?php if ( $_["recoveryEnabled"] && $_["privateKeySet"] ): ?>
+ <br />
<p>
<label for="userEnableRecovery"><?php p( $l->t( "Enable password recovery:" ) ); ?></label>
<br />
@@ -65,6 +62,5 @@ </p>
<?php endif; ?>
- <br />
</fieldset>
</form>
diff --git a/apps/files_encryption/tests/crypt.php b/apps/files_encryption/tests/crypt.php index 5146613e252..ca14e3e2ccb 100755 --- a/apps/files_encryption/tests/crypt.php +++ b/apps/files_encryption/tests/crypt.php @@ -157,6 +157,8 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { $filename = 'tmp-' . time() . '.test'; + $util = new Encryption\Util(new \OC_FilesystemView(), $this->userId); + $cryptedFile = file_put_contents('crypt:///' . $this->userId . '/files/'. $filename, $this->dataShort); // Test that data was successfully written @@ -176,10 +178,10 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { $this->assertNotEquals($this->dataShort, $retreivedCryptedFile); // Get the encrypted keyfile - $encKeyfile = Encryption\Keymanager::getFileKey($this->view, $this->userId, $filename); + $encKeyfile = Encryption\Keymanager::getFileKey($this->view, $util, $filename); // Attempt to fetch the user's shareKey - $shareKey = Encryption\Keymanager::getShareKey($this->view, $this->userId, $filename); + $shareKey = Encryption\Keymanager::getShareKey($this->view, $this->userId, $util, $filename); // get session $session = new \OCA\Encryption\Session($this->view); @@ -199,7 +201,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { // Teardown $this->view->unlink($this->userId . '/files/' . $filename); - Encryption\Keymanager::deleteFileKey($this->view, $this->userId, $filename); + Encryption\Keymanager::deleteFileKey($this->view, $filename); } /** @@ -214,6 +216,8 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { // Generate a a random filename $filename = 'tmp-' . time() . '.test'; + $util = new Encryption\Util(new \OC_FilesystemView(), $this->userId); + // Save long data as encrypted file using stream wrapper $cryptedFile = file_put_contents('crypt:///' . $this->userId . '/files/' . $filename, $this->dataLong . $this->dataLong); @@ -244,16 +248,16 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { $i = 0; while ($i < count($r)-1) { $e[] = $r[$i] . $r[$i+1]; - $i = $i + 2; + $i = $i + 2; } //print_r($e); // Get the encrypted keyfile - $encKeyfile = Encryption\Keymanager::getFileKey($this->view, $this->userId, $filename); + $encKeyfile = Encryption\Keymanager::getFileKey($this->view, $util, $filename); // Attempt to fetch the user's shareKey - $shareKey = Encryption\Keymanager::getShareKey($this->view, $this->userId, $filename); + $shareKey = Encryption\Keymanager::getShareKey($this->view, $this->userId, $util, $filename); // get session $session = new \OCA\Encryption\Session($this->view); @@ -283,7 +287,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { $this->view->unlink($this->userId . '/files/' . $filename); - Encryption\Keymanager::deleteFileKey($this->view, $this->userId, $filename); + Encryption\Keymanager::deleteFileKey($this->view, $filename); } @@ -387,7 +391,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { * @brief test decryption using legacy blowfish method */ function testLegacyDecryptShort() { - + $crypted = $this->legacyEncrypt($this->dataShort, $this->pass); $decrypted = Encryption\Crypt::legacyBlockDecrypt($crypted, $this->pass); @@ -401,7 +405,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { * @brief test decryption using legacy blowfish method */ function testLegacyDecryptLong() { - + $crypted = $this->legacyEncrypt($this->dataLong, $this->pass); $decrypted = Encryption\Crypt::legacyBlockDecrypt($crypted, $this->pass); @@ -653,8 +657,8 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { // tear down $view->unlink($filename); } - - + + /** * @brief encryption using legacy blowfish method * @param $data string data to encrypt diff --git a/apps/files_encryption/tests/helper.php b/apps/files_encryption/tests/helper.php new file mode 100644 index 00000000000..4b46e976b81 --- /dev/null +++ b/apps/files_encryption/tests/helper.php @@ -0,0 +1,104 @@ +<?php +/** + * Copyright (c) 2013 Bjoern Schiessle <schiessle@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + + +require_once __DIR__ . '/../lib/helper.php'; +require_once __DIR__ . '/util.php'; + +use OCA\Encryption; + +/** + * Class Test_Encryption_Helper + */ +class Test_Encryption_Helper extends \PHPUnit_Framework_TestCase { + + const TEST_ENCRYPTION_HELPER_USER1 = "test-helper-user1"; + + public static function setUpBeforeClass() { + // create test user + \Test_Encryption_Util::loginHelper(\Test_Encryption_Helper::TEST_ENCRYPTION_HELPER_USER1, true); + } + + public static function tearDownAfterClass() { + // cleanup test user + \OC_User::deleteUser(\Test_Encryption_Helper::TEST_ENCRYPTION_HELPER_USER1); + } + + /** + * @medium + */ + function testStripPartialFileExtension() { + + $partFilename = 'testfile.txt.part'; + $filename = 'testfile.txt'; + + $this->assertTrue(Encryption\Helper::isPartialFilePath($partFilename)); + + $this->assertEquals('testfile.txt', Encryption\Helper::stripPartialFileExtension($partFilename)); + + $this->assertFalse(Encryption\Helper::isPartialFilePath($filename)); + + $this->assertEquals('testfile.txt', Encryption\Helper::stripPartialFileExtension($filename)); + } + + + /** + * @medium + */ + function testStripPartialFileExtensionWithTransferIdPath() { + + $partFilename = 'testfile.txt.ocTransferId643653835.part'; + $filename = 'testfile.txt'; + + $this->assertTrue(Encryption\Helper::isPartialFilePath($partFilename)); + + $this->assertEquals('testfile.txt', Encryption\Helper::stripPartialFileExtension($partFilename)); + + $this->assertFalse(Encryption\Helper::isPartialFilePath($filename)); + + $this->assertEquals('testfile.txt', Encryption\Helper::stripPartialFileExtension($filename)); + } + + function testGetPathToRealFile() { + + // the relative path to /user/files/ that's what we want to get from getPathToRealFile() + $relativePath = "foo/bar/test.txt"; + + // test paths + $versionPath = "/user/files_versions/foo/bar/test.txt.v456756835"; + $cachePath = "/user/cache/transferid636483/foo/bar/test.txt"; + + $this->assertEquals($relativePath, Encryption\Helper::getPathToRealFile($versionPath)); + $this->assertEquals($relativePath, Encryption\Helper::getPathToRealFile($cachePath)); + } + + function testGetUser() { + + $path1 = "/" . self::TEST_ENCRYPTION_HELPER_USER1 . "/files/foo/bar.txt"; + $path2 = "/" . self::TEST_ENCRYPTION_HELPER_USER1 . "/cache/foo/bar.txt"; + $path3 = "/" . self::TEST_ENCRYPTION_HELPER_USER1 . "/thumbnails/foo"; + $path4 ="/" . "/" . self::TEST_ENCRYPTION_HELPER_USER1; + + // if we are logged-in every path should return the currently logged-in user + $this->assertEquals(self::TEST_ENCRYPTION_HELPER_USER1, Encryption\Helper::getUser($path3)); + + // now log out + \Test_Encryption_Util::logoutHelper(); + + // now we should only get the user from /user/files and user/cache paths + $this->assertEquals(self::TEST_ENCRYPTION_HELPER_USER1, Encryption\Helper::getUser($path1)); + $this->assertEquals(self::TEST_ENCRYPTION_HELPER_USER1, Encryption\Helper::getUser($path2)); + + $this->assertFalse(Encryption\Helper::getUser($path3)); + $this->assertFalse(Encryption\Helper::getUser($path4)); + + // Log-in again + \Test_Encryption_Util::loginHelper(\Test_Encryption_Helper::TEST_ENCRYPTION_HELPER_USER1); + } + +} diff --git a/apps/files_encryption/tests/keymanager.php b/apps/files_encryption/tests/keymanager.php index b2d200cca3e..1467979f005 100644 --- a/apps/files_encryption/tests/keymanager.php +++ b/apps/files_encryption/tests/keymanager.php @@ -145,13 +145,15 @@ class Test_Encryption_Keymanager extends \PHPUnit_Framework_TestCase { $file = 'unittest-' . time() . '.txt'; + $util = new Encryption\Util($this->view, $this->userId); + // Disable encryption proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; $this->view->file_put_contents($this->userId . '/files/' . $file, $this->dataShort); - Encryption\Keymanager::setFileKey($this->view, $file, $this->userId, $key); + Encryption\Keymanager::setFileKey($this->view, $util, $file, $key); $this->assertTrue($this->view->file_exists('/' . $this->userId . '/files_encryption/keyfiles/' . $file . '.key')); @@ -191,23 +193,6 @@ class Test_Encryption_Keymanager extends \PHPUnit_Framework_TestCase { /** * @medium */ - function testFixPartialFilePath() { - - $partFilename = 'testfile.txt.part'; - $filename = 'testfile.txt'; - - $this->assertTrue(Encryption\Keymanager::isPartialFilePath($partFilename)); - - $this->assertEquals('testfile.txt', Encryption\Keymanager::fixPartialFilePath($partFilename)); - - $this->assertFalse(Encryption\Keymanager::isPartialFilePath($filename)); - - $this->assertEquals('testfile.txt', Encryption\Keymanager::fixPartialFilePath($filename)); - } - - /** - * @medium - */ function testRecursiveDelShareKeys() { // generate filename diff --git a/apps/files_encryption/tests/proxy.php b/apps/files_encryption/tests/proxy.php index 5a2d851ff7c..419f95e1a38 100644 --- a/apps/files_encryption/tests/proxy.php +++ b/apps/files_encryption/tests/proxy.php @@ -1,220 +1,165 @@ <?php /** - * Copyright (c) 2012 Sam Tuke <samtuke@owncloud.com>, - * and Robin Appelman <icewind@owncloud.com> - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. + * ownCloud + * + * @author Bjoern Schiessle + * @copyright 2013 Bjoern Schiessle <schiessle@owncloud.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library 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 along with this library. If not, see <http://www.gnu.org/licenses/>. + * */ -// require_once "PHPUnit/Framework/TestCase.php"; -// require_once realpath( dirname(__FILE__).'/../../../lib/base.php' ); -// require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery.php' ); -// require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/Generator.php' ); -// require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/MockInterface.php' ); -// require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/Mock.php' ); -// require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/Container.php' ); -// require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/Configuration.php' ); -// require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/CompositeExpectation.php' ); -// require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/ExpectationDirector.php' ); -// require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/Expectation.php' ); -// require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/Exception.php' ); -// require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/CountValidator/CountValidatorAbstract.php' ); -// require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/CountValidator/Exception.php' ); -// require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/CountValidator/Exact.php' ); -// -// use \Mockery as m; -// use OCA\Encryption; - -// class Test_Util extends \PHPUnit_Framework_TestCase { -// -// public function setUp() { -// -// $this->proxy = new Encryption\Proxy(); -// -// $this->tmpFileName = "tmpFile-".time(); -// -// $this->privateKey = file_get_contents( realpath( dirname(__FILE__).'/data/admin.public.key' ) ); -// $this->publicKey = file_get_contents( realpath( dirname(__FILE__).'/data/admin.private.key' ) ); -// $this->encDataShort = file_get_contents( realpath( dirname(__FILE__).'/data/yoga-manchester-enc' ) ); -// $this->encDataShortKey = file_get_contents( realpath( dirname(__FILE__).'/data/yoga-manchester.key' ) ); -// -// $this->dataShort = file_get_contents( realpath( dirname(__FILE__).'/data/yoga-manchester' ) ); -// $this->dataLong = file_get_contents( realpath( dirname(__FILE__).'/../lib/crypt.php' ) ); -// $this->longDataPath = realpath( dirname(__FILE__).'/../lib/crypt.php' ); -// -// $this->data1 = file_get_contents( realpath( dirname(__FILE__).'/../../../data/admin/files/enc-test.txt' ) ); -// -// \OC_FileProxy::$enabled = false; -// $this->Encdata1 = file_get_contents( realpath( dirname(__FILE__).'/../../../data/admin/files/enc-test.txt' ) ); -// \OC_FileProxy::$enabled = true; -// -// $this->userId = 'admin'; -// $this->pass = 'admin'; -// -// $this->session = new Encryption\Session( $view ); // FIXME: Provide a $view object for use here -// -// $this->session->setPrivateKey( -// '-----BEGIN PRIVATE KEY----- -// MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDiH3EA4EpFA7Fx -// s2dyyfL5jwXeYXrTqQJ6DqKgGn8VsbT3eu8R9KzM2XitVwZe8c8L52DvJ06o5vg0 -// GqPYxilFdOFJe/ggac5Tq8UmJiZS4EqYEMwxBIfIyWTxeGV06/0HOwnVAkqHMcBz -// 64qldtgi5O8kZMEM2/gKBgU0kMLJzM+8oEWhL1+gsUWQhxd8cKLXypS6iWgqFJrz -// f/X0hJsJR+gyYxNpahtnjzd/LxLAETrOMsl2tue+BAxmjbAM0aG0NEM0div+b59s -// 2uz/iWbxImp5pOdYVKcVW89D4XBMyGegR40trV2VwiuX1blKCfdjMsJhiaL9pymp -// ug1wzyQFAgMBAAECggEAK6c+PZkPPXuVCgpEcliiW6NM0r2m5K3AGKgypQ34csu3 -// z/8foCvIIFPrhCtEw5eTDQ1CHWlNOjY8vHJYJ0U6Onpx86nHIRrMBkMm8FJ1G5LJ -// U8oKYXwqaozWu/cuPwA//OFc6I5krOzh5n8WaRMkbrgbor8AtebRX74By0AXGrXe -// cswJI7zR96oFn4Dm7Pgvpg5Zhk1vFJ+w6QtH+4DDJ6PBvlZsRkGxYBLGVd/3qhAI -// sBAyjFlSzuP4eCRhHOhHC/e4gmAH9evFVXB88jFyRZm3K+jQ5W5CwrVRBCV2lph6 -// 2B6P7CBJN+IjGKMhy+75y13UvvKPv9IwH8Fzl2x1gQKBgQD8qQOr7a6KhSj16wQE -// jim2xqt9gQ2jH5No405NrKs/PFQQZnzD4YseQsiK//NUjOJiUhaT+L5jhIpzINHt -// RJpt3bGkEZmLyjdjgTpB3GwZdXa28DNK9VdXZ19qIl/ZH0qAjKmJCRahUDASMnVi -// M4Pkk9yx9ZIKkri4TcuMWqc0DQKBgQDlHKBTITZq/arYPD6Nl3NsoOdqVRqJrGay -// 0TjXAVbBXe46+z5lnMsqwXb79nx14hdmSEsZULrw/3f+MnQbdjMTYLFP24visZg9 -// MN8vAiALiiiR1a+Crz+DTA1Q8sGOMVCMqMDmD7QBys3ZuWxuapm0txAiIYUtsjJZ -// XN76T4nZ2QKBgQCHaT3igzwsWTmesxowJtEMeGWomeXpKx8h89EfqA8PkRGsyIDN -// qq+YxEoe1RZgljEuaLhZDdNcGsjo8woPk9kAUPTH7fbRCMuutK+4ZJ469s1tNkcH -// QX5SBcEJbOrZvv967ehe3VQXmJZq6kgnHVzuwKBjcC2ZJRGDFY6l5l/+cQKBgCqh -// +Adf/8NK7paMJ0urqfPFwSodKfICXZ3apswDWMRkmSbqh4La+Uc8dsqN5Dz/VEFZ -// JHhSeGbN8uMfOlG93eU2MehdPxtw1pZUWMNjjtj23XO9ooob2CKzbSrp8TBnZsi1 -// widNNr66oTFpeo7VUUK6acsgF6sYJJxSVr+XO1yJAoGAEhvitq8shNKcEY0xCipS -// k1kbgyS7KKB7opVxI5+ChEqyUDijS3Y9FZixrRIWE6i2uGu86UG+v2lbKvSbM4Qm -// xvbOcX9OVMnlRb7n8woOP10UMY+ZE2x+YEUXQTLtPYq7F66e1OfxltstMxLQA+3d -// Y1d5piFV8PXK3Fg2F+Cj5qg= -// -----END PRIVATE KEY----- -// ' -// , $this->userId -// ); -// -// \OC_User::setUserId( $this->userId ); -// -// } -// -// public function testpreFile_get_contents() { -// -// // This won't work for now because mocking of the static keymanager class isn't working :( -// -// // $mock = m::mock( 'alias:OCA\Encryption\Keymanager' ); -// // -// // $mock->shouldReceive( 'getFileKey' )->times(2)->andReturn( $this->encDataShort ); -// // -// // $encrypted = $this->proxy->postFile_get_contents( 'data/'.$this->tmpFileName, $this->encDataShortKey ); -// // -// // $this->assertNotEquals( $this->dataShort, $encrypted ); -// -// $decrypted = $this->proxy->postFile_get_contents( 'data/admin/files/enc-test.txt', $this->data1 ); -// -// } -// -// } - -// class Test_CryptProxy extends PHPUnit_Framework_TestCase { -// private $oldConfig; -// private $oldKey; -// -// public function setUp(){ -// $user=OC_User::getUser(); -// -// $this->oldConfig=OCP\Config::getAppValue('files_encryption','enable_encryption','true'); -// OCP\Config::setAppValue('files_encryption','enable_encryption','true'); -// $this->oldKey=isset($_SESSION['privateKey'])?$_SESSION['privateKey']:null; -// -// -// //set testing key -// $_SESSION['privateKey']=md5(time()); -// -// //clear all proxies and hooks so we can do clean testing -// OC_FileProxy::clearProxies(); -// OC_Hook::clear('OC_Filesystem'); -// -// //enable only the encryption hook -// OC_FileProxy::register(new OC_FileProxy_Encryption()); -// -// //set up temporary storage -// OC_Filesystem::clearMounts(); -// OC_Filesystem::mount('OC_Filestorage_Temporary',array(),'/'); -// -// OC_Filesystem::init('/'.$user.'/files'); -// -// //set up the users home folder in the temp storage -// $rootView=new OC_FilesystemView(''); -// $rootView->mkdir('/'.$user); -// $rootView->mkdir('/'.$user.'/files'); -// } -// -// public function tearDown(){ -// OCP\Config::setAppValue('files_encryption','enable_encryption',$this->oldConfig); -// if(!is_null($this->oldKey)){ -// $_SESSION['privateKey']=$this->oldKey; -// } -// } -// -// public function testSimple(){ -// $file=OC::$SERVERROOT.'/3rdparty/MDB2.php'; -// $original=file_get_contents($file); -// -// OC_Filesystem::file_put_contents('/file',$original); -// -// OC_FileProxy::$enabled=false; -// $stored=OC_Filesystem::file_get_contents('/file'); -// OC_FileProxy::$enabled=true; -// -// $fromFile=OC_Filesystem::file_get_contents('/file'); -// $this->assertNotEquals($original,$stored); -// $this->assertEquals(strlen($original),strlen($fromFile)); -// $this->assertEquals($original,$fromFile); -// -// } -// -// public function testView(){ -// $file=OC::$SERVERROOT.'/3rdparty/MDB2.php'; -// $original=file_get_contents($file); -// -// $rootView=new OC_FilesystemView(''); -// $view=new OC_FilesystemView('/'.OC_User::getUser()); -// $userDir='/'.OC_User::getUser().'/files'; -// -// $rootView->file_put_contents($userDir.'/file',$original); -// -// OC_FileProxy::$enabled=false; -// $stored=$rootView->file_get_contents($userDir.'/file'); -// OC_FileProxy::$enabled=true; -// -// $this->assertNotEquals($original,$stored); -// $fromFile=$rootView->file_get_contents($userDir.'/file'); -// $this->assertEquals($original,$fromFile); -// -// $fromFile=$view->file_get_contents('files/file'); -// $this->assertEquals($original,$fromFile); -// } -// -// public function testBinary(){ -// $file=__DIR__.'/binary'; -// $original=file_get_contents($file); -// -// OC_Filesystem::file_put_contents('/file',$original); -// -// OC_FileProxy::$enabled=false; -// $stored=OC_Filesystem::file_get_contents('/file'); -// OC_FileProxy::$enabled=true; -// -// $fromFile=OC_Filesystem::file_get_contents('/file'); -// $this->assertNotEquals($original,$stored); -// $this->assertEquals(strlen($original),strlen($fromFile)); -// $this->assertEquals($original,$fromFile); -// -// $file=__DIR__.'/zeros'; -// $original=file_get_contents($file); -// -// OC_Filesystem::file_put_contents('/file',$original); -// -// OC_FileProxy::$enabled=false; -// $stored=OC_Filesystem::file_get_contents('/file'); -// OC_FileProxy::$enabled=true; -// -// $fromFile=OC_Filesystem::file_get_contents('/file'); -// $this->assertNotEquals($original,$stored); -// $this->assertEquals(strlen($original),strlen($fromFile)); -// } -// } +require_once __DIR__ . '/../../../lib/base.php'; +require_once __DIR__ . '/../lib/crypt.php'; +require_once __DIR__ . '/../lib/keymanager.php'; +require_once __DIR__ . '/../lib/proxy.php'; +require_once __DIR__ . '/../lib/stream.php'; +require_once __DIR__ . '/../lib/util.php'; +require_once __DIR__ . '/../appinfo/app.php'; +require_once __DIR__ . '/util.php'; + +use OCA\Encryption; + +/** + * Class Test_Encryption_Proxy + * @brief this class provide basic proxy app tests + */ +class Test_Encryption_Proxy extends \PHPUnit_Framework_TestCase { + + const TEST_ENCRYPTION_PROXY_USER1 = "test-proxy-user1"; + + public $userId; + public $pass; + /** + * @var \OC_FilesystemView + */ + public $view; // view in /data/user/files + public $rootView; // view on /data/user + public $data; + public $filename; + + public static function setUpBeforeClass() { + // reset backend + \OC_User::clearBackends(); + \OC_User::useBackend('database'); + + \OC_Hook::clear('OC_Filesystem'); + \OC_Hook::clear('OC_User'); + + // Filesystem related hooks + \OCA\Encryption\Helper::registerFilesystemHooks(); + + // clear and register hooks + \OC_FileProxy::clearProxies(); + \OC_FileProxy::register(new OCA\Encryption\Proxy()); + + // create test user + \Test_Encryption_Util::loginHelper(\Test_Encryption_Proxy::TEST_ENCRYPTION_PROXY_USER1, true); + } + + function setUp() { + // set user id + \OC_User::setUserId(\Test_Encryption_Proxy::TEST_ENCRYPTION_PROXY_USER1); + $this->userId = \Test_Encryption_Proxy::TEST_ENCRYPTION_PROXY_USER1; + $this->pass = \Test_Encryption_Proxy::TEST_ENCRYPTION_PROXY_USER1; + + // init filesystem view + $this->view = new \OC_FilesystemView('/'. \Test_Encryption_Proxy::TEST_ENCRYPTION_PROXY_USER1 . '/files'); + $this->rootView = new \OC_FilesystemView('/'. \Test_Encryption_Proxy::TEST_ENCRYPTION_PROXY_USER1 ); + + // init short data + $this->data = 'hats'; + $this->filename = 'enc_proxy_tests-' . time() . '.txt'; + + } + + public static function tearDownAfterClass() { + // cleanup test user + \OC_User::deleteUser(\Test_Encryption_Proxy::TEST_ENCRYPTION_PROXY_USER1); + } + + /** + * @medium + * @brief test if postFileSize returns the unencrypted file size + */ + function testPostFileSize() { + + $this->view->file_put_contents($this->filename, $this->data); + + \OC_FileProxy::$enabled = false; + + $unencryptedSize = $this->view->filesize($this->filename); + + \OC_FileProxy::$enabled = true; + + $encryptedSize = $this->view->filesize($this->filename); + + $this->assertTrue($encryptedSize !== $unencryptedSize); + + // cleanup + $this->view->unlink($this->filename); + + } + + function testPreUnlinkWithoutTrash() { + + // remember files_trashbin state + $stateFilesTrashbin = OC_App::isEnabled('files_trashbin'); + + // we want to tests with app files_trashbin enabled + \OC_App::disable('files_trashbin'); + + $this->view->file_put_contents($this->filename, $this->data); + + // create a dummy file that we can delete something outside of data/user/files + $this->rootView->file_put_contents("dummy.txt", $this->data); + + // check if all keys are generated + $this->assertTrue($this->rootView->file_exists( + '/files_encryption/share-keys/' + . $this->filename . '.' . \Test_Encryption_Proxy::TEST_ENCRYPTION_PROXY_USER1 . '.shareKey')); + $this->assertTrue($this->rootView->file_exists( + '/files_encryption/keyfiles/' . $this->filename . '.key')); + + + // delete dummy file outside of data/user/files + $this->rootView->unlink("dummy.txt"); + + // all keys should still exist + $this->assertTrue($this->rootView->file_exists( + '/files_encryption/share-keys/' + . $this->filename . '.' . \Test_Encryption_Proxy::TEST_ENCRYPTION_PROXY_USER1 . '.shareKey')); + $this->assertTrue($this->rootView->file_exists( + '/files_encryption/keyfiles/' . $this->filename . '.key')); + + + // delete the file in data/user/files + $this->view->unlink($this->filename); + + // now also the keys should be gone + $this->assertFalse($this->rootView->file_exists( + '/files_encryption/share-keys/' + . $this->filename . '.' . \Test_Encryption_Proxy::TEST_ENCRYPTION_PROXY_USER1 . '.shareKey')); + $this->assertFalse($this->rootView->file_exists( + '/files_encryption/keyfiles/' . $this->filename . '.key')); + + if ($stateFilesTrashbin) { + OC_App::enable('files_trashbin'); + } + else { + OC_App::disable('files_trashbin'); + } + } + +} diff --git a/apps/files_encryption/tests/share.php b/apps/files_encryption/tests/share.php index 6a29d2428dc..e55427620a6 100755 --- a/apps/files_encryption/tests/share.php +++ b/apps/files_encryption/tests/share.php @@ -649,9 +649,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { * @large */ function testRecoveryFile() { - $this->markTestIncomplete( - 'No idea what\'s wrong here, this works perfectly in real-world. removeRecoveryKeys(\'/\') L709 removes correctly the keys, but for some reasons afterwards also the top-level folder "share-keys" is gone...' - ); + // login as admin \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); @@ -754,13 +752,13 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { * @large */ function testRecoveryForUser() { - $this->markTestIncomplete( - 'This test drives Jenkins crazy - "Cannot modify header information - headers already sent" - line 811' - ); + // login as admin \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); - \OCA\Encryption\Helper::adminEnableRecovery(null, 'test123'); + $result = \OCA\Encryption\Helper::adminEnableRecovery(null, 'test123'); + $this->assertTrue($result); + $recoveryKeyId = OC_Appconfig::getValue('files_encryption', 'recoveryKeyId'); // login as user2 @@ -771,6 +769,9 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { // enable recovery for admin $this->assertTrue($util->setRecoveryForUser(1)); + // add recovery keys for existing files (e.g. the auto-generated welcome.txt) + $util->addRecoveryKeys(); + // create folder structure $this->view->mkdir('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files' . $this->folder1); $this->view->mkdir( @@ -809,6 +810,10 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { // change password \OC_User::setPassword(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, 'test', 'test123'); + $params = array('uid' => \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, + 'password' => 'test', + 'recoveryPassword' => 'test123'); + \OCA\Encryption\Hooks::setPassphrase($params); // login as user2 \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, false, 'test'); @@ -823,8 +828,8 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { $this->assertEquals($this->dataShort, $retrievedCryptedFile2); // cleanup - $this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files' . $this->folder1); - $this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files' . $this->filename); + $this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->folder1); + $this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->filename); // check if share key for user and recovery exists $this->assertFalse($this->view->file_exists( @@ -889,8 +894,8 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase { } catch (Exception $e) { $this->assertEquals(0, strpos($e->getMessage(), "Following users are not set up for encryption")); } - - + + // login as admin \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); diff --git a/apps/files_encryption/tests/stream.php b/apps/files_encryption/tests/stream.php index 530ee3a7b2d..2767bbe512b 100644 --- a/apps/files_encryption/tests/stream.php +++ b/apps/files_encryption/tests/stream.php @@ -180,4 +180,43 @@ class Test_Encryption_Stream extends \PHPUnit_Framework_TestCase { // tear down $view->unlink($filename); } + + /** + * @medium + * @brief test if stream wrapper can read files outside from the data folder + */ + function testStreamFromLocalFile() { + + $filename = '/' . $this->userId . '/files/' . 'tmp-' . time().'.txt'; + + $tmpFilename = "/tmp/" . time() . ".txt"; + + // write an encrypted file + $cryptedFile = $this->view->file_put_contents($filename, $this->dataShort); + + // Test that data was successfully written + $this->assertTrue(is_int($cryptedFile)); + + // create a copy outside of the data folder in /tmp + $proxyStatus = \OC_FileProxy::$enabled; + \OC_FileProxy::$enabled = false; + $encryptedContent = $this->view->file_get_contents($filename); + \OC_FileProxy::$enabled = $proxyStatus; + + file_put_contents($tmpFilename, $encryptedContent); + + \OCA\Encryption\Helper::addTmpFileToMapper($tmpFilename, $filename); + + // try to read the file from /tmp + $handle = fopen("crypt://".$tmpFilename, "r"); + $contentFromTmpFile = stream_get_contents($handle); + + // check if it was successful + $this->assertEquals($this->dataShort, $contentFromTmpFile); + + // clean up + unlink($tmpFilename); + $this->view->unlink($filename); + + } } diff --git a/apps/files_encryption/tests/util.php b/apps/files_encryption/tests/util.php index eddc4c6b3ff..b1904cbadc7 100755 --- a/apps/files_encryption/tests/util.php +++ b/apps/files_encryption/tests/util.php @@ -134,6 +134,41 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { /** * @medium + * @brief test detection of encrypted files + */ + function testIsEncryptedPath() { + + $util = new Encryption\Util($this->view, $this->userId); + + self::loginHelper($this->userId); + + $unencryptedFile = '/tmpUnencrypted-' . time() . '.txt'; + $encryptedFile = '/tmpEncrypted-' . time() . '.txt'; + + // Disable encryption proxy to write a unencrypted file + $proxyStatus = \OC_FileProxy::$enabled; + \OC_FileProxy::$enabled = false; + + $this->view->file_put_contents($this->userId . '/files/' . $unencryptedFile, $this->dataShort); + + // Re-enable proxy - our work is done + \OC_FileProxy::$enabled = $proxyStatus; + + // write a encrypted file + $this->view->file_put_contents($this->userId . '/files/' . $encryptedFile, $this->dataShort); + + // test if both files are detected correctly + $this->assertFalse($util->isEncryptedPath($this->userId . '/files/' . $unencryptedFile)); + $this->assertTrue($util->isEncryptedPath($this->userId . '/files/' . $encryptedFile)); + + // cleanup + $this->view->unlink($this->userId . '/files/' . $unencryptedFile, $this->dataShort); + $this->view->unlink($this->userId . '/files/' . $encryptedFile, $this->dataShort); + + } + + /** + * @medium * @brief test setup of encryption directories */ function testSetupServerSide() { @@ -242,6 +277,34 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { } /** +< * @brief Test that data that is read by the crypto stream wrapper + */ + function testGetFileSize() { + \Test_Encryption_Util::loginHelper(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER1); + + $filename = 'tmp-' . time(); + $externalFilename = '/' . $this->userId . '/files/' . $filename; + + // Test for 0 byte files + $problematicFileSizeData = ""; + $cryptedFile = $this->view->file_put_contents($externalFilename, $problematicFileSizeData); + $this->assertTrue(is_int($cryptedFile)); + $this->assertEquals($this->util->getFileSize($externalFilename), 0); + $decrypt = $this->view->file_get_contents($externalFilename); + $this->assertEquals($problematicFileSizeData, $decrypt); + $this->view->unlink($this->userId . '/files/' . $filename); + + // Test a file with 18377 bytes as in https://github.com/owncloud/mirall/issues/1009 + $problematicFileSizeData = str_pad("", 18377, "abc"); + $cryptedFile = $this->view->file_put_contents($externalFilename, $problematicFileSizeData); + $this->assertTrue(is_int($cryptedFile)); + $this->assertEquals($this->util->getFileSize($externalFilename), 18377); + $decrypt = $this->view->file_get_contents($externalFilename); + $this->assertEquals($problematicFileSizeData, $decrypt); + $this->view->unlink($this->userId . '/files/' . $filename); + } + + /** * @medium */ function testIsSharedPath() { @@ -253,6 +316,64 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { $this->assertFalse($this->util->isSharedPath($path)); } + function testEncryptAll() { + + $filename = "/encryptAll" . time() . ".txt"; + $util = new Encryption\Util($this->view, $this->userId); + + // disable encryption to upload a unencrypted file + \OC_App::disable('files_encryption'); + + $this->view->file_put_contents($this->userId . '/files/' . $filename, $this->dataShort); + + $fileInfoUnencrypted = $this->view->getFileInfo($this->userId . '/files/' . $filename); + + $this->assertTrue(is_array($fileInfoUnencrypted)); + + // enable file encryption again + \OC_App::enable('files_encryption'); + + // encrypt all unencrypted files + $util->encryptAll('/' . $this->userId . '/' . 'files'); + + $fileInfoEncrypted = $this->view->getFileInfo($this->userId . '/files/' . $filename); + + $this->assertTrue(is_array($fileInfoEncrypted)); + + // check if mtime and etags unchanged + $this->assertEquals($fileInfoEncrypted['mtime'], $fileInfoUnencrypted['mtime']); + $this->assertEquals($fileInfoEncrypted['etag'], $fileInfoUnencrypted['etag']); + + $this->view->unlink($this->userId . '/files/' . $filename); + } + + + function testDecryptAll() { + + $filename = "/decryptAll" . time() . ".txt"; + $util = new Encryption\Util($this->view, $this->userId); + + $this->view->file_put_contents($this->userId . '/files/' . $filename, $this->dataShort); + + $fileInfoEncrypted = $this->view->getFileInfo($this->userId . '/files/' . $filename); + + $this->assertTrue(is_array($fileInfoEncrypted)); + + // encrypt all unencrypted files + $util->decryptAll('/' . $this->userId . '/' . 'files'); + + $fileInfoUnencrypted = $this->view->getFileInfo($this->userId . '/files/' . $filename); + + $this->assertTrue(is_array($fileInfoUnencrypted)); + + // check if mtime and etags unchanged + $this->assertEquals($fileInfoEncrypted['mtime'], $fileInfoUnencrypted['mtime']); + $this->assertEquals($fileInfoEncrypted['etag'], $fileInfoUnencrypted['etag']); + + $this->view->unlink($this->userId . '/files/' . $filename); + + } + /** * @large */ @@ -330,10 +451,16 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase { OCA\Encryption\Hooks::login($params); } + public static function logoutHelper() { + \OC_Util::tearDownFS(); + \OC_User::setUserId(''); + \OC\Files\Filesystem::tearDown(); + } + /** * helper function to set migration status to the right value * to be able to test the migration path - * + * * @param $status needed migration status for test * @param $user for which user the status should be set * @return boolean diff --git a/apps/files_external/3rdparty/php-opencloud/LICENSE b/apps/files_external/3rdparty/php-opencloud/LICENSE new file mode 100644 index 00000000000..f7c56967e6c --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/LICENSE @@ -0,0 +1,16 @@ + Copyright 2012-2013 Rackspace US, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + All contributions to this repository are covered under the same license, + terms, and conditions.
\ No newline at end of file diff --git a/apps/files_external/3rdparty/php-opencloud/lib/Autoload.php b/apps/files_external/3rdparty/php-opencloud/lib/Autoload.php new file mode 100644 index 00000000000..32e9dc24b7e --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/Autoload.php @@ -0,0 +1,296 @@ +<?php + +// Copyright (c) 2004-2013 Fabien Potencier + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is furnished +// to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +class ClassLoader +{ + private $namespaces = array(); + private $prefixes = array(); + private $namespaceFallbacks = array(); + private $prefixFallbacks = array(); + private $useIncludePath = false; + + /** + * Turns on searching the include for class files. Allows easy loading + * of installed PEAR packages + * + * @param Boolean $useIncludePath + */ + public function useIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return Boolean + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Gets the configured namespaces. + * + * @return array A hash with namespaces as keys and directories as values + */ + public function getNamespaces() + { + return $this->namespaces; + } + + /** + * Gets the configured class prefixes. + * + * @return array A hash with class prefixes as keys and directories as values + */ + public function getPrefixes() + { + return $this->prefixes; + } + + /** + * Gets the directory(ies) to use as a fallback for namespaces. + * + * @return array An array of directories + */ + public function getNamespaceFallbacks() + { + return $this->namespaceFallbacks; + } + + /** + * Gets the directory(ies) to use as a fallback for class prefixes. + * + * @return array An array of directories + */ + public function getPrefixFallbacks() + { + return $this->prefixFallbacks; + } + + /** + * Registers the directory to use as a fallback for namespaces. + * + * @param array $dirs An array of directories + * + * @api + */ + public function registerNamespaceFallbacks(array $dirs) + { + $this->namespaceFallbacks = $dirs; + } + + /** + * Registers a directory to use as a fallback for namespaces. + * + * @param string $dir A directory + */ + public function registerNamespaceFallback($dir) + { + $this->namespaceFallbacks[] = $dir; + } + + /** + * Registers directories to use as a fallback for class prefixes. + * + * @param array $dirs An array of directories + * + * @api + */ + public function registerPrefixFallbacks(array $dirs) + { + $this->prefixFallbacks = $dirs; + } + + /** + * Registers a directory to use as a fallback for class prefixes. + * + * @param string $dir A directory + */ + public function registerPrefixFallback($dir) + { + $this->prefixFallbacks[] = $dir; + } + + /** + * Registers an array of namespaces + * + * @param array $namespaces An array of namespaces (namespaces as keys and locations as values) + * + * @api + */ + public function registerNamespaces(array $namespaces) + { + foreach ($namespaces as $namespace => $locations) { + $this->namespaces[$namespace] = (array) $locations; + } + } + + /** + * Registers a namespace. + * + * @param string $namespace The namespace + * @param array|string $paths The location(s) of the namespace + * + * @api + */ + public function registerNamespace($namespace, $paths) + { + $this->namespaces[$namespace] = (array) $paths; + } + + /** + * Registers an array of classes using the PEAR naming convention. + * + * @param array $classes An array of classes (prefixes as keys and locations as values) + * + * @api + */ + public function registerPrefixes(array $classes) + { + foreach ($classes as $prefix => $locations) { + $this->prefixes[$prefix] = (array) $locations; + } + } + + /** + * Registers a set of classes using the PEAR naming convention. + * + * @param string $prefix The classes prefix + * @param array|string $paths The location(s) of the classes + * + * @api + */ + public function registerPrefix($prefix, $paths) + { + $this->prefixes[$prefix] = (array) $paths; + } + + /** + * Registers this instance as an autoloader. + * + * @param Boolean $prepend Whether to prepend the autoloader or not + * + * @api + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + } + + /** + * Fix for certain versions of PHP that have trouble with + * namespaces with leading separators. + * + * @access private + * @param mixed $className + * @return void + */ + private function makeBackwardsCompatible($className) + { + return (phpversion() < '5.3.3') ? ltrim($className, '\\') : $className; + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * + * @return Boolean|null True, if loaded + */ + public function loadClass($class) + { + $class = $this->makeBackwardsCompatible($class); + + if ($file = $this->findFile($class)) { + require $file; + + return true; + } + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|null The path, if found + */ + public function findFile($class) + { + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $namespace = substr($class, 0, $pos); + $className = substr($class, $pos + 1); + $normalizedClass = str_replace('\\', DIRECTORY_SEPARATOR, $namespace).DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $className).'.php'; + foreach ($this->namespaces as $ns => $dirs) { + if (0 !== strpos($namespace, $ns)) { + continue; + } + + foreach ($dirs as $dir) { + $file = $dir.DIRECTORY_SEPARATOR.$normalizedClass; + if (is_file($file)) { + return $file; + } + } + } + + foreach ($this->namespaceFallbacks as $dir) { + $file = $dir.DIRECTORY_SEPARATOR.$normalizedClass; + if (is_file($file)) { + return $file; + } + } + + } else { + // PEAR-like class name + $normalizedClass = str_replace('_', DIRECTORY_SEPARATOR, $class).'.php'; + foreach ($this->prefixes as $prefix => $dirs) { + if (0 !== strpos($class, $prefix)) { + continue; + } + + foreach ($dirs as $dir) { + $file = $dir.DIRECTORY_SEPARATOR.$normalizedClass; + if (is_file($file)) { + return $file; + } + } + } + + foreach ($this->prefixFallbacks as $dir) { + $file = $dir.DIRECTORY_SEPARATOR.$normalizedClass; + if (is_file($file)) { + return $file; + } + } + } + + if ($this->useIncludePath && $file = stream_resolve_include_path($normalizedClass)) { + return $file; + } + } +} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Base.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Base.php new file mode 100644 index 00000000000..f80c9320e2a --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Base.php @@ -0,0 +1,301 @@ +<?php +/** + * @copyright 2012-2013 Rackspace Hosting, Inc. + * See COPYING for licensing information + * @package phpOpenCloud + * @version 1.0 + * @author Glen Campbell <glen.campbell@rackspace.com> + * @author Jamie Hannaford <jamie.hannaford@rackspace.com> + */ + +namespace OpenCloud\Common; + +use OpenCloud\Common\Lang; +use OpenCloud\Common\Exceptions\AttributeError; +use OpenCloud\Common\Exceptions\JsonError; +use OpenCloud\Common\Exceptions\UrlError; + +/** + * The root class for all other objects used or defined by this SDK. + * + * It contains common code for error handling as well as service functions that + * are useful. Because it is an abstract class, it cannot be called directly, + * and it has no publicly-visible properties. + */ +abstract class Base +{ + + private $http_headers = array(); + private $_errors = array(); + + /** + * Debug status. + * + * @var LoggerInterface + * @access private + */ + private $logger; + + /** + * Sets the Logger object. + * + * @param \OpenCloud\Common\Log\LoggerInterface $logger + */ + public function setLogger(Log\LoggerInterface $logger) + { + $this->logger = $logger; + } + + /** + * Returns the Logger object. + * + * @return \OpenCloud\Common\Log\AbstractLogger + */ + public function getLogger() + { + if (null === $this->logger) { + $this->setLogger(new Log\Logger); + } + return $this->logger; + } + + /** + * Returns the URL of the service/object + * + * The assumption is that nearly all objects will have a URL; at this + * base level, it simply throws an exception to enforce the idea that + * subclasses need to define this method. + * + * @throws UrlError + */ + public function url($subresource = '') + { + throw new UrlError(Lang::translate( + 'URL method must be overridden in class definition' + )); + } + +/** + * Populates the current object based on an unknown data type. + * + * @param array|object|string|integer $info + * @throws Exceptions\InvalidArgumentError + */ + public function populate($info, $setObjects = true) + { + if (is_string($info) || is_integer($info)) { + + // If the data type represents an ID, the primary key is set + // and we retrieve the full resource from the API + $this->{$this->primaryKeyField()} = (string) $info; + $this->refresh($info); + + } elseif (is_object($info) || is_array($info)) { + + foreach($info as $key => $value) { + + if ($key == 'metadata' || $key == 'meta') { + + if (empty($this->metadata) || !$this->metadata instanceof Metadata) { + $this->metadata = new Metadata; + } + + // Metadata + $this->$key->setArray($value); + + } elseif (!empty($this->associatedResources[$key]) && $setObjects === true) { + + // Associated resource + try { + $resource = $this->service()->resource($this->associatedResources[$key], $value); + $resource->setParent($this); + $this->$key = $resource; + } catch (Exception\ServiceException $e) {} + + } elseif (!empty($this->associatedCollections[$key]) && $setObjects === true) { + + // Associated collection + try { + $this->$key = $this->service()->resourceList($this->associatedCollections[$key], null, $this); + } catch (Exception\ServiceException $e) {} + + } else { + + // Normal key/value pair + $this->$key = $value; + } + } + } elseif (null !== $info) { + throw new Exceptions\InvalidArgumentError(sprintf( + Lang::translate('Argument for [%s] must be string or object'), + get_class() + )); + } + } + + /** + * Sets extended attributes on an object and validates them + * + * This function is provided to ensure that attributes cannot + * arbitrarily added to an object. If this function is called, it + * means that the attribute is not defined on the object, and thus + * an exception is thrown. + * + * @codeCoverageIgnore + * + * @param string $property the name of the attribute + * @param mixed $value the value of the attribute + * @return void + */ + public function __set($property, $value) + { + $this->setProperty($property, $value); + } + + /** + * Sets an extended (unrecognized) property on the current object + * + * If RAXSDK_STRICT_PROPERTY_CHECKS is TRUE, then the prefix of the + * property name must appear in the $prefixes array, or else an + * exception is thrown. + * + * @param string $property the property name + * @param mixed $value the value of the property + * @param array $prefixes optional list of supported prefixes + * @throws \OpenCloud\AttributeError if strict checks are on and + * the property prefix is not in the list of prefixes. + */ + public function setProperty($property, $value, array $prefixes = array()) + { + // if strict checks are off, go ahead and set it + if (!RAXSDK_STRICT_PROPERTY_CHECKS + || $this->checkAttributePrefix($property, $prefixes) + ) { + $this->$property = $value; + } else { + // if that fails, then throw the exception + throw new AttributeError(sprintf( + Lang::translate('Unrecognized attribute [%s] for [%s]'), + $property, + get_class($this) + )); + } + } + + /** + * Converts an array of key/value pairs into a single query string + * + * For example, array('A'=>1,'B'=>2) would become 'A=1&B=2'. + * + * @param array $arr array of key/value pairs + * @return string + */ + public function makeQueryString($array) + { + $queryString = ''; + + foreach($array as $key => $value) { + if ($queryString) { + $queryString .= '&'; + } + $queryString .= urlencode($key) . '=' . urlencode($this->to_string($value)); + } + + return $queryString; + } + + /** + * Checks the most recent JSON operation for errors + * + * This function should be called after any `json_*()` function call. + * This ensures that nasty JSON errors are detected and the proper + * exception thrown. + * + * Example: + * `$obj = json_decode($string);` + * `if (check_json_error()) do something ...` + * + * @return boolean TRUE if an error occurred, FALSE if none + * @throws JsonError + * + * @codeCoverageIgnore + */ + public function checkJsonError() + { + switch (json_last_error()) { + case JSON_ERROR_NONE: + return; + case JSON_ERROR_DEPTH: + $jsonError = 'JSON error: The maximum stack depth has been exceeded'; + break; + case JSON_ERROR_STATE_MISMATCH: + $jsonError = 'JSON error: Invalid or malformed JSON'; + break; + case JSON_ERROR_CTRL_CHAR: + $jsonError = 'JSON error: Control character error, possibly incorrectly encoded'; + break; + case JSON_ERROR_SYNTAX: + $jsonError = 'JSON error: Syntax error'; + break; + case JSON_ERROR_UTF8: + $jsonError = 'JSON error: Malformed UTF-8 characters, possibly incorrectly encoded'; + break; + default: + $jsonError = 'Unexpected JSON error'; + break; + } + + if (isset($jsonError)) { + throw new JsonError(Lang::translate($jsonError)); + } + } + + /** + * Returns a class that implements the HttpRequest interface. + * + * This can be stubbed out for unit testing and avoid making live calls. + */ + public function getHttpRequestObject($url, $method = 'GET', array $options = array()) + { + return new Request\Curl($url, $method, $options); + } + + /** + * Checks the attribute $property and only permits it if the prefix is + * in the specified $prefixes array + * + * This is to support extension namespaces in some services. + * + * @param string $property the name of the attribute + * @param array $prefixes a list of prefixes + * @return boolean TRUE if valid; FALSE if not + */ + private function checkAttributePrefix($property, array $prefixes = array()) + { + $prefix = strstr($property, ':', true); + + if (in_array($prefix, $prefixes)) { + return true; + } else { + return false; + } + } + + /** + * Converts a value to an HTTP-displayable string form + * + * @param mixed $x a value to convert + * @return string + */ + private function to_string($x) + { + if (is_bool($x) && $x) { + return 'True'; + } elseif (is_bool($x)) { + return 'False'; + } else { + return (string) $x; + } + } + +} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Collection.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Collection.php new file mode 100644 index 00000000000..e1bf80376e0 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Collection.php @@ -0,0 +1,320 @@ +<?php + +namespace OpenCloud\Common; + +/** + * Provides an abstraction for working with ordered sets of objects + * + * Collection objects are used whenever there are multiples; for example, + * multiple objects in a container, or multiple servers in a service. + * + * @since 1.0 + * @author Glen Campbell <glen.campbell@rackspace.com> + * @author Jamie Hannaford <jamie.hannaford@rackspace.com> + */ +class Collection extends Base +{ + + private $service; + private $itemclass; + private $itemlist = array(); + private $pointer = 0; + private $sortkey; + private $next_page_class; + private $next_page_callback; + private $next_page_url; + + /** + * A Collection is an array of objects + * + * Some assumptions: + * * The `Collection` class assumes that there exists on its service + * a factory method with the same name of the class. For example, if + * you create a Collection of class `Foobar`, it will attempt to call + * the method `parent::Foobar()` to create instances of that class. + * * It assumes that the factory method can take an array of values, and + * it passes that to the method. + * + * @param Service $service - the service associated with the collection + * @param string $itemclass - the Class of each item in the collection + * (assumed to be the name of the factory method) + * @param array $arr - the input array + */ + public function __construct($service, $itemclass, $array) + { + $this->service = $service; + + $this->getLogger()->info( + 'Collection:service={class}, class={itemClass}, array={array}', + array( + 'class' => get_class($service), + 'itemClass' => $itemclass, + 'array' => print_r($array, true) + ) + ); + + $this->next_page_class = $itemclass; + + if (false !== ($classNamePos = strrpos($itemclass, '\\'))) { + $this->itemclass = substr($itemclass, $classNamePos + 1); + } else { + $this->itemclass = $itemclass; + } + + if (!is_array($array)) { + throw new Exceptions\CollectionError( + Lang::translate('Cannot create a Collection without an array') + ); + } + + // save the array of items + $this->setItemList($array); + } + + /** + * Set the entire data array. + * + * @param array $array + */ + public function setItemList(array $array) + { + $this->itemlist = $array; + } + + /** + * Retrieve the entire data array. + * + * @return array + */ + public function getItemList() + { + return $this->itemlist; + } + + /** + * Returns the number of items in the collection + * + * For most services, this is the total number of items. If the Collection + * is paginated, however, this only returns the count of items in the + * current page of data. + * + * @return int + */ + public function count() + { + return count($this->itemlist); + } + + /** + * Pseudonym for count() + * + * @codeCoverageIgnore + */ + public function size() + { + return $this->count(); + } + + /** + * Retrieves the service associated with the Collection + * + * @return Service + */ + public function service() + { + return $this->service; + } + + /** + * Resets the pointer to the beginning, but does NOT return the first item + * + * @api + * @return void + */ + public function reset() + { + $this->pointer = 0; + } + + /** + * Resets the collection pointer back to the first item in the page + * and returns it + * + * This is useful if you're only interested in the first item in the page. + * + * @api + * @return Base the first item in the set + */ + public function first() + { + $this->reset(); + return $this->next(); + } + + /** + * Returns the next item in the page + * + * @api + * @return Base the next item or FALSE if at the end of the page + */ + public function next() + { + if ($this->pointer >= $this->count()) { + return false; + } + + $service = $this->service(); + + if (method_exists($service, $this->itemclass)) { + return $service->{$this->itemclass}($this->itemlist[$this->pointer++]); + } elseif (method_exists($service, 'resource')) { + return $service->resource($this->itemclass, $this->itemlist[$this->pointer++]); + } + // @codeCoverageIgnoreStart + return false; + // @codeCoverageIgnoreEnd + } + + /** + * sorts the collection on a specified key + * + * Note: only top-level keys can be used as the sort key. Note that this + * only sorts the data in the current page of the Collection (for + * multi-page data). + * + * @api + * @param string $keyname the name of the field to use as the sort key + * @return void + */ + public function sort($keyname = 'id') + { + $this->sortkey = $keyname; + usort($this->itemlist, array($this, 'sortCompare')); + } + + /** + * selects only specified items from the Collection + * + * This provides a simple form of filtering on Collections. For each item + * in the collection, it calls the callback function, passing it the item. + * If the callback returns `TRUE`, then the item is retained; if it returns + * `FALSE`, then the item is deleted from the collection. + * + * Note that this should not supersede server-side filtering; the + * `Collection::Select()` method requires that *all* of the data for the + * Collection be retrieved from the server before the filtering is + * performed; this can be very inefficient, especially for large data + * sets. This method is mostly useful on smaller-sized sets. + * + * Example: + * <code> + * $services = $connection->ServiceList(); + * $services->Select(function($item){ return $item->region=='ORD';}); + * // now the $services Collection only has items from the ORD region + * </code> + * + * `Select()` is *destructive*; that is, it actually removes entries from + * the collection. For example, if you use `Select()` to find items with + * the ID > 10, then use it again to find items that are <= 10, it will + * return an empty list. + * + * @api + * @param callable $testfunc a callback function that is passed each item + * in turn. Note that `Select()` performs an explicit test for + * `FALSE`, so functions like `strpos()` need to be cast into a + * boolean value (and not just return the integer). + * @returns void + * @throws DomainError if callback doesn't return a boolean value + */ + public function select($testfunc) + { + foreach ($this->getItemList() as $index => $item) { + $test = call_user_func($testfunc, $item); + if (!is_bool($test)) { + throw new Exceptions\DomainError( + Lang::translate('Callback function for Collection::Select() did not return boolean') + ); + } + if ($test === false) { + unset($this->itemlist[$index]); + } + } + } + + /** + * returns the Collection object for the next page of results, or + * FALSE if there are no more pages + * + * Generally, the structure for a multi-page collection will look like + * this: + * + * $coll = $obj->Collection(); + * do { + * while($item = $coll->Next()) { + * // do something with the item + * } + * } while ($coll = $coll->NextPage()); + * + * @api + * @return Collection if there are more pages of results, otherwise FALSE + */ + public function nextPage() + { + if (isset($this->next_page_url)) { + return call_user_func( + $this->next_page_callback, + $this->next_page_class, + $this->next_page_url + ); + } + // @codeCoverageIgnoreStart + return false; + // @codeCoverageIgnoreEnd + } + + /** + * for paginated collection, sets the callback function and URL for + * the next page + * + * The callback function should have the signature: + * + * function Whatever($class, $url, $parent) + * + * and the `$url` should be the URL of the next page of results + * + * @param callable $callback the name of the function (or array of + * object, function name) + * @param string $url the URL of the next page of results + * @return void + */ + public function setNextPageCallback($callback, $url) + { + $this->next_page_callback = $callback; + $this->next_page_url = $url; + } + + /** + * Compares two values of sort keys + */ + private function sortCompare($a, $b) + { + $key = $this->sortkey; + + // handle strings with strcmp() + if (is_string($a->$key)) { + return strcmp($a->$key, $b->$key); + } + + // handle others with logical comparisons + if ($a->$key == $b->$key) { + return 0; + } + + if ($a->$key < $b->$key) { + return -1; + } else { + return 1; + } + } + +} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/AsyncError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/AsyncError.php new file mode 100644 index 00000000000..cbbacff38bd --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/AsyncError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class AsyncError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/AsyncHttpError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/AsyncHttpError.php new file mode 100644 index 00000000000..dc7b2d7e3a7 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/AsyncHttpError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class AsyncHttpError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/AsyncTimeoutError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/AsyncTimeoutError.php new file mode 100644 index 00000000000..bba5f09f64f --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/AsyncTimeoutError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class AsyncTimeoutError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/AttributeError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/AttributeError.php new file mode 100644 index 00000000000..7d09ceb0147 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/AttributeError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class AttributeError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/AuthenticationError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/AuthenticationError.php new file mode 100644 index 00000000000..091e4602ec0 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/AuthenticationError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class AuthenticationError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/BaseException.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/BaseException.php new file mode 100644 index 00000000000..0bc967adf67 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/BaseException.php @@ -0,0 +1,7 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class BaseException extends \Exception +{ +}
\ No newline at end of file diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/CdnError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/CdnError.php new file mode 100644 index 00000000000..0f972e9c5c7 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/CdnError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class CdnError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/CdnHttpError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/CdnHttpError.php new file mode 100644 index 00000000000..f1e2722f158 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/CdnHttpError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class CdnHttpError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/CdnNotAvailableError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/CdnNotAvailableError.php new file mode 100644 index 00000000000..853b17c7127 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/CdnNotAvailableError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class CdnNotAvailableError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/CdnTtlError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/CdnTtlError.php new file mode 100644 index 00000000000..b4364f93467 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/CdnTtlError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class CdnTtlError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/CollectionError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/CollectionError.php new file mode 100644 index 00000000000..9d5030403f6 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/CollectionError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class CollectionError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ContainerCreateError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ContainerCreateError.php new file mode 100644 index 00000000000..afc8119bd5a --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ContainerCreateError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class ContainerCreateError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ContainerDeleteError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ContainerDeleteError.php new file mode 100644 index 00000000000..c212bfbaffd --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ContainerDeleteError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class ContainerDeleteError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ContainerError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ContainerError.php new file mode 100644 index 00000000000..c9716fef075 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ContainerError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class ContainerError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ContainerNameError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ContainerNameError.php new file mode 100644 index 00000000000..e0b9592835e --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ContainerNameError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class ContainerNameError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ContainerNotEmptyError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ContainerNotEmptyError.php new file mode 100644 index 00000000000..e987449d444 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ContainerNotEmptyError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class ContainerNotEmptyError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ContainerNotFoundError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ContainerNotFoundError.php new file mode 100644 index 00000000000..2e700dbe039 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ContainerNotFoundError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class ContainerNotFoundError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/CreateError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/CreateError.php new file mode 100644 index 00000000000..bb2030373fb --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/CreateError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class CreateError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/CreateUpdateError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/CreateUpdateError.php new file mode 100644 index 00000000000..8aa651a76d9 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/CreateUpdateError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class CreateUpdateError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/CredentialError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/CredentialError.php new file mode 100644 index 00000000000..2769edaf378 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/CredentialError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class CredentialError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/DatabaseCreateError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/DatabaseCreateError.php new file mode 100644 index 00000000000..eb19198c2fe --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/DatabaseCreateError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class DatabaseCreateError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/DatabaseDeleteError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/DatabaseDeleteError.php new file mode 100644 index 00000000000..41f397529fe --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/DatabaseDeleteError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class DatabaseDeleteError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/DatabaseListError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/DatabaseListError.php new file mode 100644 index 00000000000..04a7fb9e835 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/DatabaseListError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class DatabaseListError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/DatabaseNameError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/DatabaseNameError.php new file mode 100644 index 00000000000..17a987a03b0 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/DatabaseNameError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class DatabaseNameError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/DatabaseUpdateError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/DatabaseUpdateError.php new file mode 100644 index 00000000000..c891c173787 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/DatabaseUpdateError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class DatabaseUpdateError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/DeleteError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/DeleteError.php new file mode 100644 index 00000000000..27c4b2a4894 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/DeleteError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class DeleteError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/DocumentError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/DocumentError.php new file mode 100644 index 00000000000..d501e3594b6 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/DocumentError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class DocumentError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/DomainError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/DomainError.php new file mode 100644 index 00000000000..b4eac2ae1d3 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/DomainError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class DomainError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/EmptyResponseError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/EmptyResponseError.php new file mode 100644 index 00000000000..c7863c09b01 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/EmptyResponseError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class EmptyResponseError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/EndpointError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/EndpointError.php new file mode 100644 index 00000000000..a686a6456e9 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/EndpointError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class EndpointError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/FlavorError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/FlavorError.php new file mode 100644 index 00000000000..469dc27e76c --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/FlavorError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class FlavorError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/HttpError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/HttpError.php new file mode 100644 index 00000000000..1b54b8a8253 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/HttpError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class HttpError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/HttpForbiddenError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/HttpForbiddenError.php new file mode 100644 index 00000000000..a5c64780516 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/HttpForbiddenError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class HttpForbiddenError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/HttpOverLimitError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/HttpOverLimitError.php new file mode 100644 index 00000000000..243e8df64fd --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/HttpOverLimitError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class HttpOverLimitError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/HttpRetryError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/HttpRetryError.php new file mode 100644 index 00000000000..78345840bba --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/HttpRetryError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class HttpRetryError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/HttpTimeoutError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/HttpTimeoutError.php new file mode 100644 index 00000000000..81bc9dda608 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/HttpTimeoutError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class HttpTimeoutError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/HttpUnauthorizedError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/HttpUnauthorizedError.php new file mode 100644 index 00000000000..9b1edb20333 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/HttpUnauthorizedError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class HttpUnauthorizedError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/HttpUrlError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/HttpUrlError.php new file mode 100644 index 00000000000..fa2af82c564 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/HttpUrlError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class HttpUrlError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/IOError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/IOError.php new file mode 100644 index 00000000000..df816336c6c --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/IOError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class IOError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/IdRequiredError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/IdRequiredError.php new file mode 100644 index 00000000000..398b9f3fd85 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/IdRequiredError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class IdRequiredError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ImageError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ImageError.php new file mode 100644 index 00000000000..3b846a7551f --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ImageError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class ImageError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/InstanceCreateError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/InstanceCreateError.php new file mode 100644 index 00000000000..65caa154497 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/InstanceCreateError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class InstanceCreateError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/InstanceDeleteError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/InstanceDeleteError.php new file mode 100644 index 00000000000..e4c6fdb7f57 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/InstanceDeleteError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class InstanceDeleteError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/InstanceError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/InstanceError.php new file mode 100644 index 00000000000..48152824862 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/InstanceError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class InstanceError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/InstanceFlavorError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/InstanceFlavorError.php new file mode 100644 index 00000000000..e8a074eb9bf --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/InstanceFlavorError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class InstanceFlavorError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/InstanceNotFound.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/InstanceNotFound.php new file mode 100644 index 00000000000..4bc94797b3f --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/InstanceNotFound.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class InstanceNotFound extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/InstanceUpdateError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/InstanceUpdateError.php new file mode 100644 index 00000000000..b15f3426013 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/InstanceUpdateError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class InstanceUpdateError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/InvalidArgumentError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/InvalidArgumentError.php new file mode 100644 index 00000000000..a655f11a731 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/InvalidArgumentError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class InvalidArgumentError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/InvalidIdTypeError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/InvalidIdTypeError.php new file mode 100644 index 00000000000..f329c748957 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/InvalidIdTypeError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class InvalidIdTypeError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/InvalidIpTypeError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/InvalidIpTypeError.php new file mode 100644 index 00000000000..370d8f650de --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/InvalidIpTypeError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class InvalidIpTypeError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/InvalidParameterError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/InvalidParameterError.php new file mode 100644 index 00000000000..f13986ffc94 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/InvalidParameterError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class InvalidParameterError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/InvalidRequestError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/InvalidRequestError.php new file mode 100644 index 00000000000..0266d8f22bd --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/InvalidRequestError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class InvalidRequestError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/JsonError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/JsonError.php new file mode 100644 index 00000000000..96f9102ed37 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/JsonError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class JsonError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/LoggingException.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/LoggingException.php new file mode 100644 index 00000000000..a5bdad705f4 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/LoggingException.php @@ -0,0 +1,16 @@ +<?php +/** + * @copyright Copyright 2012-2013 Rackspace US, Inc. + See COPYING for licensing information. + * @license https://www.apache.org/licenses/LICENSE-2.0 Apache 2.0 + * @version 1.5.9 + * @author Jamie Hannaford <jamie.hannaford@rackspace.com> + */ + +namespace OpenCloud\Common\Exceptions; + +use Exception; + +class LoggingException extends Exception +{ +}
\ No newline at end of file diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/MetadataCreateError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/MetadataCreateError.php new file mode 100644 index 00000000000..a119397392f --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/MetadataCreateError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class MetadataCreateError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/MetadataDeleteError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/MetadataDeleteError.php new file mode 100644 index 00000000000..4acd879afe9 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/MetadataDeleteError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class MetadataDeleteError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/MetadataError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/MetadataError.php new file mode 100644 index 00000000000..65f94975a44 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/MetadataError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class MetadataError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/MetadataJsonError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/MetadataJsonError.php new file mode 100644 index 00000000000..a7a74ca9e13 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/MetadataJsonError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class MetadataJsonError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/MetadataKeyError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/MetadataKeyError.php new file mode 100644 index 00000000000..606f6d95874 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/MetadataKeyError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class MetadataKeyError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/MetadataPrefixError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/MetadataPrefixError.php new file mode 100644 index 00000000000..271e69010a7 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/MetadataPrefixError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class MetadataPrefixError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/MetadataUpdateError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/MetadataUpdateError.php new file mode 100644 index 00000000000..49db43d6f70 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/MetadataUpdateError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class MetadataUpdateError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/MisMatchedChecksumError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/MisMatchedChecksumError.php new file mode 100644 index 00000000000..75b4f926995 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/MisMatchedChecksumError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class MisMatchedChecksumError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/MissingValueError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/MissingValueError.php new file mode 100644 index 00000000000..0dd5b8ee737 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/MissingValueError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class MissingValueError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/NameError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/NameError.php new file mode 100644 index 00000000000..6918120a56c --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/NameError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class NameError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/NetworkCreateError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/NetworkCreateError.php new file mode 100644 index 00000000000..a0c7640ffe8 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/NetworkCreateError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class NetworkCreateError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/NetworkDeleteError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/NetworkDeleteError.php new file mode 100644 index 00000000000..0e2922babe2 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/NetworkDeleteError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class NetworkDeleteError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/NetworkError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/NetworkError.php new file mode 100644 index 00000000000..4b30806c1bc --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/NetworkError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class NetworkError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/NetworkUpdateError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/NetworkUpdateError.php new file mode 100644 index 00000000000..f55f09d8ec2 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/NetworkUpdateError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class NetworkUpdateError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/NetworkUrlError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/NetworkUrlError.php new file mode 100644 index 00000000000..666ec50482b --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/NetworkUrlError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class NetworkUrlError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/NoContentTypeError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/NoContentTypeError.php new file mode 100644 index 00000000000..59a33088163 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/NoContentTypeError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class NoContentTypeError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/NoNameError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/NoNameError.php new file mode 100644 index 00000000000..2d56f5fcd0d --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/NoNameError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class NoNameError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ObjFetchError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ObjFetchError.php new file mode 100644 index 00000000000..9d7391823e8 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ObjFetchError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class ObjFetchError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ObjectCopyError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ObjectCopyError.php new file mode 100644 index 00000000000..ef7b3b39220 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ObjectCopyError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class ObjectCopyError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ObjectError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ObjectError.php new file mode 100644 index 00000000000..ea667ad25f6 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ObjectError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class ObjectError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/RebuildError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/RebuildError.php new file mode 100644 index 00000000000..9ee6ab37fd9 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/RebuildError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class RebuildError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/RecordTypeError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/RecordTypeError.php new file mode 100644 index 00000000000..718ce98574c --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/RecordTypeError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class RecordTypeError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ServerActionError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ServerActionError.php new file mode 100644 index 00000000000..d4ad6453281 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ServerActionError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class ServerActionError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ServerCreateError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ServerCreateError.php new file mode 100644 index 00000000000..69904111c61 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ServerCreateError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class ServerCreateError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ServerDeleteError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ServerDeleteError.php new file mode 100644 index 00000000000..94a1adc4f0b --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ServerDeleteError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class ServerDeleteError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ServerImageScheduleError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ServerImageScheduleError.php new file mode 100644 index 00000000000..19fbcbd279c --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ServerImageScheduleError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class ServerImageScheduleError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ServerIpsError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ServerIpsError.php new file mode 100644 index 00000000000..3e737c28614 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ServerIpsError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class ServerIpsError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ServerJsonError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ServerJsonError.php new file mode 100644 index 00000000000..c10e67d645d --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ServerJsonError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class ServerJsonError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ServerUpdateError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ServerUpdateError.php new file mode 100644 index 00000000000..d9d7b370808 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ServerUpdateError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class ServerUpdateError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ServerUrlError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ServerUrlError.php new file mode 100644 index 00000000000..ba0308d04e7 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ServerUrlError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class ServerUrlError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ServiceValueError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ServiceValueError.php new file mode 100644 index 00000000000..7ce52c846a4 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/ServiceValueError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class ServiceValueError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/SnapshotError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/SnapshotError.php new file mode 100644 index 00000000000..14d7614a9ee --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/SnapshotError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class SnapshotError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/TempUrlMethodError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/TempUrlMethodError.php new file mode 100644 index 00000000000..61f4647d1b3 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/TempUrlMethodError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class TempUrlMethodError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UnknownError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UnknownError.php new file mode 100644 index 00000000000..2b0772530fc --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UnknownError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class UnknownError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UnknownParameterError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UnknownParameterError.php new file mode 100644 index 00000000000..704ee28c052 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UnknownParameterError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class UnknownParameterError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UnrecognizedServiceError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UnrecognizedServiceError.php new file mode 100644 index 00000000000..396d451e131 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UnrecognizedServiceError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class UnrecognizedServiceError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UnsupportedExtensionError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UnsupportedExtensionError.php new file mode 100644 index 00000000000..5ff5ae89c73 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UnsupportedExtensionError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class UnsupportedExtensionError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UnsupportedFeatureExtension.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UnsupportedFeatureExtension.php new file mode 100644 index 00000000000..6d9143a1d91 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UnsupportedFeatureExtension.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class UnsupportedFeatureExtension extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UnsupportedVersionError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UnsupportedVersionError.php new file mode 100644 index 00000000000..060733ad5b5 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UnsupportedVersionError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class UnsupportedVersionError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UpdateError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UpdateError.php new file mode 100644 index 00000000000..23f0dbb6aa7 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UpdateError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class UpdateError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UrlError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UrlError.php new file mode 100644 index 00000000000..6c4d9ab69aa --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UrlError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class UrlError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UserCreateError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UserCreateError.php new file mode 100644 index 00000000000..f87ee0d2fc9 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UserCreateError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class UserCreateError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UserDeleteError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UserDeleteError.php new file mode 100644 index 00000000000..3196289aafc --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UserDeleteError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class UserDeleteError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UserListError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UserListError.php new file mode 100644 index 00000000000..7d287ae0ecf --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UserListError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class UserListError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UserNameError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UserNameError.php new file mode 100644 index 00000000000..51902f8e93c --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UserNameError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class UserNameError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UserUpdateError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UserUpdateError.php new file mode 100644 index 00000000000..403b53420d0 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/UserUpdateError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class UserUpdateError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/VolumeError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/VolumeError.php new file mode 100644 index 00000000000..c19c4c2009d --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/VolumeError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class VolumeError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/VolumeTypeError.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/VolumeTypeError.php new file mode 100644 index 00000000000..a9cc1e3f64b --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Exceptions/VolumeTypeError.php @@ -0,0 +1,5 @@ +<?php + +namespace OpenCloud\Common\Exceptions; + +class VolumeTypeError extends \Exception {} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Identity/Role.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Identity/Role.php new file mode 100644 index 00000000000..b2c480d71b5 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Identity/Role.php @@ -0,0 +1,21 @@ +<?php + +/** + * PHP OpenCloud library. + * + * @author Jamie Hannaford <jamie@limetree.org> + * @version 2.0.0 + * @copyright Copyright 2012-2013 Rackspace US, Inc. + * @license https://www.apache.org/licenses/LICENSE-2.0 Apache 2.0 + */ + +/** + * Description of Role + * + * @link + * + * @codeCoverageIgnore + */ +class Role +{ +}
\ No newline at end of file diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Identity/Tenant.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Identity/Tenant.php new file mode 100644 index 00000000000..62783613c2f --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Identity/Tenant.php @@ -0,0 +1,22 @@ +<?php + +/** + * PHP OpenCloud library. + * + * @author Jamie Hannaford <jamie@limetree.org> + * @version 2.0.0 + * @copyright Copyright 2012-2013 Rackspace US, Inc. + * @license https://www.apache.org/licenses/LICENSE-2.0 Apache 2.0 + */ + +/** + * Description of Tenant + * + * @link + * + * @codeCoverageIgnore + */ +class Tenant +{ + +}
\ No newline at end of file diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Identity/User.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Identity/User.php new file mode 100644 index 00000000000..9e3862d1750 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Identity/User.php @@ -0,0 +1,73 @@ +<?php +/** + * @copyright 2012-2013 Rackspace Hosting, Inc. + * See COPYING for licensing information + * @package phpOpenCloud + * @version 1.5.9 + * @author Glen Campbell <glen.campbell@rackspace.com> + * @author Jamie Hannaford <jamie.hannaford@rackspace.co.uk> + */ + +/** + * Represents a sub-user in Keystone. + * + * @link http://docs.rackspace.com/auth/api/v2.0/auth-client-devguide/content/User_Calls.html + * + * @codeCoverageIgnore + */ +class User extends PersistentObject +{ + + public static function factory($info) + { + $user = new self; + } + + /** + * Return detailed information about a specific user, by either user name or user ID. + * @param int|string $info + */ + public function get($info) + { + if (is_integer($info)) { + + } elseif (is_string($info)) { + + } else { + throw new Exception\IdentityException(sprintf( + 'A string-based username or an integer-based user ID is valid' + )); + } + } + + public function create() + { + + } + + public function update() + { + + } + + public function delete() + { + + } + + public function listAllCredentials() + { + + } + + public function getCredentials() + { + + } + + public function resetApiKey() + { + + } + +}
\ No newline at end of file diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Lang.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Lang.php new file mode 100644 index 00000000000..7bb12859734 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Lang.php @@ -0,0 +1,21 @@ +<?php + +namespace OpenCloud\Common; + +class Lang +{ + + public static function translate($word = null) + { + return $word; + } + + public static function noslash($str) + { + while ($str && (substr($str, -1) == '/')) { + $str = substr($str, 0, strlen($str) - 1); + } + return $str; + } + +} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Log/AbstractLogger.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Log/AbstractLogger.php new file mode 100644 index 00000000000..c7aea7f8767 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Log/AbstractLogger.php @@ -0,0 +1,140 @@ +<?php + +// Copyright (c) 2012 PHP Framework Interoperability Group +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +namespace OpenCloud\Common\Log; + +/** + * This is a simple Logger implementation that other Loggers can inherit from. + * + * It simply delegates all log-level-specific methods to the `log` method to + * reduce boilerplate code that a simple Logger that does the same thing with + * messages regardless of the error level has to implement. + */ +abstract class AbstractLogger implements LoggerInterface +{ + /** + * System is unusable. + * + * @param string $message + * @param array $context + * @return null + */ + public function emergency($message, array $context = array()) + { + $this->log(LogLevel::EMERGENCY, $message, $context); + } + + /** + * Action must be taken immediately. + * + * Example: Entire website down, database unavailable, etc. This should + * trigger the SMS alerts and wake you up. + * + * @param string $message + * @param array $context + * @return null + */ + public function alert($message, array $context = array()) + { + $this->log(LogLevel::ALERT, $message, $context); + } + + /** + * Critical conditions. + * + * Example: Application component unavailable, unexpected exception. + * + * @param string $message + * @param array $context + * @return null + */ + public function critical($message, array $context = array()) + { + $this->log(LogLevel::CRITICAL, $message, $context); + } + + /** + * Runtime errors that do not require immediate action but should typically + * be logged and monitored. + * + * @param string $message + * @param array $context + * @return null + */ + public function error($message, array $context = array()) + { + $this->log(LogLevel::ERROR, $message, $context); + } + + /** + * Exceptional occurrences that are not errors. + * + * Example: Use of deprecated APIs, poor use of an API, undesirable things + * that are not necessarily wrong. + * + * @param string $message + * @param array $context + * @return null + */ + public function warning($message, array $context = array()) + { + $this->log(LogLevel::WARNING, $message, $context); + } + + /** + * Normal but significant events. + * + * @param string $message + * @param array $context + * @return null + */ + public function notice($message, array $context = array()) + { + $this->log(LogLevel::NOTICE, $message, $context); + } + + /** + * Interesting events. + * + * Example: User logs in, SQL logs. + * + * @param string $message + * @param array $context + * @return null + */ + public function info($message, array $context = array()) + { + $this->log(LogLevel::INFO, $message, $context); + } + + /** + * Detailed debug information. + * + * @param string $message + * @param array $context + * @return null + */ + public function debug($message, array $context = array()) + { + $this->log(LogLevel::DEBUG, $message, $context); + } +}
\ No newline at end of file diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Log/LogLevel.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Log/LogLevel.php new file mode 100644 index 00000000000..64b0169b507 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Log/LogLevel.php @@ -0,0 +1,38 @@ +<?php + +// Copyright (c) 2012 PHP Framework Interoperability Group +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +namespace OpenCloud\Common\Log; + +/** + * Describes log levels + */ +class LogLevel +{ + const EMERGENCY = 'emergency'; + const ALERT = 'alert'; + const CRITICAL = 'critical'; + const ERROR = 'error'; + const WARNING = 'warning'; + const NOTICE = 'notice'; + const INFO = 'info'; + const DEBUG = 'debug'; +}
\ No newline at end of file diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Log/Logger.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Log/Logger.php new file mode 100644 index 00000000000..e11d3fbb7ca --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Log/Logger.php @@ -0,0 +1,220 @@ +<?php +/** + * @copyright Copyright 2012-2013 Rackspace US, Inc. + See COPYING for licensing information. + * @license https://www.apache.org/licenses/LICENSE-2.0 Apache 2.0 + * @version 1.5.9 + * @author Jamie Hannaford <jamie.hannaford@rackspace.com> + */ + +namespace OpenCloud\Common\Log; + +use OpenCloud\Common\Exceptions\LoggingException; + +/** + * Basic logger for OpenCloud which extends FIG's PSR-3 standard logger. + * + * @link https://github.com/php-fig/log + */ +class Logger extends AbstractLogger +{ + /** + * Is this debug class enabled or not? + * + * @var bool + */ + private $enabled = false; + + /** + * These are the levels which will always be outputted - regardless of + * user-imposed settings. + * + * @var array + */ + private $urgentLevels = array( + LogLevel::EMERGENCY, + LogLevel::ALERT, + LogLevel::CRITICAL + ); + + /** + * Logging options. + * + * @var array + */ + private $options = array( + 'outputToFile' => false, + 'logFile' => null, + 'dateFormat' => 'd/m/y H:I', + 'delimeter' => ' - ' + ); + + /** + * Determines whether a log level needs to be outputted. + * + * @param string $logLevel + * @return bool + */ + private function outputIsUrgent($logLevel) + { + return in_array($logLevel, $this->urgentLevels); + } + + /** + * Interpolates context values into the message placeholders. + * + * @param string $message + * @param array $context + * @return type + */ + private function interpolate($message, array $context = array()) + { + // build a replacement array with braces around the context keys + $replace = array(); + foreach ($context as $key => $val) { + $replace['{' . $key . '}'] = $val; + } + + // interpolate replacement values into the message and return + return strtr($message, $replace); + } + + /** + * Enable or disable the debug class. + * + * @param bool $enabled + * @return self + */ + public function setEnabled($enabled) + { + $this->enabled = $enabled; + return $this; + } + + /** + * Is the debug class enabled? + * + * @return bool + */ + public function getEnabled() + { + return $this->enabled; + } + + /** + * Set an array of options. + * + * @param array $options + */ + public function setOptions(array $options = array()) + { + foreach ($options as $key => $value) { + $this->setOption($key, $value); + } + } + + /** + * Get all options. + * + * @return array + */ + public function getOptions() + { + return $this->options; + } + + /** + * Set an individual option. + * + * @param string $key + * @param string $value + */ + public function setOption($key, $value) + { + if ($this->optionExists($key)) { + $this->options[$key] = $value; + } + } + + /** + * Get an individual option. + * + * @param string $key + * @return string|null + */ + public function getOption($key) + { + if ($this->optionExists($key)) { + return $this->options[$key]; + } + } + + /** + * Check whether an individual option exists. + * + * @param string $key + * @return bool + */ + private function optionExists($key) + { + return array_key_exists($key, $this->getOptions()); + } + + /** + * Outputs a log message if necessary. + * + * @param string $logLevel + * @param string $message + * @param string $context + */ + public function log($level, $message, array $context = array()) + { + if ($this->outputIsUrgent($level) + || $this->getEnabled() === true + || RAXSDK_DEBUG === true + ) { + $this->dispatch($message, $context); + } + } + + /** + * Used to format the line outputted in the log file. + * + * @param string $string + * @return string + */ + private function formatFileLine($string) + { + $format = $this->getOption('dateFormat') . $this->getOption('delimeter'); + return date($format) . $string; + } + + /** + * Dispatch a log output message. + * + * @param string $message + * @param array $context + * @throws LoggingException + */ + private function dispatch($message, $context) + { + $output = $this->interpolate($message, $context) . PHP_EOL; + + if ($this->getOption('outputToFile') === true) { + $file = $this->getOption('logFile'); + + if (!is_writable($file)) { + throw new LoggingException( + 'The log file either does not exist or is not writeable' + ); + } + + // Output to file + file_put_contents($file, $this->formatFileLine($output)); + } else { + + echo $output; + } + } + +}
\ No newline at end of file diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Log/LoggerInterface.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Log/LoggerInterface.php new file mode 100644 index 00000000000..daef1b04dad --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Log/LoggerInterface.php @@ -0,0 +1,134 @@ +<?php + +// Copyright (c) 2012 PHP Framework Interoperability Group +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +namespace OpenCloud\Common\Log; + +/** + * Describes a logger instance + * + * The message MUST be a string or object implementing __toString(). + * + * The message MAY contain placeholders in the form: {foo} where foo + * will be replaced by the context data in key "foo". + * + * The context array can contain arbitrary data, the only assumption that + * can be made by implementors is that if an Exception instance is given + * to produce a stack trace, it MUST be in a key named "exception". + * + * See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md + * for the full interface specification. + */ +interface LoggerInterface +{ + /** + * System is unusable. + * + * @param string $message + * @param array $context + * @return null + */ + public function emergency($message, array $context = array()); + + /** + * Action must be taken immediately. + * + * Example: Entire website down, database unavailable, etc. This should + * trigger the SMS alerts and wake you up. + * + * @param string $message + * @param array $context + * @return null + */ + public function alert($message, array $context = array()); + + /** + * Critical conditions. + * + * Example: Application component unavailable, unexpected exception. + * + * @param string $message + * @param array $context + * @return null + */ + public function critical($message, array $context = array()); + + /** + * Runtime errors that do not require immediate action but should typically + * be logged and monitored. + * + * @param string $message + * @param array $context + * @return null + */ + public function error($message, array $context = array()); + + /** + * Exceptional occurrences that are not errors. + * + * Example: Use of deprecated APIs, poor use of an API, undesirable things + * that are not necessarily wrong. + * + * @param string $message + * @param array $context + * @return null + */ + public function warning($message, array $context = array()); + + /** + * Normal but significant events. + * + * @param string $message + * @param array $context + * @return null + */ + public function notice($message, array $context = array()); + + /** + * Interesting events. + * + * Example: User logs in, SQL logs. + * + * @param string $message + * @param array $context + * @return null + */ + public function info($message, array $context = array()); + + /** + * Detailed debug information. + * + * @param string $message + * @param array $context + * @return null + */ + public function debug($message, array $context = array()); + + /** + * Logs with an arbitrary level. + * + * @param mixed $level + * @param string $message + * @param array $context + * @return null + */ + public function log($level, $message, array $context = array()); +}
\ No newline at end of file diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Metadata.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Metadata.php new file mode 100644 index 00000000000..be6903e897e --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Metadata.php @@ -0,0 +1,92 @@ +<?php +/** + * A metadata object, used by other components in Compute and Object Storage + * + * @copyright 2012-2013 Rackspace Hosting, Inc. + * See COPYING for licensing information + * + * @package phpOpenCloud + * @version 1.0 + * @author Glen Campbell <glen.campbell@rackspace.com> + */ + +namespace OpenCloud\Common; + +/** + * The Metadata class represents either Server or Image metadata + * + * @api + * @author Glen Campbell <glen.campbell@rackspace.com> + */ +class Metadata extends Base +{ + + // array holding the names of keys that were set + private $_keylist = array(); + + /** + * This setter overrides the base one, since the metadata key can be + * anything + * + * @param string $key + * @param string $value + * @return void + */ + public function __set($key, $value) + { + // set the value and track the keys + if (!in_array($key, $this->_keylist)) { + $this->_keylist[] = $key; + } + + $this->$key = $value; + } + + /** + * Returns the list of keys defined + * + * @return array + */ + public function Keylist() + { + return $this->_keylist; + } + + /** + * Sets metadata values from an array, with optional prefix + * + * If $prefix is provided, then only array keys that match the prefix + * are set as metadata values, and $prefix is stripped from the key name. + * + * @param array $values an array of key/value pairs to set + * @param string $prefix if provided, a prefix that is used to identify + * metadata values. For example, you can set values from headers + * for a Container by using $prefix='X-Container-Meta-'. + * @return void + */ + public function setArray($values, $prefix = null) + { + if (empty($values)) { + return false; + } + + foreach ($values as $key => $value) { + if ($prefix) { + if (strpos($key, $prefix) === 0) { + $name = substr($key, strlen($prefix)); + $this->getLogger()->info( + Lang::translate('Setting [{name}] to [{value}]'), + array( + 'name' => $name, + 'value' => $value + ) + ); + $this->$name = $value; + } + } else { + $this->$key = $value; + } + } + } + +} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Nova.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Nova.php new file mode 100644 index 00000000000..fe4dcccc73f --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Nova.php @@ -0,0 +1,140 @@ +<?php + +/** + * An abstract class that defines shared components for products that use + * OpenStack Nova + * + * @copyright 2012-2013 Rackspace Hosting, Inc. + * See COPYING for licensing information + * + * @package phpOpenCloud + * @version 1.0 + * @author Glen Campbell <glen.campbell@rackspace.com> + */ + +namespace OpenCloud\Common; + +use OpenCloud\OpenStack; +use OpenCloud\Common\Lang; +use OpenCloud\Compute\Flavor; + +/** + * Nova is an abstraction layer for the OpenStack compute service. + * + * Nova is used as a basis for several products, including Compute services + * as well as Rackspace's Cloud Databases. This class is, in essence, a vehicle + * for sharing common code between those other classes. + */ +abstract class Nova extends Service +{ + + private $_url; + + /** + * Called when creating a new Compute service object + * + * _NOTE_ that the order of parameters for this is *different* from the + * parent Service class. This is because the earlier parameters are the + * ones that most typically change, whereas the later ones are not + * modified as often. + * + * @param \OpenCloud\Identity $conn - a connection object + * @param string $serviceRegion - identifies the region of this Compute + * service + * @param string $urltype - identifies the URL type ("publicURL", + * "privateURL") + * @param string $serviceName - identifies the name of the service in the + * catalog + */ + public function __construct( + OpenStack $conn, + $serviceType, + $serviceName, + $serviceRegion, + $urltype + ) { + parent::__construct( + $conn, + $serviceType, + $serviceName, + $serviceRegion, + $urltype + ); + + $this->_url = Lang::noslash(parent::Url()); + + $this->getLogger()->info(Lang::translate('Initializing Nova...')); + } + + /** + * Returns a flavor from the service + * + * This is a factory method and should generally be called instead of + * creating a Flavor object directly. + * + * @api + * @param string $id - if supplied, the Flavor identified by this is + * retrieved + * @return Compute\Flavor object + */ + public function Flavor($id = null) + { + return new Flavor($this, $id); + } + + /** + * Returns a list of Flavor objects + * + * This is a factory method and should generally be called instead of + * creating a FlavorList object directly. + * + * @api + * @param boolean $details - if TRUE (the default), returns full details. + * Set to FALSE to retrieve minimal details and possibly improve + * performance. + * @param array $filter - optional key/value pairs for creating query + * strings + * @return Collection (or FALSE on an error) + */ + public function FlavorList($details = true, array $filter = array()) + { + if ($details) { + $url = $this->Url(Flavor::ResourceName().'/detail', $filter); + } else { + $url = $this->Url(Flavor::ResourceName(), $filter); + } + return $this->Collection('\OpenCloud\Compute\Flavor', $url); + } + + /** + * Gets a request from an HTTP source and ensures that the + * content type is always "application/json" + * + * This is a simple subclass of the parent::Request() method that ensures + * that all Compute requests use application/json as the Content-Type: + * + * @param string $url - the URL of the request + * @param string $method - the HTTP method ("GET" by default) + * @param array $headers - an associative array of headers to pass to + * the request + * @param string $body - optional body for POST or PUT requests + * @return \Rackspace\HttpResult object + */ + public function Request($url, $method = 'GET', array $headers = array(), $body = null) + { + $headers['Content-Type'] = RAXSDK_CONTENT_TYPE_JSON; + return parent::Request($url, $method, $headers, $body); + } + + /** + * Loads the available namespaces from the /extensions resource + */ + protected function load_namespaces() + { + $ext = $this->Extensions(); + foreach($ext as $obj) { + $this->_namespaces[] = $obj->alias; + } + } + +} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/PersistentObject.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/PersistentObject.php new file mode 100644 index 00000000000..0257526d709 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/PersistentObject.php @@ -0,0 +1,939 @@ +<?php +/** + * An abstraction that defines persistent objects associated with a service + * + * @copyright 2012-2013 Rackspace Hosting, Inc. + * See COPYING for licensing information + * + * @package phpOpenCloud + * @version 1.0 + * @author Glen Campbell <glen.campbell@rackspace.com> + * @author Jamie Hannaford <jamie.hannaford@rackspace.com> + */ + +namespace OpenCloud\Common; + +/** + * Represents an object that can be retrieved, created, updated and deleted. + * + * This class abstracts much of the common functionality between: + * + * * Nova servers; + * * Swift containers and objects; + * * DBAAS instances; + * * Cinder volumes; + * * and various other objects that: + * * have a URL; + * * can be created, updated, deleted, or retrieved; + * * use a standard JSON format with a top-level element followed by + * a child object with attributes. + * + * In general, you can create a persistent object class by subclassing this + * class and defining some protected, static variables: + * + * * $url_resource - the sub-resource value in the URL of the parent. For + * example, if the parent URL is `http://something/parent`, then setting this + * value to "another" would result in a URL for the persistent object of + * `http://something/parent/another`. + * + * * $json_name - the top-level JSON object name. For example, if the + * persistent object is represented by `{"foo": {"attr":value, ...}}`, then + * set $json_name to "foo". + * + * * $json_collection_name - optional; this value is the name of a collection + * of the persistent objects. If not provided, it defaults to `json_name` + * with an appended "s" (e.g., if `json_name` is "foo", then + * `json_collection_name` would be "foos"). Set this value if the collection + * name doesn't follow this pattern. + * + * * $json_collection_element - the common pattern for a collection is: + * `{"collection": [{"attr":"value",...}, {"attr":"value",...}, ...]}` + * That is, each element of the array is a \stdClass object containing the + * object's attributes. In rare instances, the objects in the array + * are named, and `json_collection_element` contains the name of the + * collection objects. For example, in this JSON response: + * `{"allowedDomain":[{"allowedDomain":{"name":"foo"}}]}`, + * `json_collection_element` would be set to "allowedDomain". + * + * The PersistentObject class supports the standard CRUD methods; if these are + * not needed (i.e. not supported by the service), the subclass should redefine + * these to call the `noCreate`, `noUpdate`, or `noDelete` methods, which will + * trigger an appropriate exception. For example, if an object cannot be created: + * + * function create($params = array()) + * { + * $this->noCreate(); + * } + */ +abstract class PersistentObject extends Base +{ + + private $service; + + private $parent; + + protected $id; + + /** + * Retrieves the instance from persistent storage + * + * @param mixed $service The service object for this resource + * @param mixed $info The ID or array/object of data + */ + public function __construct($service = null, $info = null) + { + if ($service instanceof Service) { + $this->setService($service); + } + + if (property_exists($this, 'metadata')) { + $this->metadata = new Metadata; + } + + $this->populate($info); + } + + /** + * Validates properties that have a namespace: prefix + * + * If the property prefix: appears in the list of supported extension + * namespaces, then the property is applied to the object. Otherwise, + * an exception is thrown. + * + * @param string $name the name of the property + * @param mixed $value the property's value + * @return void + * @throws AttributeError + */ + public function __set($name, $value) + { + $this->setProperty($name, $value, $this->getService()->namespaces()); + } + + /** + * Sets the service associated with this resource object. + * + * @param \OpenCloud\Common\Service $service + */ + public function setService(Service $service) + { + $this->service = $service; + return $this; + } + + /** + * Returns the service object for this resource; required for making + * requests, etc. because it has direct access to the Connection. + * + * @return \OpenCloud\Common\Service + */ + public function getService() + { + if (null === $this->service) { + throw new Exceptions\ServiceValueError( + 'No service defined' + ); + } + return $this->service; + } + + /** + * Legacy shortcut to getService + * + * @return \OpenCloud\Common\Service + */ + public function service() + { + return $this->getService(); + } + + /** + * Set the parent object for this resource. + * + * @param \OpenCloud\Common\PersistentObject $parent + */ + public function setParent(PersistentObject $parent) + { + $this->parent = $parent; + return $this; + } + + /** + * Returns the parent. + * + * @return \OpenCloud\Common\PersistentObject + */ + public function getParent() + { + if (null === $this->parent) { + $this->parent = $this->getService(); + } + return $this->parent; + } + + /** + * Legacy shortcut to getParent + * + * @return \OpenCloud\Common\PersistentObject + */ + public function parent() + { + return $this->getParent(); + } + + + + + /** + * API OPERATIONS (CRUD & CUSTOM) + */ + + /** + * Creates a new object + * + * @api + * @param array $params array of values to set when creating the object + * @return HttpResponse + * @throws VolumeCreateError if HTTP status is not Success + */ + public function create($params = array()) + { + // set parameters + if (!empty($params)) { + $this->populate($params, false); + } + + // debug + $this->getLogger()->info('{class}::Create({name})', array( + 'class' => get_class($this), + 'name' => $this->Name() + )); + + // construct the JSON + $object = $this->createJson(); + $json = json_encode($object); + $this->checkJsonError(); + + $this->getLogger()->info('{class}::Create JSON [{json}]', array( + 'class' => get_class($this), + 'json' => $json + )); + + // send the request + $response = $this->getService()->request( + $this->createUrl(), + 'POST', + array('Content-Type' => 'application/json'), + $json + ); + + // check the return code + // @codeCoverageIgnoreStart + if ($response->httpStatus() > 204) { + throw new Exceptions\CreateError(sprintf( + Lang::translate('Error creating [%s] [%s], status [%d] response [%s]'), + get_class($this), + $this->Name(), + $response->HttpStatus(), + $response->HttpBody() + )); + } + + if ($response->HttpStatus() == "201" && ($location = $response->Header('Location'))) { + // follow Location header + $this->refresh(null, $location); + } else { + // set values from response + $object = json_decode($response->httpBody()); + + if (!$this->checkJsonError()) { + $top = $this->jsonName(); + if (isset($object->$top)) { + $this->populate($object->$top); + } + } + } + // @codeCoverageIgnoreEnd + + return $response; + } + + /** + * Updates an existing object + * + * @api + * @param array $params array of values to set when updating the object + * @return HttpResponse + * @throws VolumeCreateError if HTTP status is not Success + */ + public function update($params = array()) + { + // set parameters + if (!empty($params)) { + $this->populate($params); + } + + // debug + $this->getLogger()->info('{class}::Update({name})', array( + 'class' => get_class($this), + 'name' => $this->Name() + )); + + // construct the JSON + $obj = $this->updateJson($params); + $json = json_encode($obj); + + $this->checkJsonError(); + + $this->getLogger()->info('{class}::Update JSON [{json}]', array( + 'class' => get_class($this), + 'json' => $json + )); + + // send the request + $response = $this->getService()->Request( + $this->url(), + 'PUT', + array(), + $json + ); + + // check the return code + // @codeCoverageIgnoreStart + if ($response->HttpStatus() > 204) { + throw new Exceptions\UpdateError(sprintf( + Lang::translate('Error updating [%s] with [%s], status [%d] response [%s]'), + get_class($this), + $json, + $response->HttpStatus(), + $response->HttpBody() + )); + } + // @codeCoverageIgnoreEnd + + return $response; + } + + /** + * Deletes an object + * + * @api + * @return HttpResponse + * @throws DeleteError if HTTP status is not Success + */ + public function delete() + { + $this->getLogger()->info('{class}::Delete()', array('class' => get_class($this))); + + // send the request + $response = $this->getService()->request($this->url(), 'DELETE'); + + // check the return code + // @codeCoverageIgnoreStart + if ($response->HttpStatus() > 204) { + throw new Exceptions\DeleteError(sprintf( + Lang::translate('Error deleting [%s] [%s], status [%d] response [%s]'), + get_class(), + $this->Name(), + $response->HttpStatus(), + $response->HttpBody() + )); + } + // @codeCoverageIgnoreEnd + + return $response; + } + + /** + * Returns an object for the Create() method JSON + * Must be overridden in a child class. + * + * @throws CreateError if not overridden + */ + protected function createJson() + { + throw new Exceptions\CreateError(sprintf( + Lang::translate('[%s] CreateJson() must be overridden'), + get_class($this) + )); + } + + /** + * Returns an object for the Update() method JSON + * Must be overridden in a child class. + * + * @throws UpdateError if not overridden + */ + protected function updateJson($params = array()) + { + throw new Exceptions\UpdateError(sprintf( + Lang::translate('[%s] UpdateJson() must be overridden'), + get_class($this) + )); + } + + /** + * throws a CreateError for subclasses that don't support Create + * + * @throws CreateError + */ + protected function noCreate() + { + throw new Exceptions\CreateError(sprintf( + Lang::translate('[%s] does not support Create()'), + get_class() + )); + } + + /** + * throws a DeleteError for subclasses that don't support Delete + * + * @throws DeleteError + */ + protected function noDelete() + { + throw new Exceptions\DeleteError(sprintf( + Lang::translate('[%s] does not support Delete()'), + get_class() + )); + } + + /** + * throws a UpdateError for subclasses that don't support Update + * + * @throws UpdateError + */ + protected function noUpdate() + { + throw new Exceptions\UpdateError(sprintf( + Lang::translate('[%s] does not support Update()'), + get_class() + )); + } + + /** + * Returns the default URL of the object + * + * This may have to be overridden in subclasses. + * + * @param string $subresource optional sub-resource string + * @param array $qstr optional k/v pairs for query strings + * @return string + * @throws UrlError if URL is not defined + */ + public function url($subresource = null, $queryString = array()) + { + // find the primary key attribute name + $primaryKey = $this->primaryKeyField(); + + // first, see if we have a [self] link + $url = $this->findLink('self'); + + /** + * Next, check to see if we have an ID + * Note that we use Parent() instead of Service(), since the parent + * object might not be a service. + */ + if (!$url && $this->$primaryKey) { + $url = Lang::noslash($this->getParent()->url($this->resourceName())) . '/' . $this->$primaryKey; + } + + // add the subresource + if ($url) { + $url .= $subresource ? "/$subresource" : ''; + if (count($queryString)) { + $url .= '?' . $this->makeQueryString($queryString); + } + return $url; + } + + // otherwise, we don't have a URL yet + throw new Exceptions\UrlError(sprintf( + Lang::translate('%s does not have a URL yet'), + get_class($this) + )); + } + + /** + * Waits for the server/instance status to change + * + * This function repeatedly polls the system for a change in server + * status. Once the status reaches the `$terminal` value (or 'ERROR'), + * then the function returns. + * + * The polling interval is set by the constant RAXSDK_POLL_INTERVAL. + * + * The function will automatically terminate after RAXSDK_SERVER_MAXTIMEOUT + * seconds elapse. + * + * @api + * @param string $terminal the terminal state to wait for + * @param integer $timeout the max time (in seconds) to wait + * @param callable $callback a callback function that is invoked with + * each repetition of the polling sequence. This can be used, for + * example, to update a status display or to permit other operations + * to continue + * @return void + */ + public function waitFor( + $terminal = 'ACTIVE', + $timeout = RAXSDK_SERVER_MAXTIMEOUT, + $callback = NULL, + $sleep = RAXSDK_POLL_INTERVAL + ) { + // find the primary key field + $primaryKey = $this->PrimaryKeyField(); + + // save stats + $startTime = time(); + + $states = array('ERROR', $terminal); + + while (true) { + + $this->refresh($this->$primaryKey); + + if ($callback) { + call_user_func($callback, $this); + } + + if (in_array($this->status(), $states) || (time() - $startTime) > $timeout) { + return; + } + // @codeCoverageIgnoreStart + sleep($sleep); + } + } + // @codeCoverageIgnoreEnd + + /** + * Refreshes the object from the origin (useful when the server is + * changing states) + * + * @return void + * @throws IdRequiredError + */ + public function refresh($id = null, $url = null) + { + $primaryKey = $this->PrimaryKeyField(); + + if (!$url) { + if ($id === null) { + $id = $this->$primaryKey; + } + + if (!$id) { + throw new Exceptions\IdRequiredError(sprintf( + Lang::translate('%s has no ID; cannot be refreshed'), + get_class()) + ); + } + + // retrieve it + $this->getLogger()->info(Lang::translate('{class} id [{id}]'), array( + 'class' => get_class($this), + 'id' => $id + )); + + $this->$primaryKey = $id; + $url = $this->url(); + } + + // reset status, if available + if (property_exists($this, 'status')) { + $this->status = null; + } + + // perform a GET on the URL + $response = $this->getService()->Request($url); + + // check status codes + // @codeCoverageIgnoreStart + if ($response->HttpStatus() == 404) { + throw new Exceptions\InstanceNotFound( + sprintf(Lang::translate('%s [%s] not found [%s]'), + get_class($this), + $this->$primaryKey, + $url + )); + } + + if ($response->HttpStatus() >= 300) { + throw new Exceptions\UnknownError( + sprintf(Lang::translate('Unexpected %s error [%d] [%s]'), + get_class($this), + $response->HttpStatus(), + $response->HttpBody() + )); + } + + // check for empty response + if (!$response->HttpBody()) { + throw new Exceptions\EmptyResponseError( + sprintf(Lang::translate('%s::Refresh() unexpected empty response, URL [%s]'), + get_class($this), + $url + )); + } + + // we're ok, reload the response + if ($json = $response->HttpBody()) { + + $this->getLogger()->info('refresh() JSON [{json}]', array('json' => $json)); + + $response = json_decode($json); + + if ($this->CheckJsonError()) { + throw new Exceptions\ServerJsonError(sprintf( + Lang::translate('JSON parse error on %s refresh'), + get_class($this) + )); + } + + $top = $this->JsonName(); + + if ($top && isset($response->$top)) { + $content = $response->$top; + } else { + $content = $response; + } + + $this->populate($content); + + } + // @codeCoverageIgnoreEnd + } + + + /** + * OBJECT INFORMATION + */ + + /** + * Returns the displayable name of the object + * + * Can be overridden by child objects; *must* be overridden by child + * objects if the object does not have a `name` attribute defined. + * + * @api + * @return string + * @throws NameError if attribute 'name' is not defined + */ + public function name() + { + if (property_exists($this, 'name')) { + return $this->name; + } else { + throw new Exceptions\NameError(sprintf( + Lang::translate('Name attribute does not exist for [%s]'), + get_class($this) + )); + } + } + + /** + * Sends the json string to the /action resource + * + * This is used for many purposes, such as rebooting the server, + * setting the root password, creating images, etc. + * Since it can only be used on a live server, it checks for a valid ID. + * + * @param $object - this will be encoded as json, and we handle all the JSON + * error-checking in one place + * @throws ServerIdError if server ID is not defined + * @throws ServerActionError on other errors + * @returns boolean; TRUE if successful, FALSE otherwise + */ + protected function action($object) + { + $primaryKey = $this->primaryKeyField(); + + if (!$this->$primaryKey) { + throw new Exceptions\IdRequiredError(sprintf( + Lang::translate('%s is not defined'), + get_class($this) + )); + } + + if (!is_object($object)) { + throw new Exceptions\ServerActionError(sprintf( + Lang::translate('%s::Action() requires an object as its parameter'), + get_class($this) + )); + } + + // convert the object to json + $json = json_encode($object); + $this->getLogger()->info('JSON [{string}]', array('json' => $json)); + + $this->checkJsonError(); + + // debug - save the request + $this->getLogger()->info(Lang::translate('{class}::action [{json}]'), array( + 'class' => get_class($this), + 'json' => $json + )); + + // get the URL for the POST message + $url = $this->url('action'); + + // POST the message + $response = $this->getService()->request($url, 'POST', array(), $json); + + // @codeCoverageIgnoreStart + if (!is_object($response)) { + throw new Exceptions\HttpError(sprintf( + Lang::translate('Invalid response for %s::Action() request'), + get_class($this) + )); + } + + // check for errors + if ($response->HttpStatus() >= 300) { + throw new Exceptions\ServerActionError(sprintf( + Lang::translate('%s::Action() [%s] failed; response [%s]'), + get_class($this), + $url, + $response->HttpBody() + )); + } + // @codeCoverageIgnoreStart + + return $response; + } + + /** + * Execute a custom resource request. + * + * @param string $path + * @param string $method + * @param string|array|object $body + * @return boolean + * @throws Exceptions\InvalidArgumentError + * @throws Exceptions\HttpError + * @throws Exceptions\ServerActionError + */ + public function customAction($url, $method = 'GET', $body = null) + { + if (is_string($body) && (json_decode($body) === null)) { + throw new Exceptions\InvalidArgumentError( + 'Please provide either a well-formed JSON string, or an object ' + . 'for JSON serialization' + ); + } else { + $body = json_encode($body); + } + + // POST the message + $response = $this->service()->request($url, $method, array(), $body); + + if (!is_object($response)) { + throw new Exceptions\HttpError(sprintf( + Lang::translate('Invalid response for %s::customAction() request'), + get_class($this) + )); + } + + // check for errors + // @codeCoverageIgnoreStart + if ($response->HttpStatus() >= 300) { + throw new Exceptions\ServerActionError(sprintf( + Lang::translate('%s::customAction() [%s] failed; response [%s]'), + get_class($this), + $url, + $response->HttpBody() + )); + } + // @codeCoverageIgnoreEnd + + $object = json_decode($response->httpBody()); + + $this->checkJsonError(); + + return $object; + } + + /** + * returns the object's status or `N/A` if not available + * + * @api + * @return string + */ + public function status() + { + return (isset($this->status)) ? $this->status : 'N/A'; + } + + /** + * returns the object's identifier + * + * Can be overridden by a child class if the identifier is not in the + * `$id` property. Use of this function permits the `$id` attribute to + * be protected or private to prevent unauthorized overwriting for + * security. + * + * @api + * @return string + */ + public function id() + { + return $this->id; + } + + /** + * checks for `$alias` in extensions and throws an error if not present + * + * @throws UnsupportedExtensionError + */ + public function checkExtension($alias) + { + if (!in_array($alias, $this->getService()->namespaces())) { + throw new Exceptions\UnsupportedExtensionError(sprintf( + Lang::translate('Extension [%s] is not installed'), + $alias + )); + } + + return true; + } + + /** + * returns the region associated with the object + * + * navigates to the parent service to determine the region. + * + * @api + */ + public function region() + { + return $this->getService()->Region(); + } + + /** + * Since each server can have multiple links, this returns the desired one + * + * @param string $type - 'self' is most common; use 'bookmark' for + * the version-independent one + * @return string the URL from the links block + */ + public function findLink($type = 'self') + { + if (empty($this->links)) { + return false; + } + + foreach ($this->links as $link) { + if ($link->rel == $type) { + return $link->href; + } + } + + return false; + } + + /** + * returns the URL used for Create + * + * @return string + */ + protected function createUrl() + { + return $this->getParent()->Url($this->ResourceName()); + } + + /** + * Returns the primary key field for the object + * + * The primary key is usually 'id', but this function is provided so that + * (in rare cases where it is not 'id'), it can be overridden. + * + * @return string + */ + protected function primaryKeyField() + { + return 'id'; + } + + /** + * Returns the top-level document identifier for the returned response + * JSON document; must be overridden in child classes + * + * For example, a server document is (JSON) `{"server": ...}` and an + * Instance document is `{"instance": ...}` - this function must return + * the top level document name (either "server" or "instance", in + * these examples). + * + * @throws DocumentError if not overridden + */ + public static function jsonName() + { + if (isset(static::$json_name)) { + return static::$json_name; + } + + throw new Exceptions\DocumentError(sprintf( + Lang::translate('No JSON object defined for class [%s] in JsonName()'), + get_class() + )); + } + + /** + * returns the collection JSON element name + * + * When an object is returned in a collection, it usually has a top-level + * object that is an array holding child objects of the object types. + * This static function returns the name of the top-level element. Usually, + * that top-level element is simply the JSON name of the resource.'s'; + * however, it can be overridden by specifying the $json_collection_name + * attribute. + * + * @return string + */ + public static function jsonCollectionName() + { + if (isset(static::$json_collection_name)) { + return static::$json_collection_name; + } else { + return static::$json_name . 's'; + } + } + + /** + * returns the JSON name for each element in a collection + * + * Usually, elements in a collection are anonymous; this function, however, + * provides for an element level name: + * + * `{ "collection" : [ { "element" : ... } ] }` + * + * @return string + */ + public static function jsonCollectionElement() + { + if (isset(static::$json_collection_element)) { + return static::$json_collection_element; + } + } + + /** + * Returns the resource name for the URL of the object; must be overridden + * in child classes + * + * For example, a server is `/servers/`, a database instance is + * `/instances/`. Must be overridden in child classes. + * + * @throws UrlError + */ + public static function resourceName() + { + if (isset(static::$url_resource)) { + return static::$url_resource; + } + + throw new Exceptions\UrlError(sprintf( + Lang::translate('No URL resource defined for class [%s] in ResourceName()'), + get_class() + )); + } + +}
\ No newline at end of file diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Request/Curl.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Request/Curl.php new file mode 100644 index 00000000000..bb829afc5f6 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Request/Curl.php @@ -0,0 +1,308 @@ +<?php + +namespace OpenCloud\Common\Request; + +use OpenCloud\Common\Base; +use OpenCloud\Common\Lang; +use OpenCloud\Common\Exceptions\HttpRetryError; +use OpenCloud\Common\Exceptions\HttpUrlError; +use OpenCloud\Common\Exceptions\HttpTimeoutError; +use OpenCloud\Common\Exceptions\HttpError; + +/** + * The CurlRequest class is a simple wrapper to CURL functions. Not only does + * this permit stubbing of the interface as described under the HttpRequest + * interface, it could potentially allow us to replace the interface methods + * with other function calls in the future. + * + * @api + * @author Glen Campbell <glen.campbell@rackspace.com> + */ +class Curl extends Base implements HttpRequestInterface +{ + + private $url; + private $method; + private $handle; + private $retries = 0; + private $headers = array(); + private $returnheaders = array(); + + /** + * Initializes the CURL handle and HTTP method + * + * The constructor also sets a number of default values for options. + * + * @param string $url the URL to connect to + * @param string $method the HTTP method (default "GET") + * @param array $options optional hashed array of options => value pairs + */ + public function __construct($url, $method = 'GET', array $options = array()) + { + $this->url = $url; + $this->method = $method; + $this->handle = curl_init($url); + + // set our options + $this->setOption(CURLOPT_CUSTOMREQUEST, $method); + + foreach($options as $opt => $value) { + $this->getLogger()->info(Lang::translate('Setting option {key}={val}'), array( + 'key' => $opt, + 'val' => $value + )); + $this->setOption($opt, $value); + } + + // @codeCoverageIgnoreStart + if (RAXSDK_SSL_VERIFYHOST != 2) { + $this->getLogger()->warning("WARNING: RAXSDK_SSL_VERIFYHOST has reduced security, value [{value}]", array( + 'value' => RAXSDK_SSL_VERIFYHOST + )); + } + + if (RAXSDK_SSL_VERIFYPEER !== true) { + $this->getLogger()->warning("WARNING: RAXSDK_SSL_VERIFYPEER has reduced security"); + } + // @codeCoverageIgnoreEnd + + $this->setOption(CURLOPT_SSL_VERIFYHOST, RAXSDK_SSL_VERIFYHOST); + $this->setOption(CURLOPT_SSL_VERIFYPEER, RAXSDK_SSL_VERIFYPEER); + + if (defined('RAXSDK_CACERTPEM') && file_exists(RAXSDK_CACERTPEM)) { + $this->setOption(CURLOPT_CAINFO, RAXSDK_CACERTPEM); + } + + // curl code [18] + // message [transfer closed with x bytes remaining to read] + if ($method === 'HEAD') { + $this->setOption(CURLOPT_NOBODY, true); + } + + // follow redirects + $this->setOption(CURLOPT_FOLLOWLOCATION, true); + + // don't return the headers in the request + $this->setOption(CURLOPT_HEADER, false); + + // retrieve headers via callback + $this->setOption(CURLOPT_HEADERFUNCTION, array($this, '_get_header_cb')); + + // return the entire request on curl_exec() + $this->setOption(CURLOPT_RETURNTRANSFER, true); + + // set default timeouts + $this->setConnectTimeout(RAXSDK_CONNECTTIMEOUT); + $this->setHttpTimeout(RAXSDK_TIMEOUT); + } + + /** + * Sets a CURL option + * + * @param const $name - a CURL named constant; e.g. CURLOPT_TIMEOUT + * @param mixed $value - the value for the option + */ + public function setOption($name, $value) + { + return curl_setopt($this->handle, $name, $value); + } + + /** + * Explicit method for setting the connect timeout + * + * The connect timeout is the time it takes for the initial connection + * request to be established. It is different than the HTTP timeout, which + * is the time for the entire request to be serviced. + * + * @param integer $value The connection timeout in seconds. + * Use 0 to wait indefinitely (NOT recommended) + */ + public function setConnectTimeout($value) + { + $this->setOption(CURLOPT_CONNECTTIMEOUT, $value); + } + + /** + * Explicit method for setting the HTTP timeout + * + * The HTTP timeout is the time it takes for the HTTP request to be + * serviced. This value is usually larger than the connect timeout + * value. + * + * @param integer $value - the number of seconds to wait before timing out + * the HTTP request. + */ + public function setHttpTimeout($value) + { + $this->setOption(CURLOPT_TIMEOUT, $value); + } + + /** + * Sets the number of retries + * + * If you set this to a non-zero value, then it will repeat the request + * up to that number. + */ + public function setRetries($value) + { + $this->retries = $value; + } + + /** + * Simplified method for setting lots of headers at once + * + * This method takes an associative array of header/value pairs and calls + * the setheader() method on each of them. + * + * @param array $arr an associative array of headers + */ + public function setheaders($array) + { + if (!is_array($array)) { + throw new HttpError(Lang::translate( + 'Value passed to CurlRequest::setheaders() must be array' + )); + } + + foreach ($array as $name => $value) { + $this->setHeader($name, $value); + } + } + + /** + * Sets a single header + * + * For example, to set the content type to JSON: + * `$request->SetHeader('Content-Type','application/json');` + * + * @param string $name The name of the header + * @param mixed $value The value of the header + */ + public function setHeader($name, $value) + { + $this->headers[$name] = $value; + } + + /** + * Executes the current request + * + * This method actually performs the request using the values set + * previously. It throws a OpenCloud\HttpError exception on + * any CURL error. + * + * @return OpenCloud\HttpResponse + * @throws OpenCloud\HttpError + * + * @codeCoverageIgnore + */ + public function execute() + { + // set all the headers + $headarr = array(); + + foreach ($this->headers as $name => $value) { + $headarr[] = $name.': '.$value; + } + + $this->setOption(CURLOPT_HTTPHEADER, $headarr); + + // set up to retry if necessary + $try_counter = 0; + + do { + $data = curl_exec($this->handle); + if (curl_errno($this->handle) && ($try_counter<$this->retries)) { + $this->getLogger()->info(Lang::translate('Curl error [%d]; retrying [%s]'), array( + 'error' => curl_errno($this->handle), + 'url' => $this->url + )); + } + + } while((++$try_counter <= $this->retries) && (curl_errno($this->handle) != 0)); + + // log retries error + if ($this->retries && curl_errno($this->handle)) { + throw new HttpRetryError(sprintf( + Lang::translate('No more retries available, last error [%d]'), + curl_errno($this->handle) + )); + } + + // check for CURL errors + switch(curl_errno($this->handle)) { + case 0: + // everything's ok + break; + case 3: + throw new HttpUrlError(sprintf(Lang::translate('Malformed URL [%s]'), $this->url)); + break; + case 28: + // timeout + throw new HttpTimeoutError(Lang::translate('Operation timed out; check RAXSDK_TIMEOUT value')); + break; + default: + throw new HttpError(sprintf( + Lang::translate('HTTP error on [%s], curl code [%d] message [%s]'), + $this->url, + curl_errno($this->handle), + curl_error($this->handle) + )); + } + + // otherwise, return the HttpResponse + return new Response\Http($this, $data); + } + + /** + * returns an array of information about the request + */ + public function info() + { + return curl_getinfo($this->handle); + } + + /** + * returns the most recent CURL error number + */ + public function errno() + { + return curl_errno($this->handle); + } + + /** + * returns the most recent CURL error string + */ + public function error() + { + return curl_error($this->handle); + } + + /** + * Closes the HTTP request + */ + public function close() + { + return curl_close($this->handle); + } + + /** + * Returns the headers as an array + */ + public function returnHeaders() + { + return $this->returnheaders; + } + + /** + * This is a callback method used to handle the returned HTTP headers + * + * @param mixed $ch a CURL handle + * @param string $header the header string in its entirety + */ + public function _get_header_cb($ch, $header) + { + $this->returnheaders[] = $header; + return strlen($header); + } + +} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Request/HttpRequestInterface.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Request/HttpRequestInterface.php new file mode 100644 index 00000000000..cbe3b5412a1 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Request/HttpRequestInterface.php @@ -0,0 +1,23 @@ +<?php + +namespace OpenCloud\Common\Request; + +/** + * The HttpRequest interface defines methods for wrapping CURL; this allows + * those methods to be stubbed out for unit testing, thus allowing us to + * test without actually making live calls. + */ +interface HttpRequestInterface +{ + + public function SetOption($name, $value); + + public function setheaders($arr); + + public function SetHeader($header, $value); + + public function Execute(); + + public function close(); + +} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Request/Response/Blank.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Request/Response/Blank.php new file mode 100644 index 00000000000..0c79adcef3a --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Request/Response/Blank.php @@ -0,0 +1,27 @@ +<?php + +namespace OpenCloud\Common\Request\Response; + +class Blank extends Http +{ + public $errno; + public $error; + public $info; + public $body; + public $headers = array(); + public $status = 200; + public $rawdata; + + public function __construct(array $values = array()) + { + foreach($values as $name => $value) { + $this->$name = $value; + } + } + + public function httpStatus() + { + return $this->status; + } + +}
\ No newline at end of file diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Request/Response/Http.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Request/Response/Http.php new file mode 100644 index 00000000000..a7cb9e96346 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Request/Response/Http.php @@ -0,0 +1,140 @@ +<?php + +namespace OpenCloud\Common\Request\Response; + +use OpenCloud\Common\Base; + +/** + * The HttpResponse returns an object with status information, separated + * headers, and any response body necessary. + * + * @api + * @author Glen Campbell <glen.campbell@rackspace.com> + */ + +class Http extends Base +{ + + private $errno; + private $error; + private $info = array(); + protected $body; + protected $headers = array(); + + /** + * The constructor parses everything necessary + */ + public function __construct($request, $data) + { + // save the raw data (who knows? we might need it) + $this->setBody($data); + + // and split each line into name: value pairs + foreach($request->returnHeaders() as $line) { + if (preg_match('/^([^:]+):\s+(.+?)\s*$/', $line, $matches)) { + $this->headers[$matches[1]] = $matches[2]; + } else { + $this->headers[$line] = trim($line); + } + } + + // @codeCoverageIgnoreStart + if (isset($this->headers['Cache-Control'])) { + $this->getLogger()->info('Cache-Control: {header}', array( + 'headers' => $this->headers['Cache-Control'] + )); + } + if (isset($this->headers['Expires'])) { + $this->getLogger()->info('Expires: {header}', array( + 'headers' => $this->headers['Expires'] + )); + } + // @codeCoverageIgnoreEnd + + // set some other data + $this->info = $request->info(); + $this->errno = $request->errno(); + $this->error = $request->error(); + } + + /** + * Returns the full body of the request + * + * @return string + */ + public function httpBody() + { + return $this->body; + } + + /** + * Sets the body. + * + * @param string $body + */ + public function setBody($body) + { + $this->body = $body; + } + + /** + * Returns an array of headers + * + * @return associative array('header'=>value) + */ + public function headers() + { + return $this->headers; + } + + /** + * Returns a single header + * + * @return string with the value of the requested header, or NULL + */ + public function header($name) + { + return isset($this->headers[$name]) ? $this->headers[$name] : null; + } + + /** + * Returns an array of information + * + * @return array + */ + public function info() + { + return $this->info; + } + + /** + * Returns the most recent error number + * + * @return integer + */ + public function errno() + { + return $this->errno; + } + + /** + * Returns the most recent error message + * + * @return string + */ + public function error() + { + return $this->error; + } + + /** + * Returns the HTTP status code + * + * @return integer + */ + public function httpStatus() + { + return $this->info['http_code']; + } + +} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Service.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Service.php new file mode 100644 index 00000000000..5b3aa729a97 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/Service.php @@ -0,0 +1,489 @@ +<?php +/** + * PHP OpenCloud library. + * + * @copyright Copyright 2013 Rackspace US, Inc. See COPYING for licensing information. + * @license https://www.apache.org/licenses/LICENSE-2.0 Apache 2.0 + * @version 1.6.0 + * @author Jamie Hannaford <jamie.hannaford@rackspace.com> + */ + +namespace OpenCloud\Common; + +use OpenCloud\Common\Base; +use OpenCloud\Common\Lang; +use OpenCloud\OpenStack; +use OpenCloud\Common\Exceptions; + +/** + * This class defines a cloud service; a relationship between a specific OpenStack + * and a provided service, represented by a URL in the service catalog. + * + * Because Service is an abstract class, it cannot be called directly. Provider + * services such as Rackspace Cloud Servers or OpenStack Swift are each + * subclassed from Service. + * + * @author Glen Campbell <glen.campbell@rackspace.com> + */ + +abstract class Service extends Base +{ + + protected $conn; + private $service_type; + private $service_name; + private $service_region; + private $service_url; + + protected $_namespaces = array(); + + /** + * Creates a service on the specified connection + * + * Usage: `$x = new Service($conn, $type, $name, $region, $urltype);` + * The service's URL is defined in the OpenStack's serviceCatalog; it + * uses the $type, $name, $region, and $urltype to find the proper URL + * and set it. If it cannot find a URL in the service catalog that matches + * the criteria, then an exception is thrown. + * + * @param OpenStack $conn - a Connection object + * @param string $type - the service type (e.g., "compute") + * @param string $name - the service name (e.g., "cloudServersOpenStack") + * @param string $region - the region (e.g., "ORD") + * @param string $urltype - the specified URL from the catalog + * (e.g., "publicURL") + */ + public function __construct( + OpenStack $conn, + $type, + $name, + $region, + $urltype = RAXSDK_URL_PUBLIC, + $customServiceUrl = null + ) { + $this->setConnection($conn); + $this->service_type = $type; + $this->service_name = $name; + $this->service_region = $region; + $this->service_url = $customServiceUrl ?: $this->getEndpoint($type, $name, $region, $urltype); + } + + /** + * Set this service's connection. + * + * @param type $connection + */ + public function setConnection($connection) + { + $this->conn = $connection; + } + + /** + * Get this service's connection. + * + * @return type + */ + public function getConnection() + { + return $this->conn; + } + + /** + * Returns the URL for the Service + * + * @param string $resource optional sub-resource + * @param array $query optional k/v pairs for query strings + * @return string + */ + public function url($resource = '', array $param = array()) + { + $baseurl = $this->service_url; + + // use strlen instead of boolean test because '0' is a valid name + if (strlen($resource) > 0) { + $baseurl = Lang::noslash($baseurl).'/'.$resource; + } + + if (!empty($param)) { + $baseurl .= '?'.$this->MakeQueryString($param); + } + + return $baseurl; + } + + /** + * Returns the /extensions for the service + * + * @api + * @return array of objects + */ + public function extensions() + { + $ext = $this->getMetaUrl('extensions'); + return (is_object($ext) && isset($ext->extensions)) ? $ext->extensions : array(); + } + + /** + * Returns the /limits for the service + * + * @api + * @return array of limits + */ + public function limits() + { + $limits = $this->getMetaUrl('limits'); + return (is_object($limits)) ? $limits->limits : array(); + } + + /** + * Performs an authenticated request + * + * This method handles the addition of authentication headers to each + * request. It always adds the X-Auth-Token: header and will add the + * X-Auth-Project-Id: header if there is a tenant defined on the + * connection. + * + * @param string $url The URL of the request + * @param string $method The HTTP method (defaults to "GET") + * @param array $headers An associative array of headers + * @param string $body An optional body for POST/PUT requests + * @return \OpenCloud\HttpResult + */ + public function request( + $url, + $method = 'GET', + array $headers = array(), + $body = null + ) { + + $headers['X-Auth-Token'] = $this->conn->Token(); + + if ($tenant = $this->conn->Tenant()) { + $headers['X-Auth-Project-Id'] = $tenant; + } + + return $this->conn->request($url, $method, $headers, $body); + } + + /** + * returns a collection of objects + * + * @param string $class the class of objects to fetch + * @param string $url (optional) the URL to retrieve + * @param mixed $parent (optional) the parent service/object + * @return OpenCloud\Common\Collection + */ + public function collection($class, $url = null, $parent = null) + { + // Set the element names + $collectionName = $class::JsonCollectionName(); + $elementName = $class::JsonCollectionElement(); + + // Set the parent if empty + if (!$parent) { + $parent = $this; + } + + // Set the URL if empty + if (!$url) { + $url = $parent->url($class::ResourceName()); + } + + // Save debug info + $this->getLogger()->info( + '{class}:Collection({url}, {collectionClass}, {collectionName})', + array( + 'class' => get_class($this), + 'url' => $url, + 'collectionClass' => $class, + 'collectionName' => $collectionName + ) + ); + + // Fetch the list + $response = $this->request($url); + + $this->getLogger()->info('Response {status} [{body}]', array( + 'status' => $response->httpStatus(), + 'body' => $response->httpBody() + )); + + // Check return code + if ($response->httpStatus() > 204) { + throw new Exceptions\CollectionError(sprintf( + Lang::translate('Unable to retrieve [%s] list from [%s], status [%d] response [%s]'), + $class, + $url, + $response->httpStatus(), + $response->httpBody() + )); + } + + // Handle empty response + if (strlen($response->httpBody()) == 0) { + return new Collection($parent, $class, array()); + } + + // Parse the return + $object = json_decode($response->httpBody()); + $this->checkJsonError(); + + // See if there's a "next" link + // Note: not sure if the current API offers links as top-level structures; + // might have to refactor to allow $nextPageUrl as method argument + // @codeCoverageIgnoreStart + if (isset($object->links) && is_array($object->links)) { + foreach($object->links as $link) { + if (isset($link->rel) && $link->rel == 'next') { + if (isset($link->href)) { + $nextPageUrl = $link->href; + } else { + $this->getLogger()->warning( + 'Unexpected [links] found with no [href]' + ); + } + } + } + } + // @codeCoverageIgnoreEnd + + // How should we populate the collection? + $data = array(); + + if (!$collectionName) { + // No element name, just a plain object + // @codeCoverageIgnoreStart + $data = $object; + // @codeCoverageIgnoreEnd + } elseif (isset($object->$collectionName)) { + if (!$elementName) { + // The object has a top-level collection name only + $data = $object->$collectionName; + } else { + // The object has element levels which need to be iterated over + $data = array(); + foreach($object->$collectionName as $item) { + $subValues = $item->$elementName; + unset($item->$elementName); + $data[] = array_merge((array)$item, (array)$subValues); + } + } + } + + $collectionObject = new Collection($parent, $class, $data); + + // if there's a $nextPageUrl, then we need to establish a callback + // @codeCoverageIgnoreStart + if (!empty($nextPageUrl)) { + $collectionObject->setNextPageCallback(array($this, 'Collection'), $nextPageUrl); + } + // @codeCoverageIgnoreEnd + + return $collectionObject; + } + + /** + * returns the Region associated with the service + * + * @api + * @return string + */ + public function region() + { + return $this->service_region; + } + + /** + * returns the serviceName associated with the service + * + * This is used by DNS for PTR record lookups + * + * @api + * @return string + */ + public function name() + { + return $this->service_name; + } + + /** + * Returns a list of supported namespaces + * + * @return array + */ + public function namespaces() + { + return (isset($this->_namespaces) && is_array($this->_namespaces)) ? $this->_namespaces : array(); + } + + /** + * Given a service type, name, and region, return the url + * + * This function ensures that services are represented by an entry in the + * service catalog, and NOT by an arbitrarily-constructed URL. + * + * Note that it will always return the first match found in the + * service catalog (there *should* be only one, but you never know...) + * + * @param string $type The OpenStack service type ("compute" or + * "object-store", for example + * @param string $name The name of the service in the service catlog + * @param string $region The region of the service + * @param string $urltype The URL type; defaults to "publicURL" + * @return string The URL of the service + */ + private function getEndpoint($type, $name, $region, $urltype = 'publicURL') + { + $catalog = $this->getConnection()->serviceCatalog(); + + // Search each service to find The One + foreach ($catalog as $service) { + // Find the service by comparing the type ("compute") and name ("openstack") + if (!strcasecmp($service->type, $type) && !strcasecmp($service->name, $name)) { + foreach($service->endpoints as $endpoint) { + // Only set the URL if: + // a. It is a regionless service (i.e. no region key set) + // b. The region matches the one we want + if (isset($endpoint->$urltype) && + (!isset($endpoint->region) || !strcasecmp($endpoint->region, $region)) + ) { + $url = $endpoint->$urltype; + } + } + } + } + + // error if not found + if (empty($url)) { + throw new Exceptions\EndpointError(sprintf( + 'No endpoints for service type [%s], name [%s], region [%s] and urlType [%s]', + $type, + $name, + $region, + $urltype + )); + } + + return $url; + } + + /** + * Constructs a specified URL from the subresource + * + * Given a subresource (e.g., "extensions"), this constructs the proper + * URL and retrieves the resource. + * + * @param string $resource The resource requested; should NOT have slashes + * at the beginning or end + * @return \stdClass object + */ + private function getMetaUrl($resource) + { + $urlBase = $this->getEndpoint( + $this->service_type, + $this->service_name, + $this->service_region, + RAXSDK_URL_PUBLIC + ); + + $url = Lang::noslash($urlBase) . '/' . $resource; + + $response = $this->request($url); + + // check for NOT FOUND response + if ($response->httpStatus() == 404) { + return array(); + } + + // @codeCoverageIgnoreStart + if ($response->httpStatus() >= 300) { + throw new Exceptions\HttpError(sprintf( + Lang::translate('Error accessing [%s] - status [%d], response [%s]'), + $urlBase, + $response->httpStatus(), + $response->httpBody() + )); + } + // @codeCoverageIgnoreEnd + + // we're good; proceed + $object = json_decode($response->httpBody()); + + $this->checkJsonError(); + + return $object; + } + + /** + * Get all associated resources for this service. + * + * @access public + * @return void + */ + public function getResources() + { + return $this->resources; + } + + /** + * Internal method for accessing child namespace from parent scope. + * + * @return type + */ + protected function getCurrentNamespace() + { + $namespace = get_class($this); + return substr($namespace, 0, strrpos($namespace, '\\')); + } + + /** + * Resolves fully-qualified classname for associated local resource. + * + * @param string $resourceName + * @return string + */ + protected function resolveResourceClass($resourceName) + { + $className = substr_count($resourceName, '\\') + ? $resourceName + : $this->getCurrentNamespace() . '\\Resource\\' . ucfirst($resourceName); + + if (!class_exists($className)) { + throw new Exceptions\UnrecognizedServiceError(sprintf( + '%s resource does not exist, please try one of the following: %s', + $resourceName, + implode(', ', $this->getResources()) + )); + } + + return $className; + } + + /** + * Factory method for instantiating resource objects. + * + * @access public + * @param string $resourceName + * @param mixed $info (default: null) + * @return object + */ + public function resource($resourceName, $info = null) + { + $className = $this->resolveResourceClass($resourceName); + return new $className($this, $info); + } + + /** + * Factory method for instantiate a resource collection. + * + * @param string $resourceName + * @param string|null $url + * @return Collection + */ + public function resourceList($resourceName, $url = null, $service = null) + { + $className = $this->resolveResourceClass($resourceName); + return $this->collection($className, $url, $service); + } + +} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/ServiceCatalogItem.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/ServiceCatalogItem.php new file mode 100644 index 00000000000..3e20bcbc7b9 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Common/ServiceCatalogItem.php @@ -0,0 +1,18 @@ +<?php + +namespace OpenCloud\Common; + +/** + * Holds information on a single service from the Service Catalog + */ +class ServiceCatalogItem +{ + + public function __construct($info = array()) + { + foreach($info as $key => $value) { + $this->$key = $value; + } + } + +} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Globals.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Globals.php new file mode 100644 index 00000000000..fbdc4355e02 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Globals.php @@ -0,0 +1,252 @@ +<?php +/** + * Defines global constants and functions + * + * @copyright 2012-2013 Rackspace Hosting, Inc. + * See COPYING for licensing information + * + * @package phpOpenCloud + * @version 1.0 + * @author Glen Campbell <glen.campbell@rackspace.com> + */ + +namespace OpenCloud; + +/** + * This file contains only configuration data such as constants. + * You can override these constants by defining them BEFORE you including + * any of the top-level files from the SDK. + * + * Definitions: + * * RAXSDK_TIMEZONE - the default timezone for interpreting date/time requests + * * RAXSDK_STRICT_PROPERTY_CHECKS - if TRUE, the library will strictly enforce + * property names on objects; only properties that are pre-defined or + * appear in the extensions aliases for the service will be permitted. + * When FALSE (the default), then any property can be set on an object. + * * RAXSDK_COMPUTE_NAME - the default name for the compute service + * * RAXSDK_COMPUTE_REGION - the default region for the compute service + * * RAXSDK_COMPUTE_URLTYPE - the default URL type for the compute service + * * RAXSDK_OBJSTORE_NAME - the default name for the object storage service + * * RAXSDK_OBJSTORE_REGION - the default region for the object storage service + * * RAXSDK_OBJSTORE_URLTYPE - the default URL type for the object storage + * service + * * RAXSDK_DATABASE_NAME - the default name for the DbService service + * * RAXSDK_DATABASE_REGION - the default region for the DbService service + * * RAXSDK_DATABASE_URLTYPE - the default URL type for the DbService service + * * RAXSDK_CONNECTTIMEOUT - the time (in seconds) to wait for a connection + * to a service + * * RAXSDK_TIMEOUT - the max time (in seconds) to wait for an HTTP request + * to complete + * * RAXSDK_SERVER_MAXTIMEOUT - the max time (in seconds) that a server + * will wait for a change in status (Server::WaitFor() method) + * * RAXSDK_POLL_INTERVAL - how often (in seconds) the Server::WaitFor() method + * will poll for a status change + * * RAXSDK_DEFAULT_IP_VERSION - the default IP version (4 or 6) to return for + * the server's primary IP address + * * RAXSDK_OVERLIMIT_TIMEOUT - the max time (in seconds) to wait before + * retrying a request that has failed because of rate limits. If the + * next available time for the request is more than (X) seconds away, + * then the request will fail; otherwise, the request will sleep until + * available. + */ + +if (!defined('RAXSDK_TIMEZONE')) + define('RAXSDK_TIMEZONE', 'America/Chicago'); +if (!defined('RAXSDK_STRICT_PROPERTY_CHECKS')) + define('RAXSDK_STRICT_PROPERTY_CHECKS', FALSE); +if (!defined('RAXSDK_COMPUTE_NAME')) + define('RAXSDK_COMPUTE_NAME', 'cloudServersOpenStack'); +if (!defined('RAXSDK_COMPUTE_REGION')) + define('RAXSDK_COMPUTE_REGION', NULL); +if (!defined('RAXSDK_COMPUTE_URLTYPE')) + define('RAXSDK_COMPUTE_URLTYPE', 'publicURL'); +if (!defined('RAXSDK_MONITORING_NAME')) + define('RAXSDK_MONITORING_NAME', 'cloudMonitoring'); +if (!defined('RAXSDK_MONITORING_REGION')) + define('RAXSDK_MONITORING_REGION', '{ignore}'); +if (!defined('RAXSDK_MONITORING_URLTYPE')) + define('RAXSDK_MONITORING_URLTYPE', 'publicURL'); +if (!defined('RAXSDK_ORCHESTRATION_NAME')) + define('RAXSDK_ORCHESTRATION_NAME', 'cloudOrchestration'); +if (!defined('RAXSDK_ORCHESTRATION_REGION')) + define('RAXSDK_ORCHESTRATION_REGION', NULL); +if (!defined('RAXSDK_ORCHESTRATION_URLTYPE')) + define('RAXSDK_ORCHESTRATION_URLTYPE', 'publicURL'); +if (!defined('RAXSDK_OBJSTORE_NAME')) + define('RAXSDK_OBJSTORE_NAME', 'cloudFiles'); +if (!defined('RAXSDK_OBJSTORE_REGION')) + define('RAXSDK_OBJSTORE_REGION', NULL); +if (!defined('RAXSDK_OBJSTORE_URLTYPE')) + define('RAXSDK_OBJSTORE_URLTYPE', 'publicURL'); +if (!defined('RAXSDK_DATABASE_NAME')) + define('RAXSDK_DATABASE_NAME', 'cloudDatabases'); +if (!defined('RAXSDK_DATABASE_REGION')) + define('RAXSDK_DATABASE_REGION', NULL); +if (!defined('RAXSDK_DATABASE_URLTYPE')) + define('RAXSDK_DATABASE_URLTYPE', 'publicURL'); +if (!defined('RAXSDK_VOLUME_NAME')) + define('RAXSDK_VOLUME_NAME', 'cloudBlockStorage'); +if (!defined('RAXSDK_VOLUME_REGION')) + define('RAXSDK_VOLUME_REGION', NULL); +if (!defined('RAXSDK_VOLUME_URLTYPE')) + define('RAXSDK_VOLUME_URLTYPE', 'publicURL'); +if (!defined('RAXSDK_LBSERVICE_NAME')) + define('RAXSDK_LBSERVICE_NAME', 'cloudLoadBalancers'); +if (!defined('RAXSDK_LBSERVICE_REGION')) + define('RAXSDK_LBSERVICE_REGION', NULL); +if (!defined('RAXSDK_LBSERVICE_URLTYPE')) + define('RAXSDK_LBSERVICE_URLTYPE', 'publicURL'); +if (!defined('RAXSDK_DNS_NAME')) + define('RAXSDK_DNS_NAME', 'cloudDNS'); +if (!defined('RAXSDK_DNS_REGION')) + define('RAXSDK_DNS_REGION', '{ignore}'); // DNS is regionless +if (!defined('RAXSDK_DNS_URLTYPE')) + define('RAXSDK_DNS_URLTYPE', 'publicURL'); +if (!defined('RAXSDK_AUTOSCALE_NAME')) + define('RAXSDK_AUTOSCALE_NAME', 'autoscale'); +if (!defined('RAXSDK_AUTOSCALE_REGION')) + define('RAXSDK_AUTOSCALE_REGION', NULL); +if (!defined('RAXSDK_AUTOSCALE_URLTYPE')) + define('RAXSDK_AUTOSCALE_URLTYPE', 'publicURL'); +if (!defined('RAXSDK_DNS_ASYNC_TIMEOUT')) + define('RAXSDK_DNS_ASYNC_TIMEOUT', 60); +if (!defined('RAXSDK_DNS_ASYNC_INTERVAL')) + define('RAXSDK_DNS_ASYNC_INTERVAL', 1); +if (!defined('RAXSDK_CONNECTTIMEOUT')) + define('RAXSDK_CONNECTTIMEOUT', 5); +if (!defined('RAXSDK_TIMEOUT')) + define('RAXSDK_TIMEOUT', 60); +if (!defined('RAXSDK_SERVER_MAXTIMEOUT')) + define('RAXSDK_SERVER_MAXTIMEOUT', 3600); +if (!defined('RAXSDK_POLL_INTERVAL')) + define('RAXSDK_POLL_INTERVAL', 10); +if (!defined('RAXSDK_DEFAULT_IP_VERSION')) + define('RAXSDK_DEFAULT_IP_VERSION', 4); +if (!defined('RAXSDK_OVERLIMIT_TIMEOUT')) + define('RAXSDK_OVERLIMIT_TIMEOUT', 300); +/** + * sets default (highly secure) value for CURLOPT_SSL_VERIFYHOST. If you + * are using a self-signed SSL certificate, you can reduce this setting, but + * you do so at your own risk. + */ +if (!defined('RAXSDK_SSL_VERIFYHOST')) + define('RAXSDK_SSL_VERIFYHOST', 2); +/** + * sets default (highly secure) value for CURLOPT_SSL_VERIFYPEER. If you + * are using a self-signed SSL certificate, you can reduce this setting, but + * you do so at your own risk. + */ +if (!defined('RAXSDK_SSL_VERIFYPEER')) + define('RAXSDK_SSL_VERIFYPEER', TRUE); + +/** + * edit and uncomment this to set the default location of cacert.pem file + */ +//define('RAXSDK_CACERTPEM', __DIR__ . DIRECTORY_SEPARATOR . 'cacert.pem'); + +/* these should not be overridden */ +define('RAXSDK_VERSION', '1.5.10'); +define('RAXSDK_USER_AGENT', 'php-opencloud/'.RAXSDK_VERSION.' (Rackspace)'); +define('RAXSDK_ERROR', 'Error:'); +define('RAXSDK_FATAL', 'FATAL ERROR:'); +define('RAXSDK_TERMINATED', '*** PROCESSING HALTED ***'); +define('RAXSDK_CONTENT_TYPE_JSON', 'application/json'); +define('RAXSDK_URL_PUBLIC', 'publicURL'); +define('RAXSDK_URL_INTERNAL', 'internalURL'); +define('RAXSDK_URL_VERSION_INFO', 'versionInfo'); +define('RAXSDK_URL_VERSION_LIST', 'versionList'); + +/** + * definitions for Rackspace authentication endpoints + */ +define('RACKSPACE_US', 'https://identity.api.rackspacecloud.com/v2.0/'); +define('RACKSPACE_UK', 'https://lon.identity.api.rackspacecloud.com/v2.0/'); + +/** + * We can re-authenticate this many seconds before the token expires + * + * Set this to a higher value if your service does not cache tokens; if + * it *does* cache them, then this value is not required. + */ +define('RAXSDK_FUDGE', 0); + +/** + * Readable constants + */ +define('RAXSDK_SOFT_REBOOT', 'soft'); +define('RAXSDK_HARD_REBOOT', 'hard'); +define('RAXSDK_DETAILS', TRUE); +define('RAXSDK_MAX_CONTAINER_NAME_LEN', 256); + +/** + * UUID of the Rackspace 'public' network + */ +define('RAX_PUBLIC','00000000-0000-0000-0000-000000000000'); +/** + * UUID of the Rackspace 'private' network + */ +define('RAX_PRIVATE','11111111-1111-1111-1111-111111111111'); + +// Turn off debug mode by default +define('RAXSDK_DEBUG', false); + +/********** TIMEZONE MAGIC **********/ + +/** + * This is called if there is an error getting the default timezone; + * that means that the default timezone isn't set. + * + * @codeCoverageIgnore + */ +function __raxsdk_timezone_set($errno, $errstr) { + if ($errno==2) + date_default_timezone_set(RAXSDK_TIMEZONE); + else + die(sprintf("Unknown error %d: %s\n", $errno, $errstr)); +} +set_error_handler('\OpenCloud\__raxsdk_timezone_set'); +@date_default_timezone_get(); +restore_error_handler(); + +/********** SOME GLOBAL FUNCTIONS **********/ + + /** + * \OpenCloud\Common\Lang::translate() - this function should be used to wrap all static strings. In the future, + * this may provide us with a hook for providing different language + * translations. + * + * @codeCoverageIgnore + */ + function define_gettext() { + function translate($str) { + return $str; + } + } + + if (!function_exists('_')) + define_gettext(); + + /** + * removes trailing slash(es) from a URL string + * + * Mainly, this is just for appearance's sake. I really hate to see + * URLs like .../servers//address, for some reason. + * + * @codeCoverageIgnore + */ + function noslash($str) { + while ($str && (substr($str, -1) == '/')) + $str = substr($str, 0, strlen($str)-1); + return $str; + } + + /** + * Turns debugging on or off + * + * @codeCoverageIgnore + */ + function setDebug($state=TRUE) { + global $RAXSDK_DEBUG; + $RAXSDK_DEBUG=$state; + } + diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/ObjectStore/AbstractService.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/ObjectStore/AbstractService.php new file mode 100644 index 00000000000..4a2298d60ed --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/ObjectStore/AbstractService.php @@ -0,0 +1,57 @@ +<?php +/** + * PHP OpenCloud library. + * + * @copyright Copyright 2013 Rackspace US, Inc. See COPYING for licensing information. + * @license https://www.apache.org/licenses/LICENSE-2.0 Apache 2.0 + * @version 1.6.0 + * @author Glen Campbell <glen.campbell@rackspace.com> + * @author Jamie Hannaford <jamie.hannaford@rackspace.com> + */ + +namespace OpenCloud\ObjectStore; + +use OpenCloud\Common\Service as CommonService; + +define('SWIFT_MAX_OBJECT_SIZE', 5 * 1024 * 1024 * 1024 + 1); + +/** + * An abstract base class for common code shared between ObjectStore\Service + * (container) and ObjectStore\CDNService (CDN containers). + * + * @todo Maybe we use Traits instead of this small abstract class? + */ +abstract class AbstractService extends CommonService +{ + + const MAX_CONTAINER_NAME_LEN = 256; + const MAX_OBJECT_NAME_LEN = 1024; + const MAX_OBJECT_SIZE = SWIFT_MAX_OBJECT_SIZE; + + /** + * Creates a Container resource object. + * + * @param mixed $cdata The name of the container or an object from which to set values + * @return OpenCloud\ObjectStore\Resource\Container + */ + public function container($cdata = null) + { + return new Resource\Container($this, $cdata); + } + + /** + * Returns a Collection of Container objects. + * + * @param array $filter An array to filter the results + * @return OpenCloud\Common\Collection + */ + public function containerList(array $filter = array()) + { + $filter['format'] = 'json'; + + return $this->collection( + 'OpenCloud\ObjectStore\Resource\Container', $this->url(null, $filter) + ); + } + +} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/ObjectStore/CDNService.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/ObjectStore/CDNService.php new file mode 100644 index 00000000000..132d5f47ad6 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/ObjectStore/CDNService.php @@ -0,0 +1,62 @@ +<?php +/** + * PHP OpenCloud library. + * + * @copyright Copyright 2013 Rackspace US, Inc. See COPYING for licensing information. + * @license https://www.apache.org/licenses/LICENSE-2.0 Apache 2.0 + * @version 1.6.0 + * @author Glen Campbell <glen.campbell@rackspace.com> + * @author Jamie Hannaford <jamie.hannaford@rackspace.com> + */ + +namespace OpenCloud\ObjectStore; + +use OpenCloud\OpenStack; +use OpenCloud\Common\Exceptions; + +/** + * This is the CDN version of the ObjectStore service. + */ +class CDNService extends AbstractService +{ + + /** + * Creates a new CDNService object. + * + * This is a simple wrapper function around the parent Service construct, + * but supplies defaults for the service type. + * + * @param OpenCloud\OpenStack $connection The connection object + * @param string $serviceName The name of the service + * @param string $serviceRegion The service's region + * @param string $urlType The type of URL (normally 'publicURL') + */ + public function __construct( + OpenStack $connection, + $serviceName = RAXSDK_OBJSTORE_NAME, + $serviceRegion = RAXSDK_OBJSTORE_REGION, + $urltype = RAXSDK_URL_PUBLIC + ) { + $this->getLogger()->info('Initializing CDN Service...'); + + parent::__construct( + $connection, + 'rax:object-cdn', + $serviceName, + $serviceRegion, + $urltype + ); + } + + /** + * Helps catch errors if someone calls the method on the + * wrong object + */ + public function CDN() + { + throw new Exceptions\CdnError( + 'Invalid method call; no CDN() on the CDN object' + ); + } + +} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/ObjectStore/Resource/AbstractStorageObject.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/ObjectStore/Resource/AbstractStorageObject.php new file mode 100644 index 00000000000..c6799b22b7e --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/ObjectStore/Resource/AbstractStorageObject.php @@ -0,0 +1,170 @@ +<?php +/** + * PHP OpenCloud library. + * + * @copyright Copyright 2013 Rackspace US, Inc. See COPYING for licensing information. + * @license https://www.apache.org/licenses/LICENSE-2.0 Apache 2.0 + * @version 1.6.0 + * @author Glen Campbell <glen.campbell@rackspace.com> + * @author Jamie Hannaford <jamie.hannaford@rackspace.com> + */ + +namespace OpenCloud\ObjectStore\Resource; + +use OpenCloud\Common\Base; +use OpenCloud\Common\Metadata; +use OpenCloud\Common\Exceptions\NameError; +use OpenCloud\Common\Exceptions\MetadataPrefixError; +use OpenCloud\Common\Request\Response\Http; + +/** + * Abstract base class which implements shared functionality of ObjectStore + * resources. Provides support, for example, for metadata-handling and other + * features that are common to the ObjectStore components. + */ +abstract class AbstractStorageObject extends Base +{ + + const ACCOUNT_META_PREFIX = 'X-Account-'; + const CONTAINER_META_PREFIX = 'X-Container-Meta-'; + const OBJECT_META_PREFIX = 'X-Object-Meta-'; + const CDNCONTAINER_META_PREFIX = 'X-Cdn-'; + + /** + * Metadata belonging to a resource. + * + * @var OpenCloud\Common\Metadata + */ + public $metadata; + + /** + * Initializes the metadata component + */ + public function __construct() + { + $this->metadata = new Metadata; + } + + /** + * Given an Http response object, converts the appropriate headers + * to metadata + * + * @param OpenCloud\Common\Request\Response\Http + * @return void + */ + public function getMetadata(Http $response) + { + $this->metadata = new Metadata; + $this->metadata->setArray($response->headers(), $this->prefix()); + } + + /** + * If object has metadata, return an associative array of headers. + * + * For example, if a DataObject has a metadata item named 'FOO', + * then this would return array('X-Object-Meta-FOO'=>$value); + * + * @return array + */ + public function metadataHeaders() + { + $headers = array(); + + // only build if we have metadata + if (is_object($this->metadata)) { + foreach ($this->metadata as $key => $value) { + $headers[$this->prefix() . $key] = $value; + } + } + + return $headers; + } + + /** + * Returns the displayable name of the object + * + * Can be overridden by child objects; *must* be overridden by child + * objects if the object does not have a `name` attribute defined. + * + * @api + * @throws NameError if attribute 'name' is not defined + */ + public function name() + { + if (property_exists($this, 'name')) { + return $this->name; + } else { + throw new NameError(sprintf( + 'Name attribute does not exist for [%s]', + get_class($this) + )); + } + } + + /** + * Override parent method. + * + * @return null + */ + public static function jsonName() + { + return null; + } + + /** + * Override parent method. + * + * @return null + */ + public static function jsonCollectionName() + { + return null; + } + + /** + * Override parent method. + * + * @return null + */ + public static function jsonCollectionElement() + { + return null; + } + + /** + * Returns the proper prefix for the specified type of object + * + * @param string $type The type of object; derived from `get_class()` if not + * specified. + * @codeCoverageIgnore + */ + private function prefix($type = null) + { + if ($type === null) { + $parts = preg_split('/\\\/', get_class($this)); + $type = $parts[count($parts)-1]; + } + + switch($type) { + case 'Account': + $prefix = self::ACCOUNT_META_PREFIX; + break; + case 'CDNContainer': + $prefix = self::CDNCONTAINER_META_PREFIX; + break; + case 'Container': + $prefix = self::CONTAINER_META_PREFIX; + break; + case 'DataObject': + $prefix = self::OBJECT_META_PREFIX; + break; + default: + throw new MetadataPrefixError(sprintf( + 'Unrecognized metadata type [%s]', + $type + )); + } + + return $prefix; + } +} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/ObjectStore/Resource/CDNContainer.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/ObjectStore/Resource/CDNContainer.php new file mode 100644 index 00000000000..9b6367c87e0 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/ObjectStore/Resource/CDNContainer.php @@ -0,0 +1,298 @@ +<?php +/** + * PHP OpenCloud library. + * + * @copyright Copyright 2013 Rackspace US, Inc. See COPYING for licensing information. + * @license https://www.apache.org/licenses/LICENSE-2.0 Apache 2.0 + * @version 1.6.0 + * @author Glen Campbell <glen.campbell@rackspace.com> + * @author Jamie Hannaford <jamie.hannaford@rackspace.com> + */ + +namespace OpenCloud\ObjectStore\Resource; + +use OpenCloud\Common\Service as AbstractService; +use OpenCloud\Common\Lang; +use OpenCloud\Common\Exceptions; +use OpenCloud\ObjectStore\AbstractService as AbstractObjectService; + +/** + * A container that has been CDN-enabled. Each CDN-enabled container has a unique + * Uniform Resource Locator (URL) that can be combined with its object names and + * openly distributed in web pages, emails, or other applications. + */ +class CDNContainer extends AbstractStorageObject +{ + /** + * The name of the container. + * + * The only restrictions on container names is that they cannot contain a + * forward slash (/) and must be less than 256 bytes in length. Please note + * that the length restriction applies to the name after it has been URL + * encoded. For example, a container named Course Docs would be URL encoded + * as Course%20Docs - which is 13 bytes in length rather than the expected 11. + * + * @var string + */ + public $name; + + /** + * Count of how many objects exist in the container. + * + * @var int + */ + public $count = 0; + + /** + * The total bytes used in the container. + * + * @var int + */ + public $bytes = 0; + + /** + * The service object. + * + * @var AbstractService + */ + private $service; + + /** + * URL of the container. + * + * @var string + */ + private $containerUrl; + + /** + * Creates the container object + * + * Creates a new container object or, if the $cdata object is a string, + * retrieves the named container from the object store. If $cdata is an + * array or an object, then its values are used to set this object. + * + * @param OpenCloud\ObjectStore $service - the ObjectStore service + * @param mixed $cdata - if supplied, the name of the object + */ + public function __construct(AbstractService $service, $cdata = null) + { + $this->getLogger()->info('Initializing CDN Container Service...'); + + parent::__construct(); + + $this->service = $service; + + // Populate data if set + $this->populate($cdata); + } + + /** + * Allow other objects to know what the primary key is. + * + * @return string + */ + public function primaryKeyField() + { + return 'name'; + } + + /** + * Returns the Service associated with the Container + */ + public function getService() + { + return $this->service; + } + + /** + * Returns the URL of the container + * + * @return string + * @param string $subresource not used; required for compatibility + * @throws NoNameError + */ + public function url($subresource = '') + { + if (strlen($this->name) == 0) { + throw new Exceptions\NoNameError( + Lang::translate('Container does not have an identifier') + ); + } + + return Lang::noslash($this->getService()->url(rawurlencode($this->name))); + } + + /** + * Creates a new container with the specified attributes + * + * @param array $params array of parameters + * @return boolean TRUE on success; FALSE on failure + * @throws ContainerCreateError + */ + public function create($params = array()) + { + // Populate object and check container name + $this->populate($params); + $this->isValidName($this->name); + + // Dispatch + $this->containerUrl = $this->url(); + $response = $this->getService()->request($this->url(), 'PUT', $this->metadataHeaders()); + + // Check return code + // @codeCoverageIgnoreStart + if ($response->httpStatus() > 202) { + throw new Exceptions\ContainerCreateError(sprintf( + Lang::translate('Problem creating container [%s] status [%d] response [%s]'), + $this->url(), + $response->httpStatus(), + $response->httpBody() + )); + } + // @codeCoverageIgnoreEnd + + return true; + } + + /** + * Updates the metadata for a container + * + * @return boolean TRUE on success; FALSE on failure + * @throws ContainerCreateError + */ + public function update() + { + $response = $this->getService()->request($this->url(), 'POST', $this->metadataHeaders()); + + // check return code + // @codeCoverageIgnoreStart + if ($response->httpStatus() > 204) { + throw new Exceptions\ContainerCreateError(sprintf( + Lang::translate('Problem updating container [%s] status [%d] response [%s]'), + $this->Url(), + $response->httpStatus(), + $response->httpBody() + )); + } + // @codeCoverageIgnoreEnd + + return true; + } + + /** + * Deletes the specified container + * + * @return boolean TRUE on success; FALSE on failure + * @throws ContainerDeleteError + */ + public function delete() + { + $response = $this->getService()->request($this->url(), 'DELETE'); + + // validate the response code + // @codeCoverageIgnoreStart + if ($response->httpStatus() == 404) { + throw new Exceptions\ContainerNotFoundError(sprintf( + Lang::translate('Container [%s] not found'), + $this->name + )); + } + + if ($response->httpStatus() == 409) { + throw new Exceptions\ContainerNotEmptyError(sprintf( + Lang::translate('Container [%s] must be empty before deleting'), + $this->name + )); + } + + if ($response->httpStatus() >= 300) { + throw new Exceptions\ContainerDeleteError(sprintf( + Lang::translate('Problem deleting container [%s] status [%d] response [%s]'), + $this->url(), + $response->httpStatus(), + $response->httpBody() + )); + return false; + } + // @codeCoverageIgnoreEnd + + return true; + } + + /** + * Loads the object from the service + * + * @return void + */ + public function refresh($name = null, $url = null) + { + $response = $this->getService()->request( + $this->url($name), 'HEAD', array('Accept' => '*/*') + ); + + // validate the response code + // @codeCoverageIgnoreStart + if ($response->HttpStatus() == 404) { + throw new Exceptions\ContainerNotFoundError(sprintf( + 'Container [%s] (%s) not found', + $this->name, + $this->url() + )); + } + + if ($response->HttpStatus() >= 300) { + throw new Exceptions\HttpError(sprintf( + 'Error retrieving Container, status [%d] response [%s]', + $response->httpStatus(), + $response->httpBody() + )); + } + + // check for headers (not metadata) + foreach($response->headers() as $header => $value) { + switch($header) { + case 'X-Container-Object-Count': + $this->count = $value; + break; + case 'X-Container-Bytes-Used': + $this->bytes = $value; + break; + } + } + // @codeCoverageIgnoreEnd + + // parse the returned object + $this->getMetadata($response); + } + + /** + * Validates that the container name is acceptable + * + * @param string $name the container name to validate + * @return boolean TRUE if ok; throws an exception if not + * @throws ContainerNameError + */ + public function isValidName($name) + { + if (strlen($name) == 0) { + throw new Exceptions\ContainerNameError( + 'Container name cannot be blank' + ); + } + + if (strpos($name, '/') !== false) { + throw new Exceptions\ContainerNameError( + 'Container name cannot contain "/"' + ); + } + + if (strlen($name) > AbstractObjectService::MAX_CONTAINER_NAME_LEN) { + throw new Exceptions\ContainerNameError( + 'Container name is too long' + ); + } + + return true; + } + +} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/ObjectStore/Resource/Container.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/ObjectStore/Resource/Container.php new file mode 100644 index 00000000000..3a56ebd9fca --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/ObjectStore/Resource/Container.php @@ -0,0 +1,401 @@ +<?php +/** + * PHP OpenCloud library. + * + * @copyright Copyright 2013 Rackspace US, Inc. See COPYING for licensing information. + * @license https://www.apache.org/licenses/LICENSE-2.0 Apache 2.0 + * @version 1.6.0 + * @author Glen Campbell <glen.campbell@rackspace.com> + * @author Jamie Hannaford <jamie.hannaford@rackspace.com> + */ + +namespace OpenCloud\ObjectStore\Resource; + +use OpenCloud\Common\Exceptions; +use OpenCloud\Common\Lang; + +/** + * A container is a storage compartment for your data and provides a way for you + * to organize your data. You can think of a container as a folder in Windows® + * or a directory in UNIX®. The primary difference between a container and these + * other file system concepts is that containers cannot be nested. + * + * A container can also be CDN-enabled (for public access), in which case you + * will need to interact with a CDNContainer object instead of this one. + */ +class Container extends CDNContainer +{ + + /** + * CDN container (if set). + * + * @var CDNContainer|null + */ + private $cdn; + + /** + * Sets the CDN container. + * + * @param OpenCloud\ObjectStore\Resource\CDNContainer $cdn + */ + public function setCDN(CDNContainer $cdn) + { + $this->cdn = $cdn; + } + + /** + * Returns the CDN container. + * + * @returns CDNContainer + */ + public function getCDN() + { + if (!$this->cdn) { + throw new Exceptions\CdnNotAvailableError( + Lang::translate('CDN-enabled container is not available') + ); + } + + return $this->cdn; + } + + /** + * Backwards compatability. + */ + public function CDN() + { + return $this->getCDN(); + } + + /** + * Makes the container public via the CDN + * + * @api + * @param integer $TTL the Time-To-Live for the CDN container; if NULL, + * then the cloud's default value will be used for caching. + * @throws CDNNotAvailableError if CDN services are not available + * @return CDNContainer + */ + public function enableCDN($ttl = null) + { + $url = $this->getService()->CDN()->url() . '/' . rawurlencode($this->name); + + $headers = $this->metadataHeaders(); + + if ($ttl) { + + // Make sure we're dealing with a real figure + if (!is_integer($ttl)) { + throw new Exceptions\CdnTtlError(sprintf( + Lang::translate('TTL value [%s] must be an integer'), + $ttl + )); + } + + $headers['X-TTL'] = $ttl; + } + + $headers['X-Log-Retention'] = 'True'; + $headers['X-CDN-Enabled'] = 'True'; + + // PUT to the CDN container + $response = $this->getService()->request($url, 'PUT', $headers); + + // check the response status + // @codeCoverageIgnoreStart + if ($response->httpStatus() > 202) { + throw new Exceptions\CdnHttpError(sprintf( + Lang::translate('HTTP error publishing to CDN, status [%d] response [%s]'), + $response->httpStatus(), + $response->httpBody() + )); + } + // @codeCoverageIgnoreEnd + + // refresh the data + $this->refresh(); + + // return the CDN container object + $cdn = new CDNContainer($this->getService()->getCDNService(), $this->name); + $this->setCDN($cdn); + + return $cdn; + } + + /** + * Backwards compatability. + */ + public function publishToCDN($ttl = null) + { + return $this->enableCDN($ttl); + } + + /** + * Disables the containers CDN function. + * + * Note that the container will still be available on the CDN until + * its TTL expires. + * + * @api + * @return void + */ + public function disableCDN() + { + // Set necessary headers + $headers['X-Log-Retention'] = 'False'; + $headers['X-CDN-Enabled'] = 'False'; + + // PUT it to the CDN service + $response = $this->getService()->request($this->CDNURL(), 'PUT', $headers); + + // check the response status + // @codeCoverageIgnoreStart + if ($response->httpStatus() != 201) { + throw new Exceptions\CdnHttpError(sprintf( + Lang::translate('HTTP error disabling CDN, status [%d] response [%s]'), + $response->httpStatus(), + $response->httpBody() + )); + } + // @codeCoverageIgnoreEnd + + return true; + } + + /** + * Creates a static website from the container + * + * @api + * @link http://docs.rackspace.com/files/api/v1/cf-devguide/content/Create_Static_Website-dle4000.html + * @param string $index the index page (starting page) of the website + * @return \OpenCloud\HttpResponse + */ + public function createStaticSite($indexHtml) + { + $headers = array('X-Container-Meta-Web-Index' => $indexHtml); + $response = $this->getService()->request($this->url(), 'POST', $headers); + + // check return code + // @codeCoverageIgnoreStart + if ($response->HttpStatus() > 204) { + throw new Exceptions\ContainerError(sprintf( + Lang::translate('Error creating static website for [%s], status [%d] response [%s]'), + $this->name, + $response->httpStatus(), + $response->httpBody() + )); + } + // @codeCoverageIgnoreEnd + + return $response; + } + + /** + * Sets the error page(s) for the static website + * + * @api + * @link http://docs.rackspace.com/files/api/v1/cf-devguide/content/Set_Error_Pages_for_Static_Website-dle4005.html + * @param string $name the name of the error page + * @return \OpenCloud\HttpResponse + */ + public function staticSiteErrorPage($name) + { + $headers = array('X-Container-Meta-Web-Error' => $name); + $response = $this->getService()->request($this->url(), 'POST', $headers); + + // check return code + // @codeCoverageIgnoreStart + if ($response->httpStatus() > 204) { + throw new Exceptions\ContainerError(sprintf( + Lang::translate('Error creating static site error page for [%s], status [%d] response [%s]'), + $this->name, + $response->httpStatus(), + $response->httpBody() + )); + } + + return $response; + // @codeCoverageIgnoreEnd + } + + /** + * Returns the CDN URL of the container (if enabled) + * + * The CDNURL() is used to manage the container. Note that it is different + * from the PublicURL() of the container, which is the publicly-accessible + * URL on the network. + * + * @api + * @return string + */ + public function CDNURL() + { + return $this->getCDN()->url(); + } + + /** + * Returns the Public URL of the container (on the CDN network) + * + */ + public function publicURL() + { + return $this->CDNURI(); + } + + /** + * Returns the CDN info about the container + * + * @api + * @return stdClass + */ + public function CDNinfo($property = null) + { + // Not quite sure why this is here... + // @codeCoverageIgnoreStart + if ($this->getService() instanceof CDNService) { + return $this->metadata; + } + // @codeCoverageIgnoreEnd + + // return NULL if the CDN container is not enabled + if (!isset($this->getCDN()->metadata->Enabled) + || $this->getCDN()->metadata->Enabled == 'False' + ) { + return null; + } + + // check to see if it's set + if (isset($this->getCDN()->metadata->$property)) { + return trim($this->getCDN()->metadata->$property); + } elseif ($property !== null) { + return null; + } + + // otherwise, return the whole metadata object + return $this->getCDN()->metadata; + } + + /** + * Returns the CDN container URI prefix + * + * @api + * @return string + */ + public function CDNURI() + { + return $this->CDNinfo('Uri'); + } + + /** + * Returns the SSL URI for the container + * + * @api + * @return string + */ + public function SSLURI() + { + return $this->CDNinfo('Ssl-Uri'); + } + + /** + * Returns the streaming URI for the container + * + * @api + * @return string + */ + public function streamingURI() + { + return $this->CDNinfo('Streaming-Uri'); + } + + /** + * Returns the IOS streaming URI for the container + * + * @api + * @link http://docs.rackspace.com/files/api/v1/cf-devguide/content/iOS-Streaming-d1f3725.html + * @return string + */ + public function iosStreamingURI() + { + return $this->CDNinfo('Ios-Uri'); + } + + /** + * Creates a Collection of objects in the container + * + * @param array $params associative array of parameter values. + * * account/tenant - The unique identifier of the account/tenant. + * * container- The unique identifier of the container. + * * limit (Optional) - The number limit of results. + * * marker (Optional) - Value of the marker, that the object names + * greater in value than are returned. + * * end_marker (Optional) - Value of the marker, that the object names + * less in value than are returned. + * * prefix (Optional) - Value of the prefix, which the returned object + * names begin with. + * * format (Optional) - Value of the serialized response format, either + * json or xml. + * * delimiter (Optional) - Value of the delimiter, that all the object + * names nested in the container are returned. + * @link http://api.openstack.org for a list of possible parameter + * names and values + * @return OpenCloud\Collection + * @throws ObjFetchError + */ + public function objectList($params = array()) + { + // construct a query string out of the parameters + $params['format'] = 'json'; + + $queryString = $this->makeQueryString($params); + + // append the query string to the URL + $url = $this->url(); + if (strlen($queryString) > 0) { + $url .= '?' . $queryString; + } + + return $this->getService()->collection( + 'OpenCloud\ObjectStore\Resource\DataObject', $url, $this + ); + } + + /** + * Returns a new DataObject associated with this container + * + * @param string $name if supplied, the name of the object to return + * @return DataObject + */ + public function dataObject($name = null) + { + return new DataObject($this, $name); + } + + /** + * Refreshes, then associates the CDN container + */ + public function refresh($id = null, $url = null) + { + parent::refresh($id, $url); + + // @codeCoverageIgnoreStart + if ($this->getService() instanceof CDNService) { + return; + } + + + if (null !== ($cdn = $this->getService()->CDN())) { + try { + $this->cdn = new CDNContainer( + $cdn, + $this->name + ); + } catch (Exceptions\ContainerNotFoundError $e) { + $this->cdn = new CDNContainer($cdn); + $this->cdn->name = $this->name; + } + } + // @codeCoverageIgnoreEnd + } + +} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/ObjectStore/Resource/DataObject.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/ObjectStore/Resource/DataObject.php new file mode 100644 index 00000000000..443df1f651f --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/ObjectStore/Resource/DataObject.php @@ -0,0 +1,941 @@ +<?php +/** + * PHP OpenCloud library. + * + * @copyright Copyright 2013 Rackspace US, Inc. See COPYING for licensing information. + * @license https://www.apache.org/licenses/LICENSE-2.0 Apache 2.0 + * @version 1.6.0 + * @author Glen Campbell <glen.campbell@rackspace.com> + * @author Jamie Hannaford <jamie.hannaford@rackspace.com> + */ + +namespace OpenCloud\ObjectStore\Resource; + +use finfo as FileInfo; +use OpenCloud\Common\Lang; +use OpenCloud\Common\Exceptions; +use OpenCloud\ObjectStore\AbstractService; +use OpenCloud\Common\Request\Response\Http; + +/** + * Objects are the basic storage entities in Cloud Files. They represent the + * files and their optional metadata you upload to the system. When you upload + * objects to Cloud Files, the data is stored as-is (without compression or + * encryption) and consists of a location (container), the object's name, and + * any metadata you assign consisting of key/value pairs. + */ +class DataObject extends AbstractStorageObject +{ + /** + * Object name. The only restriction on object names is that they must be + * less than 1024 bytes in length after URL encoding. + * + * @var string + */ + public $name; + + /** + * Hash value of the object. + * + * @var string + */ + public $hash; + + /** + * Size of object in bytes. + * + * @var string + */ + public $bytes; + + /** + * Date of last modification. + * + * @var string + */ + public $last_modified; + + /** + * Object's content type. + * + * @var string + */ + public $content_type; + + /** + * Object's content length. + * + * @var string + */ + public $content_length; + + /** + * Other headers set for this object (e.g. Access-Control-Allow-Origin) + * + * @var array + */ + public $extra_headers = array(); + + /** + * Whether or not to calculate and send an ETag on create. + * + * @var bool + */ + public $send_etag = true; + + /** + * The data contained by the object. + * + * @var string + */ + private $data; + + /** + * The ETag value. + * + * @var string + */ + private $etag; + + /** + * The parent container of this object. + * + * @var CDNContainer + */ + private $container; + + /** + * Is this data object a pseudo directory? + * + * @var bool + */ + private $directory = false; + + /** + * Used to translate header values (returned by requests) into properties. + * + * @var array + */ + private $headerTranslate = array( + 'Etag' => 'hash', + 'ETag' => 'hash', + 'Last-Modified' => 'last_modified', + 'Content-Length' => array('bytes', 'content_length'), + ); + + /** + * These properties can be freely set by the user for CRUD operations. + * + * @var array + */ + private $allowedProperties = array( + 'name', + 'content_type', + 'extra_headers', + 'send_etag' + ); + + /** + * Option for clearing the status cache when objects are uploaded to API. + * By default, it is set to FALSE for performance; but if you have files + * that are rapidly and very often updated, you might want to clear the status + * cache so PHP reads the files directly, instead of relying on the cache. + * + * @link http://php.net/manual/en/function.clearstatcache.php + * @var bool + */ + public $clearStatusCache = false; + + /** + * A DataObject is related to a container and has a name + * + * If `$name` is specified, then it attempts to retrieve the object from the + * object store. + * + * @param Container $container the container holding this object + * @param mixed $cdata if an object or array, it is treated as values + * with which to populate the object. If it is a string, it is + * treated as a name and the object's info is retrieved from + * the service. + * @return void + */ + public function __construct($container, $cdata = null) + { + parent::__construct(); + + $this->container = $container; + + // For pseudo-directories, we need to ensure the name is set + if (!empty($cdata->subdir)) { + $this->name = $cdata->subdir; + $this->directory = true; + } else { + $this->populate($cdata); + } + } + + /** + * Is this data object a pseudo-directory? + * + * @return bool + */ + public function isDirectory() + { + return $this->directory; + } + + /** + * Allow other objects to know what the primary key is. + * + * @return string + */ + public function primaryKeyField() + { + return 'name'; + } + + /** + * Is this a real file? + * + * @param string $filename + * @return bool + */ + private function isRealFile($filename) + { + return $filename != '/dev/null' && $filename != 'NUL'; + } + + /** + * Set this file's content type. + * + * @param string $contentType + */ + public function setContentType($contentType) + { + $this->content_type = $contentType; + } + + /** + * Return the content type. + * + * @return string + */ + public function getContentType() + { + return $this->content_type; + } + + /** + * Returns the URL of the data object + * + * If the object is new and doesn't have a name, then an exception is + * thrown. + * + * @param string $subresource Not used + * @return string + * @throws NoNameError + */ + public function url($subresource = '') + { + if (!$this->name) { + throw new Exceptions\NoNameError(Lang::translate('Object has no name')); + } + + return Lang::noslash( + $this->container->url()) . '/' . str_replace('%2F', '/', rawurlencode($this->name) + ); + } + + /** + * Creates (or updates; both the same) an instance of the object + * + * @api + * @param array $params an optional associative array that can contain the + * 'name' and 'content_type' of the object + * @param string $filename if provided, then the object is loaded from the + * specified file + * @return boolean + * @throws CreateUpdateError + */ + public function create($params = array(), $filename = null, $extractArchive = null) + { + // Set and validate params + $this->setParams($params); + + // assume no file upload + $fp = false; + + // if the filename is provided, process it + if ($filename) { + + if (!$fp = @fopen($filename, 'r')) { + throw new Exceptions\IOError(sprintf( + Lang::translate('Could not open file [%s] for reading'), + $filename + )); + } + + // @todo Maybe, for performance, we could set the "clear status cache" + // feature to false by default - but allow users to set to true if required + clearstatcache($this->clearStatusCache === true, $filename); + + // Cast filesize as a floating point + $filesize = (float) filesize($filename); + + // Check it's below a reasonable size, and set + // @codeCoverageIgnoreStart + if ($filesize > AbstractService::MAX_OBJECT_SIZE) { + throw new Exceptions\ObjectError("File size exceeds maximum object size."); + } + // @codeCoverageIgnoreEnd + $this->content_length = $filesize; + + // Guess the content type if necessary + if (!$this->getContentType() && $this->isRealFile($filename)) { + $this->setContentType($this->inferContentType($filename)); + } + + // Send ETag checksum if necessary + if ($this->send_etag) { + $this->etag = md5_file($filename); + } + + // Announce to the world + $this->getLogger()->info('Uploading {size} bytes from {name}', array( + 'size' => $filesize, + 'name' => $filename + )); + + } else { + // compute the length + $this->content_length = strlen($this->data); + + if ($this->send_etag) { + $this->etag = md5($this->data); + } + } + + // Only allow supported archive types + // http://docs.rackspace.com/files/api/v1/cf-devguide/content/Extract_Archive-d1e2338.html + $extractArchiveUrlArg = ''; + + if ($extractArchive) { + if ($extractArchive !== "tar.gz" && $extractArchive !== "tar.bz2") { + throw new Exceptions\ObjectError( + "Extract Archive only supports tar.gz and tar.bz2" + ); + } else { + $extractArchiveUrlArg = "?extract-archive=" . $extractArchive; + $this->etag = null; + $this->setContentType(''); + } + } + + // Set headers + $headers = $this->metadataHeaders(); + + if (!empty($this->etag)) { + $headers['ETag'] = $this->etag; + } + + // Content-Type is no longer required; if not specified, it will + // attempt to guess based on the file extension. + if (!$this->getContentType()) { + $headers['Content-Type'] = $this->getContentType(); + } + + $headers['Content-Length'] = $this->content_length; + + // Merge in extra headers + if (!empty($this->extra_headers)) { + $headers = $this->extra_headers + $headers; + } + + // perform the request + $response = $this->getService()->request( + $this->url() . $extractArchiveUrlArg, + 'PUT', + $headers, + $fp ? $fp : $this->data + ); + + // check the status + // @codeCoverageIgnoreStart + if (($status = $response->httpStatus()) >= 300) { + throw new Exceptions\CreateUpdateError(sprintf( + Lang::translate('Problem saving/updating object [%s] HTTP status [%s] response [%s]'), + $this->url() . $extractArchiveUrlArg, + $status, + $response->httpBody() + )); + } + // @codeCoverageIgnoreEnd + + // set values from response + $this->saveResponseHeaders($response); + + // close the file handle + if ($fp) { + fclose($fp); + } + + return $response; + } + + /** + * Update() is provided as an alias for the Create() method + * + * Since update and create both use a PUT request, the different functions + * may allow the developer to distinguish between the semantics in his or + * her application. + * + * @api + * @param array $params an optional associative array that can contain the + * 'name' and 'type' of the object + * @param string $filename if provided, the object is loaded from the file + * @return boolean + */ + public function update($params = array(), $filename = '') + { + return $this->create($params, $filename); + } + + /** + * UpdateMetadata() - updates headers + * + * Updates metadata headers + * + * @api + * @param array $params an optional associative array that can contain the + * 'name' and 'type' of the object + * @return boolean + */ + public function updateMetadata($params = array()) + { + $this->setParams($params); + + // set the headers + $headers = $this->metadataHeaders(); + $headers['Content-Type'] = $this->getContentType(); + + $response = $this->getService()->request( + $this->url(), + 'POST', + $headers + ); + + // check the status + // @codeCoverageIgnoreStart + if (($stat = $response->httpStatus()) >= 204) { + throw new Exceptions\UpdateError(sprintf( + Lang::translate('Problem updating object [%s] HTTP status [%s] response [%s]'), + $this->url(), + $stat, + $response->httpBody() + )); + } + // @codeCoverageIgnoreEnd + + return $response; + } + + /** + * Deletes an object from the Object Store + * + * Note that we can delete without retrieving by specifying the name in the + * parameter array. + * + * @api + * @param array $params an array of parameters + * @return HttpResponse if successful; FALSE if not + * @throws DeleteError + */ + public function delete($params = array()) + { + $this->setParams($params); + + $response = $this->getService()->request($this->url(), 'DELETE'); + + // check the status + // @codeCoverageIgnoreStart + if (($stat = $response->httpStatus()) >= 300) { + throw new Exceptions\DeleteError(sprintf( + Lang::translate('Problem deleting object [%s] HTTP status [%s] response [%s]'), + $this->url(), + $stat, + $response->httpBody() + )); + } + // @codeCoverageIgnoreEnd + + return $response; + } + + /** + * Copies the object to another container/object + * + * Note that this function, because it operates within the Object Store + * itself, is much faster than downloading the object and re-uploading it + * to a new object. + * + * @param DataObject $target the target of the COPY command + */ + public function copy(DataObject $target) + { + $uri = sprintf('/%s/%s', $target->container()->name(), $target->name()); + + $this->getLogger()->info('Copying object to [{uri}]', array('uri' => $uri)); + + $response = $this->getService()->request( + $this->url(), + 'COPY', + array('Destination' => $uri) + ); + + // check response code + // @codeCoverageIgnoreStart + if ($response->httpStatus() > 202) { + throw new Exceptions\ObjectCopyError(sprintf( + Lang::translate('Error copying object [%s], status [%d] response [%s]'), + $this->url(), + $response->httpStatus(), + $response->httpBody() + )); + } + // @codeCoverageIgnoreEnd + + return $response; + } + + /** + * Returns the container of the object + * + * @return Container + */ + public function container() + { + return $this->container; + } + + /** + * returns the TEMP_URL for the object + * + * Some notes: + * * The `$secret` value is arbitrary; it must match the value set for + * the `X-Account-Meta-Temp-URL-Key` on the account level. This can be + * set by calling `$service->SetTempUrlSecret($secret)`. + * * The `$expires` value is the number of seconds you want the temporary + * URL to be valid for. For example, use `60` to make it valid for a + * minute + * * The `$method` must be either GET or PUT. No other methods are + * supported. + * + * @param string $secret the shared secret + * @param integer $expires the expiration time (in seconds) + * @param string $method either GET or PUT + * @return string the temporary URL + */ + public function tempUrl($secret, $expires, $method) + { + $method = strtoupper($method); + $expiry_time = time() + $expires; + + // check for proper method + if ($method != 'GET' && $method != 'PUT') { + throw new Exceptions\TempUrlMethodError(sprintf( + Lang::translate( + 'Bad method [%s] for TempUrl; only GET or PUT supported'), + $method + )); + } + + // construct the URL + $url = $this->url(); + $path = urldecode(parse_url($url, PHP_URL_PATH)); + + $hmac_body = "$method\n$expiry_time\n$path"; + $hash = hash_hmac('sha1', $hmac_body, $secret); + + $this->getLogger()->info('URL [{url}]; SIG [{sig}]; HASH [{hash}]', array( + 'url' => $url, + 'sig' => $hmac_body, + 'hash' => $hash + )); + + $temp_url = sprintf('%s?temp_url_sig=%s&temp_url_expires=%d', $url, $hash, $expiry_time); + + // debug that stuff + $this->getLogger()->info('TempUrl generated [{url}]', array( + 'url' => $temp_url + )); + + return $temp_url; + } + + /** + * Sets object data from string + * + * This is a convenience function to permit the use of other technologies + * for setting an object's content. + * + * @param string $data + * @return void + */ + public function setData($data) + { + $this->data = (string) $data; + } + + /** + * Return object's data as a string + * + * @return string the entire object + */ + public function saveToString() + { + return $this->getService()->request($this->url())->httpBody(); + } + + /** + * Saves the object's data to local filename + * + * Given a local filename, the Object's data will be written to the newly + * created file. + * + * Example: + * <code> + * # ... authentication/connection/container code excluded + * # ... see previous examples + * + * # Whoops! I deleted my local README, let me download/save it + * # + * $my_docs = $conn->get_container("documents"); + * $doc = $my_docs->get_object("README"); + * + * $doc->SaveToFilename("/home/ej/cloudfiles/readme.restored"); + * </code> + * + * @param string $filename name of local file to write data to + * @return boolean <kbd>TRUE</kbd> if successful + * @throws IOException error opening file + * @throws InvalidResponseException unexpected response + */ + public function saveToFilename($filename) + { + if (!$fp = @fopen($filename, "wb")) { + throw new Exceptions\IOError(sprintf( + Lang::translate('Could not open file [%s] for writing'), + $filename + )); + } + + $result = $this->getService()->request($this->url(), 'GET', array(), $fp); + + fclose($fp); + + return $result; + } + + /** + * Saves the object's to a stream filename + * + * Given a local filename, the Object's data will be written to the stream + * + * Example: + * <code> + * # ... authentication/connection/container code excluded + * # ... see previous examples + * + * # If I want to write the README to a temporary memory string I + * # do : + * # + * $my_docs = $conn->get_container("documents"); + * $doc = $my_docs->DataObject(array("name"=>"README")); + * + * $fp = fopen('php://temp', 'r+'); + * $doc->SaveToStream($fp); + * fclose($fp); + * </code> + * + * @param string $filename name of local file to write data to + * @return boolean <kbd>TRUE</kbd> if successful + * @throws IOException error opening file + * @throws InvalidResponseException unexpected response + */ + public function saveToStream($resource) + { + if (!is_resource($resource)) { + throw new Exceptions\ObjectError( + Lang::translate("Resource argument not a valid PHP resource." + )); + } + + return $this->getService()->request($this->url(), 'GET', array(), $resource); + } + + + /** + * Returns the object's MD5 checksum + * + * Accessor method for reading Object's private ETag attribute. + * + * @api + * @return string MD5 checksum hexidecimal string + */ + public function getETag() + { + return $this->etag; + } + + /** + * Purges the object from the CDN + * + * Note that the object will still be served up to the time of its + * TTL value. + * + * @api + * @param string $email An email address that will be notified when + * the object is purged. + * @return void + * @throws CdnError if the container is not CDN-enabled + * @throws CdnHttpError if there is an HTTP error in the transaction + */ + public function purgeCDN($email) + { + // @codeCoverageIgnoreStart + if (!$cdn = $this->Container()->CDNURL()) { + throw new Exceptions\CdnError(Lang::translate('Container is not CDN-enabled')); + } + // @codeCoverageIgnoreEnd + + $url = $cdn . '/' . $this->name; + $headers['X-Purge-Email'] = $email; + $response = $this->getService()->request($url, 'DELETE', $headers); + + // check the status + // @codeCoverageIgnoreStart + if ($response->httpStatus() > 204) { + throw new Exceptions\CdnHttpError(sprintf( + Lang::translate('Error purging object, status [%d] response [%s]'), + $response->httpStatus(), + $response->httpBody() + )); + } + // @codeCoverageIgnoreEnd + + return true; + } + + /** + * Returns the CDN URL (for managing the object) + * + * Note that the DataObject::PublicURL() method is used to return the + * publicly-available URL of the object, while the CDNURL() is used + * to manage the object. + * + * @return string + */ + public function CDNURL() + { + return $this->container()->CDNURL() . '/' . $this->name; + } + + /** + * Returns the object's Public CDN URL, if available + * + * @api + * @param string $type can be 'streaming', 'ssl', 'ios-streaming', + * or anything else for the + * default URL. For example, `$object->PublicURL('ios-streaming')` + * @return string + */ + public function publicURL($type = null) + { + if (!$prefix = $this->container()->CDNURI()) { + return null; + } + + switch(strtoupper($type)) { + case 'SSL': + $url = $this->container()->SSLURI().'/'.$this->name; + break; + case 'STREAMING': + $url = $this->container()->streamingURI().'/'.$this->name; + break; + case 'IOS': + case 'IOS-STREAMING': + $url = $this->container()->iosStreamingURI().'/'.$this->name; + break; + default: + $url = $prefix.'/'.$this->name; + break; + } + + return $url; + } + + /** + * Sets parameters from an array and validates them. + * + * @param array $params Associative array of parameters + * @return void + */ + private function setParams(array $params = array()) + { + // Inspect the user's array for any unapproved keys, and unset if necessary + foreach (array_diff(array_keys($params), $this->allowedProperties) as $key) { + $this->getLogger()->warning('You cannot use the {keyName} key when creating an object', array( + 'keyName' => $key + )); + unset($params[$key]); + } + + $this->populate($params); + } + + /** + * Retrieves a single object, parses headers + * + * @return void + * @throws NoNameError, ObjFetchError + */ + private function fetch() + { + if (!$this->name) { + throw new Exceptions\NoNameError(Lang::translate('Cannot retrieve an unnamed object')); + } + + $response = $this->getService()->request($this->url(), 'HEAD', array('Accept' => '*/*')); + + // check for errors + // @codeCoverageIgnoreStart + if ($response->httpStatus() >= 300) { + throw new Exceptions\ObjFetchError(sprintf( + Lang::translate('Problem retrieving object [%s]'), + $this->url() + )); + } + // @codeCoverageIgnoreEnd + + // set headers as metadata? + $this->saveResponseHeaders($response); + + // parse the metadata + $this->getMetadata($response); + } + + /** + * Extracts the headers from the response, and saves them as object + * attributes. Additional name conversions are done where necessary. + * + * @param Http $response + */ + private function saveResponseHeaders(Http $response, $fillExtraIfNotFound = true) + { + foreach ($response->headers() as $header => $value) { + if (isset($this->headerTranslate[$header])) { + // This header needs to be translated + $property = $this->headerTranslate[$header]; + // Are there multiple properties that need to be set? + if (is_array($property)) { + foreach ($property as $subProperty) { + $this->$subProperty = $value; + } + } else { + $this->$property = $value; + } + } elseif ($fillExtraIfNotFound === true) { + // Otherwise, stock extra headers + $this->extra_headers[$header] = $value; + } + } + } + + /** + * Compatability. + */ + public function refresh() + { + return $this->fetch(); + } + + /** + * Returns the service associated with this object + * + * It's actually the object's container's service, so this method will + * simplify things a bit. + */ + private function getService() + { + return $this->container->getService(); + } + + /** + * Performs an internal check to get the proper MIME type for an object + * + * This function would go over the available PHP methods to get + * the MIME type. + * + * By default it will try to use the PHP fileinfo library which is + * available from PHP 5.3 or as an PECL extension + * (http://pecl.php.net/package/Fileinfo). + * + * It will get the magic file by default from the system wide file + * which is usually available in /usr/share/magic on Unix or try + * to use the file specified in the source directory of the API + * (share directory). + * + * if fileinfo is not available it will try to use the internal + * mime_content_type function. + * + * @param string $handle name of file or buffer to guess the type from + * @return boolean <kbd>TRUE</kbd> if successful + * @throws BadContentTypeException + * @codeCoverageIgnore + */ + private function inferContentType($handle) + { + if ($contentType = $this->getContentType()) { + return $contentType; + } + + $contentType = false; + + $filePath = (is_string($handle)) ? $handle : (string) $handle; + + if (function_exists("finfo_open")) { + + $magicPath = dirname(__FILE__) . "/share/magic"; + $finfo = new FileInfo(FILEINFO_MIME, file_exists($magicPath) ? $magicPath : null); + + if ($finfo) { + + $contentType = is_file($filePath) + ? $finfo->file($handle) + : $finfo->buffer($handle); + + /** + * PHP 5.3 fileinfo display extra information like charset so we + * remove everything after the ; since we are not into that stuff + */ + if (null !== ($extraInfo = strpos($contentType, "; "))) { + $contentType = substr($contentType, 0, $extraInfo); + } + } + + //unset($finfo); + } + + if (!$contentType) { + // Try different native function instead + if (is_file((string) $handle) && function_exists("mime_content_type")) { + $contentType = mime_content_type($handle); + } else { + $this->getLogger()->error('Content-Type cannot be found'); + } + } + + return $contentType; + } + +} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/ObjectStore/Service.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/ObjectStore/Service.php new file mode 100644 index 00000000000..571b33378ac --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/ObjectStore/Service.php @@ -0,0 +1,115 @@ +<?php +/** + * PHP OpenCloud library. + * + * @copyright Copyright 2013 Rackspace US, Inc. See COPYING for licensing information. + * @license https://www.apache.org/licenses/LICENSE-2.0 Apache 2.0 + * @version 1.6.0 + * @author Glen Campbell <glen.campbell@rackspace.com> + * @author Jamie Hannaford <jamie.hannaford@rackspace.com> + */ + +namespace OpenCloud\ObjectStore; + +use OpenCloud\OpenStack; +use OpenCloud\Common\Exceptions; +use OpenCloud\Common\Lang; + +/** + * The ObjectStore (Cloud Files) service. + */ +class Service extends AbstractService +{ + + /** + * This holds the associated CDN service (for Rackspace public cloud) + * or is NULL otherwise. The existence of an object here is + * indicative that the CDN service is available. + */ + private $cdn; + + /** + * Creates a new ObjectStore service object. + * + * @param OpenCloud\OpenStack $connection The connection object + * @param string $serviceName The name of the service + * @param string $serviceRegion The service's region + * @param string $urlType The type of URL (normally 'publicURL') + */ + public function __construct( + OpenStack $connection, + $serviceName = RAXSDK_OBJSTORE_NAME, + $serviceRegion = RAXSDK_OBJSTORE_REGION, + $urltype = RAXSDK_OBJSTORE_URLTYPE + ) { + $this->getLogger()->info('Initializing Container Service...'); + + parent::__construct( + $connection, + 'object-store', + $serviceName, + $serviceRegion, + $urltype + ); + + // establish the CDN container, if available + try { + $this->cdn = new CDNService( + $connection, + $serviceName . 'CDN', + $serviceRegion, + $urltype + ); + } catch (Exceptions\EndpointError $e) { + // If we have an endpoint error, then the CDN functionality is not + // available. In this case, we silently ignore it. + } + } + + /** + * Sets the shared secret value for the TEMP_URL + * + * @param string $secret the shared secret + * @return HttpResponse + */ + public function setTempUrlSecret($secret) + { + $response = $this->request( + $this->url(), + 'POST', + array('X-Account-Meta-Temp-Url-Key' => $secret) + ); + + // @codeCoverageIgnoreStart + if ($response->httpStatus() > 204) { + throw new Exceptions\HttpError(sprintf( + Lang::translate('Error in request, status [%d] for URL [%s] [%s]'), + $response->httpStatus(), + $this->url(), + $response->httpBody() + )); + } + // @codeCoverageIgnoreEnd + + return $response; + } + + /** + * Get the CDN service. + * + * @return null|CDNService + */ + public function getCDNService() + { + return $this->cdn; + } + + /** + * Backwards compability. + */ + public function CDN() + { + return $this->getCDNService(); + } + +} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/OpenStack.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/OpenStack.php new file mode 100644 index 00000000000..c3e645a5406 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/OpenStack.php @@ -0,0 +1,1198 @@ +<?php +/** + * PHP OpenCloud library. + * + * @copyright Copyright 2013 Rackspace US, Inc. See COPYING for licensing information. + * @license https://www.apache.org/licenses/LICENSE-2.0 Apache 2.0 + * @version 1.6.0 + * @author Glen Campbell <glen.campbell@rackspace.com> + * @author Jamie Hannaford <jamie.hannaford@rackspace.com> + */ + +namespace OpenCloud; + +require_once __DIR__ . '/Globals.php'; + +use OpenCloud\Common\Base; +use OpenCloud\Common\Lang; +use OpenCloud\Common\Exceptions; +use OpenCloud\Common\ServiceCatalogItem; + +/** + * The OpenStack class represents a relationship (or "connection") + * between a user and a service. + * + * This is the primary entry point into an OpenStack system, and the only one + * where the developer is required to know and provide the endpoint URL (in + * all other cases, the endpoint is derived from the Service Catalog provided + * by the authentication system). + * + * Since various providers have different mechanisms for authentication, users + * will often use a subclass of OpenStack. For example, the Rackspace + * class is provided for users of Rackspace's cloud services, and other cloud + * providers are welcome to add their own subclasses as well. + * + * General usage example: + * <code> + * $username = 'My Username'; + * $secret = 'My Secret'; + * $connection = new OpenCloud\OpenStack($username, $secret); + * // having established the connection, we can set some defaults + * // this sets the default name and region of the Compute service + * $connection->SetDefaults('Compute', 'cloudServersOpenStack', 'ORD'); + * // access a Compute service + * $chicago = $connection->Compute(); + * // if we want to access a different service, we can: + * $dallas = $connection->Compute('cloudServersOpenStack', 'DFW'); + * </code> + */ +class OpenStack extends Base +{ + + /** + * This holds the HTTP User-Agent: used for all requests to the services. It + * is public so that, if necessary, it can be entirely overridden by the + * developer. However, it's strongly recomended that you use the + * appendUserAgent() method to APPEND your own User Agent identifier to the + * end of this string; the user agent information can be very valuable to + * service providers to track who is using their service. + * + * @var string + */ + public $useragent = RAXSDK_USER_AGENT; + + protected $url; + protected $secret = array(); + protected $token; + protected $expiration = 0; + protected $tenant; + protected $catalog; + protected $connectTimeout = RAXSDK_CONNECTTIMEOUT; + protected $httpTimeout = RAXSDK_TIMEOUT; + protected $overlimitTimeout = RAXSDK_OVERLIMIT_TIMEOUT; + + /** + * This associative array holds default values used to identify each + * service (and to select it from the Service Catalog). Use the + * Compute::SetDefaults() method to change the default values, or + * define the global constants (for example, RAXSDK_COMPUTE_NAME) + * BEFORE loading the OpenCloud library: + * + * <code> + * define('RAXSDK_COMPUTE_NAME', 'cloudServersOpenStack'); + * include('openstack.php'); + * </code> + */ + protected $defaults = array( + 'Compute' => array( + 'name' => RAXSDK_COMPUTE_NAME, + 'region' => RAXSDK_COMPUTE_REGION, + 'urltype' => RAXSDK_COMPUTE_URLTYPE + ), + 'ObjectStore' => array( + 'name' => RAXSDK_OBJSTORE_NAME, + 'region' => RAXSDK_OBJSTORE_REGION, + 'urltype' => RAXSDK_OBJSTORE_URLTYPE + ), + 'Database' => array( + 'name' => RAXSDK_DATABASE_NAME, + 'region' => RAXSDK_DATABASE_REGION, + 'urltype' => RAXSDK_DATABASE_URLTYPE + ), + 'Volume' => array( + 'name' => RAXSDK_VOLUME_NAME, + 'region' => RAXSDK_VOLUME_REGION, + 'urltype' => RAXSDK_VOLUME_URLTYPE + ), + 'LoadBalancer' => array( + 'name' => RAXSDK_LBSERVICE_NAME, + 'region' => RAXSDK_LBSERVICE_REGION, + 'urltype' => RAXSDK_LBSERVICE_URLTYPE + ), + 'DNS' => array( + 'name' => RAXSDK_DNS_NAME, + 'region' => RAXSDK_DNS_REGION, + 'urltype' => RAXSDK_DNS_URLTYPE + ), + 'Orchestration' => array( + 'name' => RAXSDK_ORCHESTRATION_NAME, + 'region' => RAXSDK_ORCHESTRATION_REGION, + 'urltype' => RAXSDK_ORCHESTRATION_URLTYPE + ), + 'CloudMonitoring' => array( + 'name' => RAXSDK_MONITORING_NAME, + 'region' => RAXSDK_MONITORING_REGION, + 'urltype' => RAXSDK_MONITORING_URLTYPE + ), + 'Autoscale' => array( + 'name' => RAXSDK_AUTOSCALE_NAME, + 'region' => RAXSDK_AUTOSCALE_REGION, + 'urltype' => RAXSDK_AUTOSCALE_URLTYPE + ) + ); + + private $_user_write_progress_callback_func; + private $_user_read_progress_callback_func; + + /** + * Tracks file descriptors used by streaming downloads + * + * This will permit multiple simultaneous streaming downloads; the + * key is the URL of the object, and the value is its file descriptor. + * + * To prevent memory overflows, each array element is deleted when + * the end of the file is reached. + */ + private $fileDescriptors = array(); + + /** + * array of options to pass to the CURL request object + */ + private $curlOptions = array(); + + /** + * list of attributes to export/import + */ + private $exportItems = array( + 'token', + 'expiration', + 'tenant', + 'catalog' + ); + + /** + * Creates a new OpenStack object + * + * The OpenStack object needs two bits of information: the URL to + * authenticate against, and a "secret", which is an associative array + * of name/value pairs. Usually, the secret will be a username and a + * password, but other values may be required by different authentication + * systems. For example, OpenStack Keystone requires a username and + * password, but Rackspace uses a username, tenant ID, and API key. + * (See OpenCloud\Rackspace for that.) + * + * @param string $url - the authentication endpoint URL + * @param array $secret - an associative array of auth information: + * * username + * * password + * @param array $options - CURL options to pass to the HttpRequest object + */ + public function __construct($url, array $secret, array $options = array()) + { + // check for supported version + // @codeCoverageIgnoreStart + $version = phpversion(); + if ($version < '5.3.1') { + throw new Exceptions\UnsupportedVersionError(sprintf( + Lang::translate('PHP version [%s] is not supported'), + $version + )); + } + // @codeCoverageIgnoreEnd + + // Start processing + $this->getLogger()->info(Lang::translate('Initializing OpenStack client')); + + // Set properties + $this->setUrl($url); + $this->setSecret($secret); + $this->setCurlOptions($options); + } + + /** + * Set user agent. + * + * @param string $useragent + * @return OpenCloud\OpenStack + */ + public function setUserAgent($useragent) + { + $this->useragent = $useragent; + + return $this; + } + + /** + * Allows the user to append a user agent string + * + * Programs that are using these bindings are encouraged to add their + * user agent to the one supplied by this SDK. This will permit cloud + * providers to track users so that they can provide better service. + * + * @param string $agent an arbitrary user-agent string; e.g. "My Cloud App" + * @return OpenCloud\OpenStack + */ + public function appendUserAgent($useragent) + { + $this->useragent .= ';' . $useragent; + + return $this; + } + + /** + * Get user agent. + * + * @return string + */ + public function getUserAgent() + { + return $this->useragent; + } + + /** + * Sets the URL which the client will access. + * + * @param string $url + * @return OpenCloud\OpenStack + */ + public function setUrl($url) + { + $this->url = $url; + + return $this; + } + + /** + * Get the URL. + * + * @return string + */ + public function getUrl() + { + return $this->url; + } + + /** + * Set the secret for the client. + * + * @param array $secret + * @return OpenCloud\OpenStack + */ + public function setSecret(array $secret = array()) + { + $this->secret = $secret; + + return $this; + } + + /** + * Get the secret. + * + * @return array + */ + public function getSecret() + { + return $this->secret; + } + + /** + * Set the token for this client. + * + * @param string $token + * @return OpenCloud\OpenStack + */ + public function setToken($token) + { + $this->token = $token; + + return $this; + } + + /** + * Get the token for this client. + * + * @return string + */ + public function getToken() + { + return $this->token; + } + + /** + * Set the expiration for this token. + * + * @param int $expiration + * @return OpenCloud\OpenStack + */ + public function setExpiration($expiration) + { + $this->expiration = $expiration; + + return $this; + } + + /** + * Get the expiration time. + * + * @return int + */ + public function getExpiration() + { + return $this->expiration; + } + + /** + * Set the tenant for this client. + * + * @param string $tenant + * @return OpenCloud\OpenStack + */ + public function setTenant($tenant) + { + $this->tenant = $tenant; + + return $this; + } + + /** + * Get the tenant for this client. + * + * @return string + */ + public function getTenant() + { + return $this->tenant; + } + + /** + * Set the service catalog. + * + * @param mixed $catalog + * @return OpenCloud\OpenStack + */ + public function setCatalog($catalog) + { + $this->catalog = $catalog; + + return $this; + } + + /** + * Get the service catalog. + * + * @return array + */ + public function getCatalog() + { + return $this->catalog; + } + + /** + * Set (all) the cURL options. + * + * @param array $options + * @return OpenCloud\OpenStack + */ + public function setCurlOptions(array $options) + { + $this->curlOptions = $options; + + return $this; + } + + /** + * Get the cURL options. + * + * @return array + */ + public function getCurlOptions() + { + return $this->curlOptions; + } + + /** + * Set a specific file descriptor (associated with a URL) + * + * @param string $key + * @param resource $value + * @return OpenCloud\OpenStack + */ + public function setFileDescriptor($key, $value) + { + $this->descriptors[$key] = $value; + + return $this; + } + + /** + * Get a specific file descriptor (associated with a URL) + * + * @param string $key + * @return resource|false + */ + public function getFileDescriptor($key) + { + return (!isset($this->descriptors[$key])) ? false : $this->descriptors[$key]; + } + + /** + * Get the items to be exported. + * + * @return array + */ + public function getExportItems() + { + return $this->exportItems; + } + + /** + * Sets the connect timeout. + * + * @param int $timeout + * @return OpenCloud\OpenStack + */ + public function setConnectTimeout($timeout) + { + $this->connectTimeout = $timeout; + + return $this; + } + + /** + * Get the connect timeout. + * + * @return int + */ + public function getConnectTimeout() + { + return $this->connectTimeout; + } + + /** + * Set the HTTP timeout. + * + * @param int $timeout + * @return OpenCloud\OpenStack + */ + public function setHttpTimeout($timeout) + { + $this->httpTimeout = $timeout; + + return $this; + } + + /** + * Get the HTTP timeout. + * + * @return int + */ + public function getHttpTimeout() + { + return $this->httpTimeout; + } + + /** + * Set the overlimit timeout. + * + * @param int $timeout + * @return OpenCloud\OpenStack + */ + public function setOverlimitTimeout($timeout) + { + $this->overlimitTimeout = $timeout; + + return $this; + } + + /** + * Get the overlimit timeout. + * + * @return int + */ + public function getOverlimitTimeout() + { + return $this->overlimitTimeout; + } + + /** + * Sets default values (an array) for a service. Each array must contain a + * "name", "region" and "urltype" key. + * + * @param string $service + * @param array $value + * @return OpenCloud\OpenStack + */ + public function setDefault($service, array $value = array()) + { + if (isset($value['name']) && isset($value['region']) && isset($value['urltype'])) { + $this->defaults[$service] = $value; + } + + return $this; + } + + /** + * Get a specific default value for a service. If none exist, return FALSE. + * + * @param string $service + * @return array|false + */ + public function getDefault($service) + { + return (!isset($this->defaults[$service])) ? false : $this->defaults[$service]; + } + +/** + * Sets the timeouts for the current connection + * + * @api + * @param integer $t_http the HTTP timeout value (the max period that + * the OpenStack object will wait for any HTTP request to complete). + * Value is in seconds. + * @param integer $t_conn the Connect timeout value (the max period + * that the OpenStack object will wait to establish an HTTP + * connection). Value is in seconds. + * @param integer $t_overlimit the overlimit timeout value (the max period + * that the OpenStack object will wait to retry on an overlimit + * condition). Value is in seconds. + * @return void + */ + public function setTimeouts($httpTimeout, $connectTimeout = null, $overlimitTimeout = null) + { + $this->setHttpTimeout($httpTimeout); + + if (isset($connectTimeout)) { + $this->setConnectTimeout($connectTimeout); + } + + if (isset($overlimitTimeout)) { + $this->setOverlimitTimeout($overlimitTimeout); + } + } + + /** + * Returns the URL of this object + * + * @api + * @param string $subresource specified subresource + * @return string + */ + public function url($subresource='tokens') + { + return Lang::noslash($this->url) . '/' . $subresource; + } + + /** + * Returns the stored secret + * + * @return array + */ + public function secret() + { + return $this->getSecret(); + } + + /** + * Re-authenticates session if expired. + */ + public function checkExpiration() + { + if ($this->hasExpired()) { + $this->authenticate(); + } + } + + /** + * Checks whether token has expired. + * + * @return bool + */ + public function hasExpired() + { + return time() > ($this->getExpiration() - RAXSDK_FUDGE); + } + + /** + * Returns the cached token; if it has expired, then it re-authenticates + * + * @api + * @return string + */ + public function token() + { + $this->checkExpiration(); + + return $this->getToken(); + } + + /** + * Returns the cached expiration time; + * if it has expired, then it re-authenticates + * + * @api + * @return string + */ + public function expiration() + { + $this->checkExpiration(); + + return $this->getExpiration(); + } + + /** + * Returns the tenant ID, re-authenticating if necessary + * + * @api + * @return string + */ + public function tenant() + { + $this->checkExpiration(); + + return $this->getTenant(); + } + + /** + * Returns the service catalog object from the auth service + * + * @return \stdClass + */ + public function serviceCatalog() + { + $this->checkExpiration(); + + return $this->getCatalog(); + } + + /** + * Returns a Collection of objects with information on services + * + * Note that these are informational (read-only) and are not actually + * 'Service'-class objects. + */ + public function serviceList() + { + return new Common\Collection($this, 'ServiceCatalogItem', $this->serviceCatalog()); + } + + /** + * Creates and returns the formatted credentials to POST to the auth + * service. + * + * @return string + */ + public function credentials() + { + if (isset($this->secret['username']) && isset($this->secret['password'])) { + + $credentials = array( + 'auth' => array( + 'passwordCredentials' => array( + 'username' => $this->secret['username'], + 'password' => $this->secret['password'] + ) + ) + ); + + if (isset($this->secret['tenantName'])) { + $credentials['auth']['tenantName'] = $this->secret['tenantName']; + } + + return json_encode($credentials); + + } else { + throw new Exceptions\CredentialError( + Lang::translate('Unrecognized credential secret') + ); + } + } + + /** + * Authenticates using the supplied credentials + * + * @api + * @return void + * @throws AuthenticationError + */ + public function authenticate() + { + // try to auth + $response = $this->request( + $this->url(), + 'POST', + array('Content-Type'=>'application/json'), + $this->credentials() + ); + + $json = $response->httpBody(); + + // check for errors + if ($response->HttpStatus() >= 400) { + throw new Exceptions\AuthenticationError(sprintf( + Lang::translate('Authentication failure, status [%d], response [%s]'), + $response->httpStatus(), + $json + )); + } + + // Decode and check + $object = json_decode($json); + $this->checkJsonError(); + + // Save the token information as well as the ServiceCatalog + $this->setToken($object->access->token->id); + $this->setExpiration(strtotime($object->access->token->expires)); + $this->setCatalog($object->access->serviceCatalog); + + /** + * In some cases, the tenant name/id is not returned + * as part of the auth token, so we check for it before + * we set it. This occurs with pure Keystone, but not + * with the Rackspace auth. + */ + if (isset($object->access->token->tenant)) { + $this->setTenant($object->access->token->tenant->id); + } + } + + /** + * Performs a single HTTP request + * + * The request() method is one of the most frequently-used in the entire + * library. It performs an HTTP request using the specified URL, method, + * and with the supplied headers and body. It handles error and + * exceptions for the request. + * + * @api + * @param string url - the URL of the request + * @param string method - the HTTP method (defaults to GET) + * @param array headers - an associative array of headers + * @param string data - either a string or a resource (file pointer) to + * use as the request body (for PUT or POST) + * @return HttpResponse object + * @throws HttpOverLimitError, HttpUnauthorizedError, HttpForbiddenError + */ + public function request($url, $method = 'GET', $headers = array(), $data = null) + { + $this->getLogger()->info('Resource [{url}] method [{method}] body [{body}]', array( + 'url' => $url, + 'method' => $method, + 'data' => $data + )); + + // get the request object + $http = $this->getHttpRequestObject($url, $method, $this->getCurlOptions()); + + // set various options + $this->getLogger()->info('Headers: [{headers}]', array( + 'headers' => print_r($headers, true) + )); + + $http->setheaders($headers); + $http->setHttpTimeout($this->getHttpTimeout()); + $http->setConnectTimeout($this->getConnectTimeout()); + $http->setOption(CURLOPT_USERAGENT, $this->getUserAgent()); + + // data can be either a resource or a string + if (is_resource($data)) { + // loading from or writing to a file + // set the appropriate callback functions + switch($method) { + // @codeCoverageIgnoreStart + case 'GET': + // need to save the file descriptor + $this->setFileDescriptor($url, $data); + // set the CURL options + $http->setOption(CURLOPT_FILE, $data); + $http->setOption(CURLOPT_WRITEFUNCTION, array($this, '_write_cb')); + break; + // @codeCoverageIgnoreEnd + case 'PUT': + case 'POST': + // need to save the file descriptor + $this->setFileDescriptor($url, $data); + if (!isset($headers['Content-Length'])) { + throw new Exceptions\HttpError( + Lang::translate('The Content-Length: header must be specified for file uploads') + ); + } + $http->setOption(CURLOPT_UPLOAD, TRUE); + $http->setOption(CURLOPT_INFILE, $data); + $http->setOption(CURLOPT_INFILESIZE, $headers['Content-Length']); + $http->setOption(CURLOPT_READFUNCTION, array($this, '_read_cb')); + break; + default: + // do nothing + break; + } + } elseif (is_string($data)) { + $http->setOption(CURLOPT_POSTFIELDS, $data); + } elseif (isset($data)) { + throw new Exceptions\HttpError( + Lang::translate('Unrecognized data type for PUT/POST body, must be string or resource') + ); + } + + // perform the HTTP request; returns an HttpResult object + $response = $http->execute(); + + // handle and retry on overlimit errors + if ($response->httpStatus() == 413) { + + $object = json_decode($response->httpBody()); + $this->checkJsonError(); + + // @codeCoverageIgnoreStart + if (isset($object->overLimit)) { + /** + * @TODO(glen) - The documentation says "retryAt", but + * the field returned is "retryAfter". If the doc changes, + * then there's no problem, but we'll need to fix this if + * they change the code to match the docs. + */ + $retryAfter = $object->overLimit->retryAfter; + $sleepInterval = strtotime($retryAfter) - time(); + + if ($sleepInterval && $sleepInterval <= $this->getOverlimitTimeout()) { + sleep($sleepInterval); + $response = $http->Execute(); + } else { + throw new Exceptions\HttpOverLimitError(sprintf( + Lang::translate('Over limit; next available request [%s][%s] is not for [%d] seconds at [%s]'), + $method, + $url, + $sleepInterval, + $retryAfter + )); + } + } + // @codeCoverageIgnoreEnd + } + + // do some common error checking + switch ($response->httpStatus()) { + case 401: + throw new Exceptions\HttpUnauthorizedError(sprintf( + Lang::translate('401 Unauthorized for [%s] [%s]'), + $url, + $response->HttpBody() + )); + break; + case 403: + throw new Exceptions\HttpForbiddenError(sprintf( + Lang::translate('403 Forbidden for [%s] [%s]'), + $url, + $response->HttpBody() + )); + break; + case 413: // limit + throw new Exceptions\HttpOverLimitError(sprintf( + Lang::translate('413 Over limit for [%s] [%s]'), + $url, + $response->HttpBody() + )); + break; + default: + // everything is fine here, we're fine, how are you? + break; + } + + // free the handle + $http->close(); + + // return the HttpResponse object + $this->getLogger()->info('HTTP STATUS [{code}]', array( + 'code' => $response->httpStatus() + )); + + return $response; + } + + /** + * Sets default values for name, region, URL type for a service + * + * Once these are set (and they can also be set by defining global + * constants), then you do not need to specify these values when + * creating new service objects. + * + * @api + * @param string $service the name of a supported service; e.g. 'Compute' + * @param string $name the service name; e.g., 'cloudServersOpenStack' + * @param string $region the region name; e.g., 'LON' + * @param string $urltype the type of URL to use; e.g., 'internalURL' + * @return void + * @throws UnrecognizedServiceError + */ + public function setDefaults( + $service, + $name = null, + $region = null, + $urltype = null + ) { + + if (!isset($this->defaults[$service])) { + throw new Exceptions\UnrecognizedServiceError(sprintf( + Lang::translate('Service [%s] is not recognized'), $service + )); + } + + if (isset($name)) { + $this->defaults[$service]['name'] = $name; + } + + if (isset($region)) { + $this->defaults[$service]['region'] = $region; + } + + if (isset($urltype)) { + $this->defaults[$service]['urltype'] = $urltype; + } + } + + /** + * Allows the user to define a function for tracking uploads + * + * This can be used to implement a progress bar or similar function. The + * callback function is called with a single parameter, the length of the + * data that is being uploaded on this call. + * + * @param callable $callback the name of a global callback function, or an + * array($object, $functionname) + * @return void + */ + public function setUploadProgressCallback($callback) + { + $this->_user_write_progress_callback_func = $callback; + } + + /** + * Allows the user to define a function for tracking downloads + * + * This can be used to implement a progress bar or similar function. The + * callback function is called with a single parameter, the length of the + * data that is being downloaded on this call. + * + * @param callable $callback the name of a global callback function, or an + * array($object, $functionname) + * @return void + */ + public function setDownloadProgressCallback($callback) + { + $this->_user_read_progress_callback_func = $callback; + } + + /** + * Callback function to handle reads for file uploads + * + * Internal function for handling file uploads. Note that, although this + * function's visibility is public, this is only because it must be called + * from the HttpRequest interface. This should NOT be called by users + * directly. + * + * @param resource $ch a CURL handle + * @param resource $fd a file descriptor + * @param integer $length the amount of data to read + * @return string the data read + * @codeCoverageIgnore + */ + public function _read_cb($ch, $fd, $length) + { + $data = fread($fd, $length); + $len = strlen($data); + if (isset($this->_user_write_progress_callback_func)) { + call_user_func($this->_user_write_progress_callback_func, $len); + } + return $data; + } + + /** + * Callback function to handle writes for file downloads + * + * Internal function for handling file downloads. Note that, although this + * function's visibility is public, this is only because it must be called + * via the HttpRequest interface. This should NOT be called by users + * directly. + * + * @param resource $ch a CURL handle + * @param string $data the data to be written to a file + * @return integer the number of bytes written + * @codeCoverageIgnore + */ + public function _write_cb($ch, $data) + { + $url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); + + if (false === ($fp = $this->getFileDescriptor($url))) { + throw new Exceptions\HttpUrlError(sprintf( + Lang::translate('Cannot find file descriptor for URL [%s]'), $url) + ); + } + + $dlen = strlen($data); + fwrite($fp, $data, $dlen); + + // call used callback function + if (isset($this->_user_read_progress_callback_func)) { + call_user_func($this->_user_read_progress_callback_func, $dlen); + } + + // MUST return the length to CURL + return $dlen; + } + + /** + * exports saved token, expiration, tenant, and service catalog as an array + * + * This could be stored in a cache (APC or disk file) and reloaded using + * ImportCredentials() + * + * @return array + */ + public function exportCredentials() + { + $this->authenticate(); + + $array = array(); + + foreach ($this->getExportItems() as $key) { + $array[$key] = $this->$key; + } + + return $array; + } + + /** + * imports credentials from an array + * + * Takes the same values as ExportCredentials() and reuses them. + * + * @return void + */ + public function importCredentials(array $values) + { + foreach ($this->getExportItems() as $item) { + $this->$item = $values[$item]; + } + } + + /********** FACTORY METHODS ********** + * + * These methods are provided to permit easy creation of services + * (for example, Nova or Swift) from a connection object. As new + * services are supported, factory methods should be provided here. + */ + + /** + * Creates a new ObjectStore object (Swift/Cloud Files) + * + * @api + * @param string $name the name of the Object Storage service to attach to + * @param string $region the name of the region to use + * @param string $urltype the URL type (normally "publicURL") + * @return ObjectStore + */ + public function objectStore($name = null, $region = null, $urltype = null) + { + return $this->service('ObjectStore', $name, $region, $urltype); + } + + /** + * Creates a new Compute object (Nova/Cloud Servers) + * + * @api + * @param string $name the name of the Compute service to attach to + * @param string $region the name of the region to use + * @param string $urltype the URL type (normally "publicURL") + * @return Compute + */ + public function compute($name = null, $region = null, $urltype = null) + { + return $this->service('Compute', $name, $region, $urltype); + } + + /** + * Creates a new Orchestration (heat) service object + * + * @api + * @param string $name the name of the Compute service to attach to + * @param string $region the name of the region to use + * @param string $urltype the URL type (normally "publicURL") + * @return Orchestration\Service + * @codeCoverageIgnore + */ + public function orchestration($name = null, $region = null, $urltype = null) + { + return $this->service('Orchestration', $name, $region, $urltype); + } + + /** + * Creates a new VolumeService (cinder) service object + * + * This is a factory method that is Rackspace-only (NOT part of OpenStack). + * + * @param string $name the name of the service (e.g., 'cloudBlockStorage') + * @param string $region the region (e.g., 'DFW') + * @param string $urltype the type of URL (e.g., 'publicURL'); + */ + public function volumeService($name = null, $region = null, $urltype = null) + { + return $this->service('Volume', $name, $region, $urltype); + } + + /** + * Generic Service factory method + * + * Contains code reused by the other service factory methods. + * + * @param string $class the name of the Service class to produce + * @param string $name the name of the Compute service to attach to + * @param string $region the name of the region to use + * @param string $urltype the URL type (normally "publicURL") + * @return Service (or subclass such as Compute, ObjectStore) + * @throws ServiceValueError + */ + public function service($class, $name = null, $region = null, $urltype = null) + { + // debug message + $this->getLogger()->info('Factory for class [{class}] [{name}/{region}/{urlType}]', array( + 'class' => $class, + 'name' => $name, + 'region' => $region, + 'urlType' => $urltype + )); + + // Strips off base namespace + $class = preg_replace('#\\\?OpenCloud\\\#', '', $class); + + // check for defaults + $default = $this->getDefault($class); + + // report errors + if (!$name = $name ?: $default['name']) { + throw new Exceptions\ServiceValueError(sprintf( + Lang::translate('No value for %s name'), + $class + )); + } + + if (!$region = $region ?: $default['region']) { + throw new Exceptions\ServiceValueError(sprintf( + Lang::translate('No value for %s region'), + $class + )); + } + + if (!$urltype = $urltype ?: $default['urltype']) { + throw new Exceptions\ServiceValueError(sprintf( + Lang::translate('No value for %s URL type'), + $class + )); + } + + // return the object + $fullclass = 'OpenCloud\\' . $class . '\\Service'; + + return new $fullclass($this, $name, $region, $urltype); + } + + /** + * returns a service catalog item + * + * This is a helper function used to list service catalog items easily + */ + public function serviceCatalogItem($info = array()) + { + return new ServiceCatalogItem($info); + } + +} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Rackspace.php b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Rackspace.php new file mode 100644 index 00000000000..41be608b347 --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/OpenCloud/Rackspace.php @@ -0,0 +1,132 @@ +<?php +/** + * The Rackspace cloud/connection class (which uses different authentication + * than the pure OpenStack class) + * + * @copyright 2012-2013 Rackspace Hosting, Inc. + * See COPYING for licensing information + * + * @package phpOpenCloud + * @version 1.0 + * @author Glen Campbell <glen.campbell@rackspace.com> + */ + +namespace OpenCloud; + +/** + * Rackspace extends the OpenStack class with support for Rackspace's + * API key and tenant requirements. + * + * The only difference between Rackspace and OpenStack is that the + * Rackspace class generates credentials using the username + * and API key, as required by the Rackspace authentication + * service. + * + * Example: + * <code> + * $username = 'FRED'; + * $apiKey = '0900af093093788912388fc09dde090ffee09'; + * $conn = new Rackspace( + * 'https://identity.api.rackspacecloud.com/v2.0/', + * array( + * 'username' => $username, + * 'apiKey' => $apiKey + * )); + * </code> + */ +class Rackspace extends OpenStack +{ + + //this is the JSON string for our new credentials +const APIKEYTEMPLATE = <<<ENDCRED +{ "auth": { "RAX-KSKEY:apiKeyCredentials": { "username": "%s", + "apiKey": "%s" + } + } +} +ENDCRED; + + /** + * Generates Rackspace API key credentials + * + * @return string + */ + public function Credentials() + { + $sec = $this->Secret(); + if (isset($sec['username']) + && isset($sec['apiKey']) + ) { + return sprintf( + self::APIKEYTEMPLATE, + $sec['username'], + $sec['apiKey'] + ); + } else { + return parent::Credentials(); + } + } + + /** + * Creates a new DbService (Database as a Service) object + * + * This is a factory method that is Rackspace-only (NOT part of OpenStack). + * + * @param string $name the name of the service (e.g., 'Cloud Databases') + * @param string $region the region (e.g., 'DFW') + * @param string $urltype the type of URL (e.g., 'publicURL'); + */ + public function DbService($name = null, $region = null, $urltype = null) + { + return $this->Service('Database', $name, $region, $urltype); + } + + /** + * Creates a new LoadBalancerService object + * + * This is a factory method that is Rackspace-only (NOT part of OpenStack). + * + * @param string $name the name of the service + * (e.g., 'Cloud Load Balancers') + * @param string $region the region (e.g., 'DFW') + * @param string $urltype the type of URL (e.g., 'publicURL'); + */ + public function LoadBalancerService($name = null, $region = null, $urltype = null) + { + return $this->Service('LoadBalancer', $name, $region, $urltype); + } + + /** + * creates a new DNS service object + * + * This is a factory method that is currently Rackspace-only + * (not available via the OpenStack class) + */ + public function DNS($name = null, $region = null, $urltype = null) + { + return $this->Service('DNS', $name, $region, $urltype); + } + + /** + * creates a new CloudMonitoring service object + * + * This is a factory method that is currently Rackspace-only + * (not available via the OpenStack class) + */ + public function CloudMonitoring($name=null, $region=null, $urltype=null) + { + return $this->Service('CloudMonitoring', $name, $region, $urltype); + } + + /** + * creates a new Autoscale service object + * + * This is a factory method that is currently Rackspace-only + * (not available via the OpenStack class) + */ + public function Autoscale($name=null, $region=null, $urltype=null) + { + return $this->Service('Autoscale', $name, $region, $urltype); + } + +} diff --git a/apps/files_external/3rdparty/php-opencloud/lib/openstack.php b/apps/files_external/3rdparty/php-opencloud/lib/openstack.php new file mode 100644 index 00000000000..738902d244e --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/openstack.php @@ -0,0 +1,8 @@ +<?php +/** + * provided for backwards compatibility + * + * @copyright 2013 Rackspace Hosting, Inc. + * @license http://www.apache.org/licenses/LICENSE-2.0 + */ +require_once __DIR__.'/php-opencloud.php'; diff --git a/apps/files_external/3rdparty/php-opencloud/lib/php-opencloud.php b/apps/files_external/3rdparty/php-opencloud/lib/php-opencloud.php new file mode 100644 index 00000000000..15ff034b92d --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/php-opencloud.php @@ -0,0 +1,15 @@ +<?php +/** + * entry point for PHP-OpenCloud library + * + * @copyright 2013 Rackspace Hosting, Inc. + * @license http://www.apache.org/licenses/LICENSE-2.0 + */ +require_once(__DIR__ . '/Autoload.php'); +require_once(__DIR__ . '/OpenCloud/Globals.php'); + +$classLoader = new ClassLoader; +$classLoader->registerNamespaces(array( + 'OpenCloud' => array(__DIR__, __DIR__ . '/../tests') +)); +$classLoader->register();
\ No newline at end of file diff --git a/apps/files_external/3rdparty/php-opencloud/lib/rackspace.php b/apps/files_external/3rdparty/php-opencloud/lib/rackspace.php new file mode 100644 index 00000000000..738902d244e --- /dev/null +++ b/apps/files_external/3rdparty/php-opencloud/lib/rackspace.php @@ -0,0 +1,8 @@ +<?php +/** + * provided for backwards compatibility + * + * @copyright 2013 Rackspace Hosting, Inc. + * @license http://www.apache.org/licenses/LICENSE-2.0 + */ +require_once __DIR__.'/php-opencloud.php'; diff --git a/apps/files_external/3rdparty/smb4php/smb.php b/apps/files_external/3rdparty/smb4php/smb.php index e7d1dfa09fe..622942b052a 100644 --- a/apps/files_external/3rdparty/smb4php/smb.php +++ b/apps/files_external/3rdparty/smb4php/smb.php @@ -19,6 +19,10 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # +# Addition 17/12/2012 Frank Karlitschek (frank@owncloud.org) +# On the official website http://www.phpclasses.org/smb4php the +# license is listed as LGPL so we assume that this is +# dual-licensed GPL/LGPL ################################################################### define ('SMB4PHP_VERSION', '0.8'); @@ -126,7 +130,8 @@ class smb { // this put env is necessary to read the output of smbclient correctly $old_locale = getenv('LC_ALL'); putenv('LC_ALL=en_US.UTF-8'); - $output = popen (SMB4PHP_SMBCLIENT." -N {$auth} {$options} {$port} {$options} {$params} 2>/dev/null", 'r'); + $output = popen ('TZ=UTC '.SMB4PHP_SMBCLIENT." -N {$auth} {$options} {$port} {$options} {$params} 2>/dev/null", 'r'); + $gotInfo = false; $info = array (); $info['info']= array (); $mode = ''; @@ -159,7 +164,7 @@ class smb { $i = ($mode == 'servers') ? array ($name, "server") : array ($name, "workgroup", $master); break; case 'files': - list ($attr, $name) = preg_match ("/^(.*)[ ]+([D|A|H|S|R]+)$/", trim ($regs[1]), $regs2) + list ($attr, $name) = preg_match ("/^(.*)[ ]+([D|A|H|N|S|R]+)$/", trim ($regs[1]), $regs2) ? array (trim ($regs2[2]), trim ($regs2[1])) : array ('', trim ($regs[1])); list ($his, $im) = array ( @@ -181,12 +186,19 @@ class smb { return false; }elseif(substr($regs[0],0,31)=='NT_STATUS_OBJECT_PATH_NOT_FOUND'){ return false; + }elseif(substr($regs[0],0,31)=='NT_STATUS_OBJECT_NAME_NOT_FOUND'){ + return false; }elseif(substr($regs[0],0,29)=='NT_STATUS_FILE_IS_A_DIRECTORY'){ return false; } trigger_error($regs[0].' params('.$params.')', E_USER_ERROR); case 'error-connect': - return false; + // connection error can happen after obtaining share list if + // NetBIOS is disabled/blocked on the target server, + // in which case we keep the info and continue + if (!$gotInfo) { + return false; + } } if ($i) switch ($i[1]) { case 'file': @@ -194,6 +206,7 @@ class smb { case 'disk': case 'server': case 'workgroup': $info[$i[1]][] = $i[0]; + $gotInfo = true; } } pclose($output); @@ -293,6 +306,7 @@ class smb { } function rename ($url_from, $url_to) { + $replace = false; list ($from, $to) = array (smb::parse_url($url_from), smb::parse_url($url_to)); if ($from['host'] <> $to['host'] || $from['share'] <> $to['share'] || @@ -305,7 +319,21 @@ class smb { trigger_error('rename(): error in URL', E_USER_ERROR); } smb::clearstatcache ($url_from); - return smb::execute ('rename "'.$from['path'].'" "'.$to['path'].'"', $to); + $cmd = ''; + // check if target file exists + if (smb::url_stat($url_to)) { + // delete target file first + $cmd = 'del "' . $to['path'] . '"; '; + $replace = true; + } + $cmd .= 'rename "' . $from['path'] . '" "' . $to['path'] . '"'; + $result = smb::execute($cmd, $to); + if ($replace) { + // clear again, else the cache will return the info + // from the old file + smb::clearstatcache ($url_to); + } + return $result !== false; } function mkdir ($url, $mode, $options) { @@ -430,7 +458,10 @@ class smb_stream_wrapper extends smb { case 'rb': case 'a': case 'a+': $this->tmpfile = tempnam('/tmp', 'smb.down.'); - smb::execute ('get "'.$pu['path'].'" "'.$this->tmpfile.'"', $pu); + $result = smb::execute ('get "'.$pu['path'].'" "'.$this->tmpfile.'"', $pu); + if($result === false){ + return $result; + } break; case 'w': case 'w+': @@ -454,7 +485,8 @@ class smb_stream_wrapper extends smb { function stream_tell () { return ftell($this->stream); } - function stream_seek ($offset, $whence=null) { return fseek($this->stream, $offset, $whence); } + // PATCH: the wrapper must return true when fseek succeeded by returning 0. + function stream_seek ($offset, $whence=null) { return fseek($this->stream, $offset, $whence) === 0; } function stream_flush () { if ($this->mode <> 'r' && $this->need_flush) { diff --git a/apps/files_external/ajax/dropbox.php b/apps/files_external/ajax/dropbox.php index bc9821c62ec..91c465500d0 100644 --- a/apps/files_external/ajax/dropbox.php +++ b/apps/files_external/ajax/dropbox.php @@ -1,6 +1,6 @@ <?php -require_once 'Dropbox/autoload.php'; +require_once __DIR__ . '/../3rdparty/Dropbox/autoload.php'; OCP\JSON::checkAppEnabled('files_external'); OCP\JSON::checkLoggedIn(); diff --git a/apps/files_external/appinfo/app.php b/apps/files_external/appinfo/app.php index dd0b76ed9d7..5b1cd86a170 100644 --- a/apps/files_external/appinfo/app.php +++ b/apps/files_external/appinfo/app.php @@ -9,8 +9,9 @@ OC::$CLASSPATH['OC\Files\Storage\StreamWrapper'] = 'files_external/lib/streamwrapper.php'; OC::$CLASSPATH['OC\Files\Storage\FTP'] = 'files_external/lib/ftp.php'; OC::$CLASSPATH['OC\Files\Storage\DAV'] = 'files_external/lib/webdav.php'; +OC::$CLASSPATH['OC\Files\Storage\OwnCloud'] = 'files_external/lib/owncloud.php'; OC::$CLASSPATH['OC\Files\Storage\Google'] = 'files_external/lib/google.php'; -OC::$CLASSPATH['OC\Files\Storage\SWIFT'] = 'files_external/lib/swift.php'; +OC::$CLASSPATH['OC\Files\Storage\Swift'] = 'files_external/lib/swift.php'; OC::$CLASSPATH['OC\Files\Storage\SMB'] = 'files_external/lib/smb.php'; OC::$CLASSPATH['OC\Files\Storage\AmazonS3'] = 'files_external/lib/amazons3.php'; OC::$CLASSPATH['OC\Files\Storage\Dropbox'] = 'files_external/lib/dropbox.php'; diff --git a/apps/files_external/css/settings.css b/apps/files_external/css/settings.css index 4a32ac4153f..11aeb10184b 100644 --- a/apps/files_external/css/settings.css +++ b/apps/files_external/css/settings.css @@ -4,7 +4,6 @@ td.status > span { width: 16px; vertical-align: text-bottom; } - span.success { background: #37ce02; border-radius: 8px; @@ -12,9 +11,6 @@ span.success { span.error { background: #ce3702; } -span.waiting { - background: none; -} td.mountPoint, td.backend { width:160px; } td.remove>img { visibility:hidden; padding-top:13px; } @@ -22,3 +18,7 @@ tr:hover>td.remove>img { visibility:visible; cursor:pointer; } #addMountPoint>td { border:none; } #addMountPoint>td.applicable { visibility:hidden; } #selectBackend { margin-left:-10px; } + +#externalStorage label > input[type="checkbox"] { + margin-right: 3px; +} diff --git a/apps/files_external/js/dropbox.js b/apps/files_external/js/dropbox.js index 957daeb4d1f..6baaabe11b6 100644 --- a/apps/files_external/js/dropbox.js +++ b/apps/files_external/js/dropbox.js @@ -23,9 +23,12 @@ $(document).ready(function() { $(token).val(result.access_token); $(token_secret).val(result.access_token_secret); $(configured).val('true'); - OC.MountConfig.saveStorage(tr); - $(tr).find('.configuration input').attr('disabled', 'disabled'); - $(tr).find('.configuration').append('<span id="access" style="padding-left:0.5em;">'+t('files_external', 'Access granted')+'</span>'); + OC.MountConfig.saveStorage(tr, function(status) { + if (status) { + $(tr).find('.configuration input').attr('disabled', 'disabled'); + $(tr).find('.configuration').append('<span id="access" style="padding-left:0.5em;">'+t('files_external', 'Access granted')+'</span>'); + } + }); } else { OC.dialogs.alert(result.data.message, t('files_external', 'Error configuring Dropbox storage')); } @@ -77,7 +80,6 @@ $(document).ready(function() { var tr = $(this).parent().parent(); var app_key = $(this).parent().find('[data-parameter="app_key"]').val(); var app_secret = $(this).parent().find('[data-parameter="app_secret"]').val(); - var statusSpan = $(tr).find('.status span'); if (app_key != '' && app_secret != '') { var tr = $(this).parent().parent(); var configured = $(this).parent().find('[data-parameter="configured"]'); @@ -88,10 +90,9 @@ $(document).ready(function() { $(configured).val('false'); $(token).val(result.data.request_token); $(token_secret).val(result.data.request_token_secret); - OC.MountConfig.saveStorage(tr); - statusSpan.removeClass(); - statusSpan.addClass('waiting'); - window.location = result.data.url; + OC.MountConfig.saveStorage(tr, function() { + window.location = result.data.url; + }); } else { OC.dialogs.alert(result.data.message, t('files_external', 'Error configuring Dropbox storage')); } diff --git a/apps/files_external/js/google.js b/apps/files_external/js/google.js index b4be1c1dc41..068c2c13c66 100644 --- a/apps/files_external/js/google.js +++ b/apps/files_external/js/google.js @@ -32,11 +32,14 @@ $(document).ready(function() { if (result && result.status == 'success') { $(token).val(result.data.token); $(configured).val('true'); - OC.MountConfig.saveStorage(tr); - $(tr).find('.configuration input').attr('disabled', 'disabled'); - $(tr).find('.configuration').append($('<span/>') - .attr('id', 'access') - .text(t('files_external', 'Access granted'))); + OC.MountConfig.saveStorage(tr, function(status) { + if (status) { + $(tr).find('.configuration input').attr('disabled', 'disabled'); + $(tr).find('.configuration').append($('<span/>') + .attr('id', 'access') + .text(t('files_external', 'Access granted'))); + } + }); } else { OC.dialogs.alert(result.data.message, t('files_external', 'Error configuring Google Drive storage') @@ -99,7 +102,6 @@ $(document).ready(function() { var configured = $(this).parent().find('[data-parameter="configured"]'); var client_id = $(this).parent().find('[data-parameter="client_id"]').val(); var client_secret = $(this).parent().find('[data-parameter="client_secret"]').val(); - var statusSpan = $(tr).find('.status span'); if (client_id != '' && client_secret != '') { var token = $(this).parent().find('[data-parameter="token"]'); $.post(OC.filePath('files_external', 'ajax', 'google.php'), @@ -112,10 +114,9 @@ $(document).ready(function() { if (result && result.status == 'success') { $(configured).val('false'); $(token).val('false'); - OC.MountConfig.saveStorage(tr); - statusSpan.removeClass(); - statusSpan.addClass('waiting'); - window.location = result.data.url; + OC.MountConfig.saveStorage(tr, function(status) { + window.location = result.data.url; + }); } else { OC.dialogs.alert(result.data.message, t('files_external', 'Error configuring Google Drive storage') diff --git a/apps/files_external/js/settings.js b/apps/files_external/js/settings.js index 3e605c59a93..895f97bd2c3 100644 --- a/apps/files_external/js/settings.js +++ b/apps/files_external/js/settings.js @@ -1,10 +1,23 @@ +(function(){ + +function updateStatus(statusEl, result){ + statusEl.removeClass('success error loading-small'); + if (result && result.status == 'success' && result.data.message) { + statusEl.addClass('success'); + return true; + } else { + statusEl.addClass('error'); + return false; + } +} + OC.MountConfig={ - saveStorage:function(tr) { + saveStorage:function(tr, callback) { var mountPoint = $(tr).find('.mountPoint input').val(); if (mountPoint == '') { return false; } - var statusSpan = $(tr).find('.status span'); + var statusSpan = $(tr).closest('tr').find('.status span'); var backendClass = $(tr).find('.backend').data('class'); var configuration = $(tr).find('.configuration input'); var addMountPoint = true; @@ -58,6 +71,7 @@ OC.MountConfig={ } users.push(applicable); } + statusSpan.addClass('loading-small').removeClass('error success'); $.ajax({type: 'POST', url: OC.filePath('files_external', 'ajax', 'addMountPoint.php'), data: { @@ -68,14 +82,16 @@ OC.MountConfig={ applicable: applicable, isPersonal: isPersonal }, - async: false, success: function(result) { - statusSpan.removeClass(); - if (result && result.status == 'success' && result.data.message) { - status = true; - statusSpan.addClass('success'); - } else { - statusSpan.addClass('error'); + status = updateStatus(statusSpan, result); + if (callback) { + callback(status); + } + }, + error: function(result){ + status = updateStatus(statusSpan, result); + if (callback) { + callback(status); } } }); @@ -93,8 +109,7 @@ OC.MountConfig={ mountType: mountType, applicable: applicable, isPersonal: isPersonal - }, - async: false + } }); }); var mountType = 'user'; @@ -108,14 +123,14 @@ OC.MountConfig={ mountType: mountType, applicable: applicable, isPersonal: isPersonal - }, - async: false + } }); }); } else { var isPersonal = true; var mountType = 'user'; var applicable = OC.currentUser; + statusSpan.addClass('loading-small').removeClass('error success'); $.ajax({type: 'POST', url: OC.filePath('files_external', 'ajax', 'addMountPoint.php'), data: { @@ -126,14 +141,16 @@ OC.MountConfig={ applicable: applicable, isPersonal: isPersonal }, - async: false, success: function(result) { - statusSpan.removeClass(); - if (result && result.status == 'success' && result.data.message) { - status = true; - statusSpan.addClass('success'); - } else { - statusSpan.addClass('error'); + status = updateStatus(statusSpan, result); + if (callback) { + callback(status); + } + }, + error: function(result){ + status = updateStatus(statusSpan, result); + if (callback) { + callback(status); } } }); @@ -157,7 +174,7 @@ $(document).ready(function() { $(tr).find('.mountPoint input').val(suggestMountPoint(selected)); } $(tr).addClass(backendClass); - $(tr).find('.status').append('<span class="waiting"></span>'); + $(tr).find('.status').append('<span></span>'); $(tr).find('.backend').data('class', backendClass); var configurations = $(this).data('configurations'); var td = $(tr).find('td.configuration'); @@ -293,3 +310,5 @@ $(document).ready(function() { }); }); + +})(); diff --git a/apps/files_external/l10n/ar.php b/apps/files_external/l10n/ar.php index 905d221e886..338526d2afd 100644 --- a/apps/files_external/l10n/ar.php +++ b/apps/files_external/l10n/ar.php @@ -1,5 +1,8 @@ <?php $TRANSLATIONS = array( +"Folder name" => "اسم المجلد", +"Options" => "خيارات", +"All Users" => "كل المستخدمين", "Groups" => "مجموعات", "Users" => "المستخدمين", "Delete" => "إلغاء" diff --git a/apps/files_external/l10n/es_MX.php b/apps/files_external/l10n/es_MX.php new file mode 100644 index 00000000000..b508df8476a --- /dev/null +++ b/apps/files_external/l10n/es_MX.php @@ -0,0 +1,28 @@ +<?php +$TRANSLATIONS = array( +"Access granted" => "Acceso concedido", +"Error configuring Dropbox storage" => "Error configurando el almacenamiento de Dropbox", +"Grant access" => "Conceder acceso", +"Please provide a valid Dropbox app key and secret." => "Por favor, proporcione un una clave válida de la app Dropbox y una clave secreta.", +"Error configuring Google Drive storage" => "Error configurando el almacenamiento de Google Drive", +"<b>Warning:</b> \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "<b>Advertencia:</b> El cliente \"smbclient\" no se encuentra instalado. El montado de carpetas CIFS/SMB no es posible. Por favor pida al administrador de su sistema que lo instale.", +"<b>Warning:</b> The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "<b>Advertencia:</b> El soporte de FTP en PHP no se encuentra instalado. El montado de carpetas FTP no es posible. Por favor pida al administrador de su sistema que lo instale.", +"<b>Warning:</b> The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "<b>Advertencia:</b> El soporte de Curl en PHP no está activado ni instalado. El montado de ownCloud, WebDAV o GoogleDrive no es posible. Pida al administrador de su sistema que lo instale.", +"External Storage" => "Almacenamiento externo", +"Folder name" => "Nombre de la carpeta", +"External storage" => "Almacenamiento externo", +"Configuration" => "Configuración", +"Options" => "Opciones", +"Applicable" => "Aplicable", +"Add storage" => "Añadir almacenamiento", +"None set" => "No se ha configurado", +"All Users" => "Todos los usuarios", +"Groups" => "Grupos", +"Users" => "Usuarios", +"Delete" => "Eliminar", +"Enable User External Storage" => "Habilitar almacenamiento externo de usuario", +"Allow users to mount their own external storage" => "Permitir a los usuarios montar su propio almacenamiento externo", +"SSL root certificates" => "Certificados raíz SSL", +"Import Root Certificate" => "Importar certificado raíz" +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_external/l10n/km.php b/apps/files_external/l10n/km.php new file mode 100644 index 00000000000..f7d9faa38c5 --- /dev/null +++ b/apps/files_external/l10n/km.php @@ -0,0 +1,5 @@ +<?php +$TRANSLATIONS = array( +"Delete" => "លុប" +); +$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/files_external/l10n/sk.php b/apps/files_external/l10n/sk.php new file mode 100644 index 00000000000..3129cf5c411 --- /dev/null +++ b/apps/files_external/l10n/sk.php @@ -0,0 +1,5 @@ +<?php +$TRANSLATIONS = array( +"Delete" => "Odstrániť" +); +$PLURAL_FORMS = "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"; diff --git a/apps/files_external/l10n/sk_SK.php b/apps/files_external/l10n/sk_SK.php index ca445387bca..664d97c43b2 100644 --- a/apps/files_external/l10n/sk_SK.php +++ b/apps/files_external/l10n/sk_SK.php @@ -9,7 +9,7 @@ $TRANSLATIONS = array( "<b>Warning:</b> The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "<b>Upozornenie:</b> Podpora FTP v PHP nie je povolená alebo nainštalovaná. Nie je možné pripojenie oddielov FTP. Požiadajte administrátora systému, nech ho nainštaluje.", "<b>Warning:</b> The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "<b>Varovanie:</b> nie je nainštalovaná, alebo povolená, podpora Curl v PHP. Nie je možné pripojenie oddielov ownCloud, WebDAV, či GoogleDrive. Prosím požiadajte svojho administrátora systému, nech ju nainštaluje.", "External Storage" => "Externé úložisko", -"Folder name" => "Meno priečinka", +"Folder name" => "Názov priečinka", "External storage" => "Externé úložisko", "Configuration" => "Nastavenia", "Options" => "Možnosti", @@ -21,7 +21,7 @@ $TRANSLATIONS = array( "Users" => "Používatelia", "Delete" => "Zmazať", "Enable User External Storage" => "Povoliť externé úložisko", -"Allow users to mount their own external storage" => "Povoliť používateľom pripojiť ich vlastné externé úložisko", +"Allow users to mount their own external storage" => "Povoliť používateľom pripojiť si vlastné externé úložisko", "SSL root certificates" => "Koreňové SSL certifikáty", "Import Root Certificate" => "Importovať koreňový certifikát" ); diff --git a/apps/files_external/l10n/sq.php b/apps/files_external/l10n/sq.php index 42de15edadc..328822dcde8 100644 --- a/apps/files_external/l10n/sq.php +++ b/apps/files_external/l10n/sq.php @@ -1,5 +1,6 @@ <?php $TRANSLATIONS = array( +"Groups" => "Grupet", "Users" => "Përdoruesit", "Delete" => "Elimino" ); diff --git a/apps/files_external/l10n/tr.php b/apps/files_external/l10n/tr.php index cc52c425b8d..5d5e2b726a9 100644 --- a/apps/files_external/l10n/tr.php +++ b/apps/files_external/l10n/tr.php @@ -5,12 +5,12 @@ $TRANSLATIONS = array( "Grant access" => "Erişim sağlandı", "Please provide a valid Dropbox app key and secret." => "Lütfen Dropbox app key ve secret temin ediniz", "Error configuring Google Drive storage" => "Google Drive depo yapılandırma hatası", -"<b>Warning:</b> \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "<b>Uyari.</b>''smbclient''yüklü değil. Mont etme CIFS/SMB hissenin mümkün değildir. Lutfen kullanici sistemin sormak onu yuklemek ici, ", -"<b>Warning:</b> The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "<Uyari.</b>. Sistem FTP PHPden aktif degil veya yuklemedi. Monte etme hissenin FTP mumkun degildir. Lutfen kullaniici sistemin sormak onu yuklemek icin.", -"<b>Warning:</b> The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "<b> Ihbar </b>. Dayanma Curl PHPden aktif veya yuklemedi degil. Monte ownClouden/WebDay veya GoogleDrive mumkun degil. Lutfen sistm yonetici sormak yuklemek icin. ", +"<b>Warning:</b> \"smbclient\" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it." => "<b>Uyarı:</b> \"smbclient\" kurulu değil. CIFS/SMB paylaşımlarını bağlama işlemi mümkün olmadı. Lütfen kurulumu için sistem yöneticinize danışın.", +"<b>Warning:</b> The FTP support in PHP is not enabled or installed. Mounting of FTP shares is not possible. Please ask your system administrator to install it." => "<b>Uyarı:</b> PHP içerisinde FTP desteği etkin veya yüklü değil. FTP paylaşımlarını bağlama işlemi mümkün olmadı. Lütfen kurulumu için sistem yöneticinize danışın.", +"<b>Warning:</b> The Curl support in PHP is not enabled or installed. Mounting of ownCloud / WebDAV or GoogleDrive is not possible. Please ask your system administrator to install it." => "<b>Uyarı:</b> PHP içerisinde Curl desteği etkin veya yüklü değil. OwnCloud / WebDAV veya GoogleDrive bağlama işlemi mümkün olmadı. Lütfen kurulumu için sistem yöneticinizde danışın.", "External Storage" => "Harici Depolama", "Folder name" => "Dizin ismi", -"External storage" => "Harici Depolama", +"External storage" => "Harici depolama", "Configuration" => "Yapılandırma", "Options" => "Seçenekler", "Applicable" => "Uygulanabilir", diff --git a/apps/files_external/lib/amazons3.php b/apps/files_external/lib/amazons3.php index c08a266b48c..00baacd488c 100644 --- a/apps/files_external/lib/amazons3.php +++ b/apps/files_external/lib/amazons3.php @@ -81,9 +81,9 @@ class AmazonS3 extends \OC\Files\Storage\Common { $scheme = ($params['use_ssl'] === 'false') ? 'http' : 'https'; $this->test = isset($params['test']); $this->timeout = ( ! isset($params['timeout'])) ? 15 : $params['timeout']; - $params['region'] = ( ! isset($params['region'])) ? 'eu-west-1' : $params['region']; - $params['hostname'] = ( !isset($params['hostname'])) ? 's3.amazonaws.com' : $params['hostname']; - if (!isset($params['port'])) { + $params['region'] = ( ! isset($params['region']) || $params['region'] === '' ) ? 'eu-west-1' : $params['region']; + $params['hostname'] = ( !isset($params['hostname']) || $params['hostname'] === '' ) ? 's3.amazonaws.com' : $params['hostname']; + if (!isset($params['port']) || $params['port'] === '') { $params['port'] = ($params['use_ssl'] === 'false') ? 80 : 443; } $base_url = $scheme.'://'.$params['hostname'].':'.$params['port'].'/'; @@ -300,14 +300,6 @@ class AmazonS3 extends \OC\Files\Storage\Common { return false; } - public function isReadable($path) { - return true; - } - - public function isUpdatable($path) { - return true; - } - public function unlink($path) { $path = $this->normalizePath($path); @@ -515,8 +507,10 @@ class AmazonS3 extends \OC\Files\Storage\Common { } public function test() { - $test = $this->s3->get_canonical_user_id(); - if (isset($test['id']) && $test['id'] != '') { + $test = $this->connection->getBucketAcl(array( + 'Bucket' => $this->bucket, + )); + if (isset($test) && !is_null($test->getPath('Owner/ID'))) { return true; } return false; diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php index 659959e662e..01d588b3721 100755 --- a/apps/files_external/lib/config.php +++ b/apps/files_external/lib/config.php @@ -50,9 +50,9 @@ class OC_Mount_Config { 'key' => 'Access Key', 'secret' => '*Secret Key', 'bucket' => 'Bucket', - 'hostname' => 'Hostname (optional)', - 'port' => 'Port (optional)', - 'region' => 'Region (optional)', + 'hostname' => '&Hostname (optional)', + 'port' => '&Port (optional)', + 'region' => '&Region (optional)', 'use_ssl' => '!Enable SSL', 'use_path_style' => '!Enable Path Style')); @@ -84,14 +84,22 @@ class OC_Mount_Config { 'token' => '#token'), 'custom' => 'google'); - $backends['\OC\Files\Storage\SWIFT']=array( - 'backend' => 'OpenStack Swift', - 'configuration' => array( - 'host' => 'URL', - 'user' => 'Username', - 'token' => '*Token', - 'root' => '&Root', - 'secure' => '!Secure ftps://')); + if(OC_Mount_Config::checkcurl()) { + $backends['\OC\Files\Storage\Swift'] = array( + 'backend' => 'OpenStack Object Storage', + 'configuration' => array( + 'user' => 'Username (required)', + 'bucket' => 'Bucket (required)', + 'region' => '&Region (optional for OpenStack Object Storage)', + 'key' => '*API Key (required for Rackspace Cloud Files)', + 'tenant' => '&Tenantname (required for OpenStack Object Storage)', + 'password' => '*Password (required for OpenStack Object Storage)', + 'service_name' => '&Service Name (required for OpenStack Object Storage)', + 'url' => '&URL of identity endpoint (required for OpenStack Object Storage)', + 'timeout' => '&Timeout of HTTP requests in seconds (optional)', + ) + ); + } if (!OC_Util::runningOnWindows()) { if (OC_Mount_Config::checksmbclient()) { @@ -106,14 +114,24 @@ class OC_Mount_Config { } } - if(OC_Mount_Config::checkcurl()) $backends['\OC\Files\Storage\DAV']=array( - 'backend' => 'ownCloud / WebDAV', - 'configuration' => array( - 'host' => 'URL', - 'user' => 'Username', - 'password' => '*Password', - 'root' => '&Root', - 'secure' => '!Secure https://')); + if(OC_Mount_Config::checkcurl()){ + $backends['\OC\Files\Storage\DAV']=array( + 'backend' => 'WebDAV', + 'configuration' => array( + 'host' => 'URL', + 'user' => 'Username', + 'password' => '*Password', + 'root' => '&Root', + 'secure' => '!Secure https://')); + $backends['\OC\Files\Storage\OwnCloud']=array( + 'backend' => 'ownCloud', + 'configuration' => array( + 'host' => 'URL', + 'user' => 'Username', + 'password' => '*Password', + 'root' => '&Remote subfolder', + 'secure' => '!Secure https://')); + } $backends['\OC\Files\Storage\SFTP']=array( 'backend' => 'SFTP', @@ -236,6 +254,7 @@ class OC_Mount_Config { $storage = new $class($options); return $storage->test(); } catch (Exception $exception) { + \OCP\Util::logException('files_external', $exception); return false; } } @@ -258,6 +277,11 @@ class OC_Mount_Config { $mountType, $applicable, $isPersonal = false) { + $mountPoint = OC\Files\Filesystem::normalizePath($mountPoint); + if ($mountPoint === '' || $mountPoint === '/' || $mountPoint == '/Shared') { + // can't mount at root or "Shared" folder + return false; + } if ($isPersonal) { // Verify that the mount point applies for the current user // Prevent non-admin users from mounting local storage @@ -368,8 +392,7 @@ class OC_Mount_Config { * @return array */ public static function getCertificates() { - $view = \OCP\Files::getStorage('files_external'); - $path=\OCP\Config::getSystemValue('datadirectory').$view->getAbsolutePath("").'uploads/'; + $path=OC_User::getHome(OC_User::getUser()) . '/files_external/uploads/'; \OCP\Util::writeLog('files_external', 'checking path '.$path, \OCP\Util::INFO); if ( ! is_dir($path)) { //path might not exist (e.g. non-standard OC_User::getHome() value) @@ -391,8 +414,7 @@ class OC_Mount_Config { * creates certificate bundle */ public static function createCertificateBundle() { - $view = \OCP\Files::getStorage("files_external"); - $path = \OCP\Config::getSystemValue('datadirectory').$view->getAbsolutePath(""); + $path=OC_User::getHome(OC_User::getUser()) . '/files_external'; $certs = OC_Mount_Config::getCertificates(); $fh_certs = fopen($path."/rootcerts.crt", 'w'); @@ -417,7 +439,7 @@ class OC_Mount_Config { */ public static function checksmbclient() { if(function_exists('shell_exec')) { - $output=shell_exec('which smbclient'); + $output=shell_exec('which smbclient 2> /dev/null'); return !empty($output); }else{ return false; diff --git a/apps/files_external/lib/dropbox.php b/apps/files_external/lib/dropbox.php index b6deab6e5a7..f7d8d98cf03 100755 --- a/apps/files_external/lib/dropbox.php +++ b/apps/files_external/lib/dropbox.php @@ -50,6 +50,22 @@ class Dropbox extends \OC\Files\Storage\Common { } } + private function deleteMetaData($path) { + $path = $this->root.$path; + if (isset($this->metaData[$path])) { + unset($this->metaData[$path]); + return true; + } + return false; + } + + /** + * @brief Returns the path's metadata + * @param $path path for which to return the metadata + * @param $list if true, also return the directory's contents + * @return directory contents if $list is true, file metadata if $list is + * false, null if the file doesn't exist or "false" if the operation failed + */ private function getMetaData($path, $list = false) { $path = $this->root.$path; if ( ! $list && isset($this->metaData[$path])) { @@ -62,24 +78,35 @@ class Dropbox extends \OC\Files\Storage\Common { \OCP\Util::writeLog('files_external', $exception->getMessage(), \OCP\Util::ERROR); return false; } + $contents = array(); if ($response && isset($response['contents'])) { - $contents = $response['contents']; // Cache folder's contents - foreach ($contents as $file) { - $this->metaData[$path.'/'.basename($file['path'])] = $file; + foreach ($response['contents'] as $file) { + if (!isset($file['is_deleted']) || !$file['is_deleted']) { + $this->metaData[$path.'/'.basename($file['path'])] = $file; + $contents[] = $file; + } } unset($response['contents']); + } + if (!isset($response['is_deleted']) || !$response['is_deleted']) { $this->metaData[$path] = $response; } - $this->metaData[$path] = $response; // Return contents of folder only return $contents; } else { try { $response = $this->dropbox->getMetaData($path, 'false'); - $this->metaData[$path] = $response; - return $response; + if (!isset($response['is_deleted']) || !$response['is_deleted']) { + $this->metaData[$path] = $response; + return $response; + } + return null; } catch (\Exception $exception) { + if ($exception instanceof \Dropbox_Exception_NotFound) { + // don't log, might be a file_exist check + return false; + } \OCP\Util::writeLog('files_external', $exception->getMessage(), \OCP\Util::ERROR); return false; } @@ -108,7 +135,7 @@ class Dropbox extends \OC\Files\Storage\Common { public function opendir($path) { $contents = $this->getMetaData($path, true); - if ($contents) { + if ($contents !== false) { $files = array(); foreach ($contents as $file) { $files[] = basename($file['path']); @@ -146,14 +173,6 @@ class Dropbox extends \OC\Files\Storage\Common { return false; } - public function isReadable($path) { - return $this->file_exists($path); - } - - public function isUpdatable($path) { - return $this->file_exists($path); - } - public function file_exists($path) { if ($path == '' || $path == '/') { return true; @@ -165,9 +184,9 @@ class Dropbox extends \OC\Files\Storage\Common { } public function unlink($path) { - $path = $this->root.$path; try { - $this->dropbox->delete($path); + $this->dropbox->delete($this->root.$path); + $this->deleteMetaData($path); return true; } catch (\Exception $exception) { \OCP\Util::writeLog('files_external', $exception->getMessage(), \OCP\Util::ERROR); @@ -176,10 +195,14 @@ class Dropbox extends \OC\Files\Storage\Common { } public function rename($path1, $path2) { - $path1 = $this->root.$path1; - $path2 = $this->root.$path2; try { - $this->dropbox->move($path1, $path2); + // overwrite if target file exists and is not a directory + $destMetaData = $this->getMetaData($path2); + if (isset($destMetaData) && $destMetaData !== false && !$destMetaData['is_dir']) { + $this->unlink($path2); + } + $this->dropbox->move($this->root.$path1, $this->root.$path2); + $this->deleteMetaData($path1); return true; } catch (\Exception $exception) { \OCP\Util::writeLog('files_external', $exception->getMessage(), \OCP\Util::ERROR); @@ -277,7 +300,12 @@ class Dropbox extends \OC\Files\Storage\Common { } public function touch($path, $mtime = null) { - return false; + if ($this->file_exists($path)) { + return false; + } else { + $this->file_put_contents($path, ''); + } + return true; } } diff --git a/apps/files_external/lib/ftp.php b/apps/files_external/lib/ftp.php index ca6c635eb2b..00bf7a189ce 100644 --- a/apps/files_external/lib/ftp.php +++ b/apps/files_external/lib/ftp.php @@ -35,6 +35,9 @@ class FTP extends \OC\Files\Storage\StreamWrapper{ if ( ! $this->root || $this->root[0]!='/') { $this->root='/'.$this->root; } + if (substr($this->root, -1) !== '/') { + $this->root .= '/'; + } } else { throw new \Exception(); } @@ -58,6 +61,22 @@ class FTP extends \OC\Files\Storage\StreamWrapper{ $url.='://'.$this->user.':'.$this->password.'@'.$this->host.$this->root.$path; return $url; } + + /** + * Unlinks file or directory + * @param string @path + */ + public function unlink($path) { + if ($this->is_dir($path)) { + return $this->rmdir($path); + } + else { + $url = $this->constructUrl($path); + $result = unlink($url); + clearstatcache(true, $url); + return $result; + } + } public function fopen($path,$mode) { switch($mode) { case 'r': diff --git a/apps/files_external/lib/google.php b/apps/files_external/lib/google.php index b63b5885de1..426caf008ec 100644 --- a/apps/files_external/lib/google.php +++ b/apps/files_external/lib/google.php @@ -317,10 +317,6 @@ class Google extends \OC\Files\Storage\Common { } } - public function isReadable($path) { - return $this->file_exists($path); - } - public function isUpdatable($path) { $file = $this->getDriveFile($path); if ($file) { diff --git a/apps/files_external/lib/owncloud.php b/apps/files_external/lib/owncloud.php new file mode 100644 index 00000000000..98314102a64 --- /dev/null +++ b/apps/files_external/lib/owncloud.php @@ -0,0 +1,51 @@ +<?php +/** + * Copyright (c) 2013 Vincent Petry <pvince81@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Storage; + +/** + * ownCloud backend for external storage based on DAV backend. + * + * The ownCloud URL consists of three parts: + * http://%host/%context/remote.php/webdav/%root + * + */ +class OwnCloud extends \OC\Files\Storage\DAV{ + const OC_URL_SUFFIX = 'remote.php/webdav'; + + public function __construct($params) { + // extract context path from host if specified + // (owncloud install path on host) + $host = $params['host']; + $contextPath = ''; + $hostSlashPos = strpos($host, '/'); + if ($hostSlashPos !== false){ + $contextPath = substr($host, $hostSlashPos); + $host = substr($host, 0, $hostSlashPos); + } + + if (substr($contextPath , 1) !== '/'){ + $contextPath .= '/'; + } + + if (isset($params['root'])){ + $root = $params['root']; + if (substr($root, 1) !== '/'){ + $root = '/' . $root; + } + } + else{ + $root = '/'; + } + + $params['host'] = $host; + $params['root'] = $contextPath . self::OC_URL_SUFFIX . $root; + + parent::__construct($params); + } +} diff --git a/apps/files_external/lib/sftp.php b/apps/files_external/lib/sftp.php index f7f329b8993..95e0cefa398 100644 --- a/apps/files_external/lib/sftp.php +++ b/apps/files_external/lib/sftp.php @@ -29,83 +29,97 @@ class SFTP extends \OC\Files\Storage\Common { } $this->user = $params['user']; $this->password = $params['password']; - $this->root = isset($params['root']) ? $this->cleanPath($params['root']) : '/'; - if ($this->root[0] != '/') $this->root = '/' . $this->root; - if (substr($this->root, -1, 1) != '/') $this->root .= '/'; + $this->root + = isset($params['root']) ? $this->cleanPath($params['root']) : '/'; - $host_keys = $this->read_host_keys(); + if ($this->root[0] != '/') { + $this->root = '/' . $this->root; + } + + if (substr($this->root, -1, 1) != '/') { + $this->root .= '/'; + } + $hostKeys = $this->readHostKeys(); $this->client = new \Net_SFTP($this->host); + if (!$this->client->login($this->user, $this->password)) { throw new \Exception('Login failed'); } - $current_host_key = $this->client->getServerPublicHostKey(); + $currentHostKey = $this->client->getServerPublicHostKey(); - if (array_key_exists($this->host, $host_keys)) { - if ($host_keys[$this->host] != $current_host_key) { + if (array_key_exists($this->host, $hostKeys)) { + if ($hostKeys[$this->host] != $currentHostKey) { throw new \Exception('Host public key does not match known key'); } } else { - $host_keys[$this->host] = $current_host_key; - $this->write_host_keys($host_keys); + $hostKeys[$this->host] = $currentHostKey; + $this->writeHostKeys($hostKeys); } } public function test() { - if (!isset($params['host']) || !isset($params['user']) || !isset($params['password'])) { - throw new \Exception("Required parameters not set"); + if ( + !isset($this->host) + || !isset($this->user) + || !isset($this->password) + ) { + return false; } + return $this->client->nlist() !== false; } public function getId(){ return 'sftp::' . $this->user . '@' . $this->host . '/' . $this->root; } - private function abs_path($path) { + private function absPath($path) { return $this->root . $this->cleanPath($path); } - private function host_keys_path() { + private function hostKeysPath() { try { $storage_view = \OCP\Files::getStorage('files_external'); if ($storage_view) { return \OCP\Config::getSystemValue('datadirectory') . $storage_view->getAbsolutePath('') . - 'ssh_host_keys'; + 'ssh_hostKeys'; } } catch (\Exception $e) { } return false; } - private function write_host_keys($keys) { + private function writeHostKeys($keys) { try { - $key_path = $this->host_keys_path(); - $fp = fopen($key_path, 'w'); - foreach ($keys as $host => $key) { - fwrite($fp, $host . '::' . $key . "\n"); + $keyPath = $this->hostKeysPath(); + if ($keyPath && file_exists($keyPath)) { + $fp = fopen($keyPath, 'w'); + foreach ($keys as $host => $key) { + fwrite($fp, $host . '::' . $key . "\n"); + } + fclose($fp); + return true; } - fclose($fp); - return true; } catch (\Exception $e) { - return false; } + return false; } - private function read_host_keys() { + private function readHostKeys() { try { - $key_path = $this->host_keys_path(); - if (file_exists($key_path)) { + $keyPath = $this->hostKeysPath(); + if (file_exists($keyPath)) { $hosts = array(); $keys = array(); - $lines = file($key_path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + $lines = file($keyPath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ($lines) { foreach ($lines as $line) { - $host_key_arr = explode("::", $line, 2); - if (count($host_key_arr) == 2) { - $hosts[] = $host_key_arr[0]; - $keys[] = $host_key_arr[1]; + $hostKeyArray = explode("::", $line, 2); + if (count($hostKeyArray) == 2) { + $hosts[] = $hostKeyArray[0]; + $keys[] = $hostKeyArray[1]; } } return array_combine($hosts, $keys); @@ -118,7 +132,7 @@ class SFTP extends \OC\Files\Storage\Common { public function mkdir($path) { try { - return $this->client->mkdir($this->abs_path($path)); + return $this->client->mkdir($this->absPath($path)); } catch (\Exception $e) { return false; } @@ -126,7 +140,7 @@ class SFTP extends \OC\Files\Storage\Common { public function rmdir($path) { try { - return $this->client->delete($this->abs_path($path), true); + return $this->client->delete($this->absPath($path), true); } catch (\Exception $e) { return false; } @@ -134,16 +148,16 @@ class SFTP extends \OC\Files\Storage\Common { public function opendir($path) { try { - $list = $this->client->nlist($this->abs_path($path)); + $list = $this->client->nlist($this->absPath($path)); $id = md5('sftp:' . $path); - $dir_stream = array(); + $dirStream = array(); foreach($list as $file) { if ($file != '.' && $file != '..') { - $dir_stream[] = $file; + $dirStream[] = $file; } } - \OC\Files\Stream\Dir::register($id, $dir_stream); + \OC\Files\Stream\Dir::register($id, $dirStream); return opendir('fakedir://' . $id); } catch(\Exception $e) { return false; @@ -152,25 +166,23 @@ class SFTP extends \OC\Files\Storage\Common { public function filetype($path) { try { - $stat = $this->client->stat($this->abs_path($path)); - if ($stat['type'] == NET_SFTP_TYPE_REGULAR) return 'file'; - if ($stat['type'] == NET_SFTP_TYPE_DIRECTORY) return 'dir'; + $stat = $this->client->stat($this->absPath($path)); + if ($stat['type'] == NET_SFTP_TYPE_REGULAR) { + return 'file'; + } + + if ($stat['type'] == NET_SFTP_TYPE_DIRECTORY) { + return 'dir'; + } } catch (\Exeption $e) { + } return false; } - public function isReadable($path) { - return true; - } - - public function isUpdatable($path) { - return true; - } - public function file_exists($path) { try { - return $this->client->stat($this->abs_path($path)) !== false; + return $this->client->stat($this->absPath($path)) !== false; } catch (\Exception $e) { return false; } @@ -178,7 +190,7 @@ class SFTP extends \OC\Files\Storage\Common { public function unlink($path) { try { - return $this->client->delete($this->abs_path($path), true); + return $this->client->delete($this->absPath($path), true); } catch (\Exception $e) { return false; } @@ -186,18 +198,21 @@ class SFTP extends \OC\Files\Storage\Common { public function fopen($path, $mode) { try { - $abs_path = $this->abs_path($path); + $absPath = $this->absPath($path); switch($mode) { case 'r': case 'rb': - if ( !$this->file_exists($path)) return false; + if ( !$this->file_exists($path)) { + return false; + } + if (strrpos($path, '.')!==false) { $ext=substr($path, strrpos($path, '.')); } else { $ext=''; } $tmp = \OC_Helper::tmpFile($ext); - $this->getFile($abs_path, $tmp); + $this->getFile($absPath, $tmp); return fopen($tmp, $mode); case 'w': @@ -217,12 +232,18 @@ class SFTP extends \OC\Files\Storage\Common { } else { $ext=''; } + $tmpFile=\OC_Helper::tmpFile($ext); - \OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack')); + \OC\Files\Stream\Close::registerCallback( + $tmpFile, + array($this, 'writeBack') + ); + if ($this->file_exists($path)) { - $this->getFile($abs_path, $tmpFile); + $this->getFile($absPath, $tmpFile); } - self::$tempFiles[$tmpFile]=$abs_path; + + self::$tempFiles[$tmpFile]=$absPath; return fopen('close://'.$tmpFile, $mode); } } catch (\Exception $e) { @@ -240,9 +261,11 @@ class SFTP extends \OC\Files\Storage\Common { public function touch($path, $mtime=null) { try { - if (!is_null($mtime)) return false; + if (!is_null($mtime)) { + return false; + } if (!$this->file_exists($path)) { - $this->client->put($this->abs_path($path), ''); + $this->client->put($this->absPath($path), ''); } else { return false; } @@ -262,7 +285,13 @@ class SFTP extends \OC\Files\Storage\Common { public function rename($source, $target) { try { - return $this->client->rename($this->abs_path($source), $this->abs_path($target)); + if (!$this->is_dir($target) && $this->file_exists($target)) { + $this->unlink($target); + } + return $this->client->rename( + $this->absPath($source), + $this->absPath($target) + ); } catch (\Exception $e) { return false; } @@ -270,7 +299,7 @@ class SFTP extends \OC\Files\Storage\Common { public function stat($path) { try { - $stat = $this->client->stat($this->abs_path($path)); + $stat = $this->client->stat($this->absPath($path)); $mtime = $stat ? $stat['mtime'] : -1; $size = $stat ? $stat['size'] : 0; @@ -279,6 +308,5 @@ class SFTP extends \OC\Files\Storage\Common { } catch (\Exception $e) { return false; } - } } diff --git a/apps/files_external/lib/smb.php b/apps/files_external/lib/smb.php index ecd4dae0484..c5fba92ee68 100644 --- a/apps/files_external/lib/smb.php +++ b/apps/files_external/lib/smb.php @@ -47,8 +47,13 @@ class SMB extends \OC\Files\Storage\StreamWrapper{ public function constructUrl($path) { if (substr($path, -1)=='/') { - $path=substr($path, 0, -1); + $path = substr($path, 0, -1); } + if (substr($path, 0, 1)=='/') { + $path = substr($path, 1); + } + // remove trailing dots which some versions of samba don't seem to like + $path = rtrim($path, '.'); $path = urlencode($path); $user = urlencode($this->user); $pass = urlencode($this->password); @@ -77,6 +82,24 @@ class SMB extends \OC\Files\Storage\StreamWrapper{ } /** + * Unlinks file or directory + * @param string @path + */ + public function unlink($path) { + if ($this->is_dir($path)) { + $this->rmdir($path); + } + else { + $url = $this->constructUrl($path); + unlink($url); + clearstatcache(false, $url); + } + // smb4php still returns false even on success so + // check here whether file was really deleted + return !file_exists($path); + } + + /** * check if a file or folder has been updated since $time * @param string $path * @param int $time diff --git a/apps/files_external/lib/streamwrapper.php b/apps/files_external/lib/streamwrapper.php index beb4ec5605f..e484325e2fb 100644 --- a/apps/files_external/lib/streamwrapper.php +++ b/apps/files_external/lib/streamwrapper.php @@ -8,7 +8,7 @@ namespace OC\Files\Storage; -abstract class StreamWrapper extends Common{ +abstract class StreamWrapper extends Common { abstract public function constructUrl($path); public function mkdir($path) { @@ -16,9 +16,18 @@ abstract class StreamWrapper extends Common{ } public function rmdir($path) { - if($this->file_exists($path)) { - $success = rmdir($this->constructUrl($path)); - clearstatcache(); + if ($this->file_exists($path)) { + $dh = $this->opendir($path); + while (($file = readdir($dh)) !== false) { + if ($this->is_dir($path . '/' . $file)) { + $this->rmdir($path . '/' . $file); + } else { + $this->unlink($path . '/' . $file); + } + } + $url = $this->constructUrl($path); + $success = rmdir($url); + clearstatcache(false, $url); return $success; } else { return false; @@ -30,15 +39,7 @@ abstract class StreamWrapper extends Common{ } public function filetype($path) { - return filetype($this->constructUrl($path)); - } - - public function isReadable($path) { - return true;//not properly supported - } - - public function isUpdatable($path) { - return true;//not properly supported + return @filetype($this->constructUrl($path)); } public function file_exists($path) { @@ -46,8 +47,11 @@ abstract class StreamWrapper extends Common{ } public function unlink($path) { - $success = unlink($this->constructUrl($path)); - clearstatcache(); + $url = $this->constructUrl($path); + $success = unlink($url); + // normally unlink() is supposed to do this implicitly, + // but doing it anyway just to be sure + clearstatcache(false, $url); return $success; } @@ -55,15 +59,20 @@ abstract class StreamWrapper extends Common{ return fopen($this->constructUrl($path), $mode); } - public function touch($path, $mtime=null) { - if(is_null($mtime)) { - $fh = $this->fopen($path, 'a'); - fwrite($fh, ''); - fclose($fh); - - return true; + public function touch($path, $mtime = null) { + if ($this->file_exists($path)) { + if (is_null($mtime)) { + $fh = $this->fopen($path, 'a'); + fwrite($fh, ''); + fclose($fh); + + return true; + } else { + return false; //not supported + } } else { - return false;//not supported + $this->file_put_contents($path, ''); + return true; } } diff --git a/apps/files_external/lib/swift.php b/apps/files_external/lib/swift.php index a9cfe5bd20f..b615d24ce76 100644 --- a/apps/files_external/lib/swift.php +++ b/apps/files_external/lib/swift.php @@ -1,462 +1,311 @@ <?php + /** - * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com> - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. + * ownCloud + * + * @author Christian Berendt + * @copyright 2013 Christian Berendt berendt@b1-systems.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library 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 along with this library. If not, see <http://www.gnu.org/licenses/>. */ namespace OC\Files\Storage; -require_once 'php-cloudfiles/cloudfiles.php'; - -class SWIFT extends \OC\Files\Storage\Common{ - private $id; - private $host; - private $root; - private $user; - private $token; - private $secure; - private $ready = false; - /** - * @var \CF_Authentication auth - */ - private $auth; - /** - * @var \CF_Connection conn - */ - private $conn; - /** - * @var \CF_Container rootContainer - */ - private $rootContainer; - - private static $tempFiles=array(); - private $objects=array(); - private $containers=array(); - - const SUBCONTAINER_FILE='.subcontainers'; - - /** - * translate directory path to container name - * @param string $path - * @return string - */ - private function getContainerName($path) { - $path=trim(trim($this->root, '/') . "/".$path, '/.'); - return str_replace('/', '\\', $path); - } +set_include_path(get_include_path() . PATH_SEPARATOR . + \OC_App::getAppPath('files_external') . '/3rdparty/php-opencloud/lib'); +require_once 'openstack.php'; - /** - * get container by path - * @param string $path - * @return \CF_Container - */ - private function getContainer($path) { - if ($path=='' or $path=='/') { - return $this->rootContainer; - } - if (isset($this->containers[$path])) { - return $this->containers[$path]; - } - try { - $container=$this->conn->get_container($this->getContainerName($path)); - $this->containers[$path]=$container; - return $container; - } catch(\NoSuchContainerException $e) { - return null; - } - } +use \OpenCloud; +use \OpenCloud\Common\Exceptions; - /** - * create container - * @param string $path - * @return \CF_Container - */ - private function createContainer($path) { - if ($path=='' or $path=='/' or $path=='.') { - return $this->conn->create_container($this->getContainerName($path)); - } - $parent=dirname($path); - if ($parent=='' or $parent=='/' or $parent=='.') { - $parentContainer=$this->rootContainer; - } else { - if ( ! $this->containerExists($parent)) { - $parentContainer=$this->createContainer($parent); - } else { - $parentContainer=$this->getContainer($parent); - } +class Swift extends \OC\Files\Storage\Common { + + /** + * @var \OpenCloud\ObjectStore + */ + private $connection; + /** + * @var \OpenCloud\ObjectStore\Container + */ + private $container; + /** + * @var \OpenCloud\OpenStack + */ + private $anchor; + /** + * @var string + */ + private $bucket; + /** + * @var array + */ + private static $tmpFiles = array(); + + private function normalizePath($path) { + $path = trim($path, '/'); + + if (!$path) { + $path = '.'; } - $this->addSubContainer($parentContainer, basename($path)); - return $this->conn->create_container($this->getContainerName($path)); + + return $path; } - /** - * get object by path - * @param string $path - * @return \CF_Object - */ - private function getObject($path) { - if (isset($this->objects[$path])) { - return $this->objects[$path]; - } - $container=$this->getContainer(dirname($path)); - if (is_null($container)) { - return null; - } else { - if ($path=="/" or $path=='') { - return null; - } - try { - $obj=$container->get_object(basename($path)); - $this->objects[$path]=$obj; - return $obj; - } catch(\NoSuchObjectException $e) { - return null; - } + private function doesObjectExist($path) { + try { + $object = $this->container->DataObject($path); + return true; + } catch (Exceptions\ObjFetchError $e) { + \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR); + return false; + } catch (Exceptions\HttpError $e) { + \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR); + return false; } } - /** - * get the names of all objects in a container - * @param CF_Container - * @return array - */ - private function getObjects($container) { - if (is_null($container)) { - return array(); - } else { - $files=$container->get_objects(); - foreach ($files as &$file) { - $file=$file->name; - } - return $files; + public function __construct($params) { + if ((!isset($params['key']) and !isset($params['password'])) + or !isset($params['user']) or !isset($params['bucket']) + or !isset($params['region'])) { + throw new \Exception("API Key or password, Username, Bucket and Region have to be configured."); } - } - /** - * create object - * @param string $path - * @return \CF_Object - */ - private function createObject($path) { - $container=$this->getContainer(dirname($path)); - if ( ! is_null($container)) { - $container=$this->createContainer(dirname($path)); - } - return $container->create_object(basename($path)); - } + $this->id = 'swift::' . $params['user'] . md5($params['bucket']); + $this->bucket = $params['bucket']; - /** - * check if an object exists - * @param string - * @return bool - */ - private function objectExists($path) { - return !is_null($this->getObject($path)); - } + if (!isset($params['url'])) { + $params['url'] = 'https://identity.api.rackspacecloud.com/v2.0/'; + } - /** - * check if container for path exists - * @param string $path - * @return bool - */ - private function containerExists($path) { - return !is_null($this->getContainer($path)); - } + if (!isset($params['service_name'])) { + $params['service_name'] = 'cloudFiles'; + } - /** - * get the list of emulated sub containers - * @param \CF_Container $container - * @return array - */ - private function getSubContainers($container) { - $tmpFile=\OCP\Files::tmpFile(); - $obj=$this->getSubContainerFile($container); - try { - $obj->save_to_filename($tmpFile); - } catch(\Exception $e) { - return array(); + $settings = array( + 'username' => $params['user'], + + ); + + if (isset($params['password'])) { + $settings['password'] = $params['password']; + } else if (isset($params['key'])) { + $settings['apiKey'] = $params['key']; } - $obj->save_to_filename($tmpFile); - $containers=file($tmpFile); - unlink($tmpFile); - foreach ($containers as &$sub) { - $sub=trim($sub); + + if (isset($params['tenant'])) { + $settings['tenantName'] = $params['tenant']; } - return $containers; - } - /** - * add an emulated sub container - * @param \CF_Container $container - * @param string $name - * @return bool - */ - private function addSubContainer($container, $name) { - if ( ! $name) { - return false; + $this->anchor = new \OpenCloud\OpenStack($params['url'], $settings); + + if (isset($params['timeout'])) { + $this->anchor->setHttpTimeout($params['timeout']); } - $tmpFile=\OCP\Files::tmpFile(); - $obj=$this->getSubContainerFile($container); + + $this->connection = $this->anchor->ObjectStore($params['service_name'], $params['region'], 'publicURL'); + try { - $obj->save_to_filename($tmpFile); - $containers=file($tmpFile); - foreach ($containers as &$sub) { - $sub=trim($sub); - } - if(array_search($name, $containers) !== false) { - unlink($tmpFile); - return false; - } else { - $fh=fopen($tmpFile, 'a'); - fwrite($fh, $name . "\n"); - } - } catch(\Exception $e) { - file_put_contents($tmpFile, $name . "\n"); + $this->container = $this->connection->Container($this->bucket); + } catch (Exceptions\ContainerNotFoundError $e) { + $this->container = $this->connection->Container(); + $this->container->Create(array('name' => $this->bucket)); } - $obj->load_from_filename($tmpFile); - unlink($tmpFile); - return true; + if (!$this->file_exists('.')) { + $this->mkdir('.'); + } } - /** - * remove an emulated sub container - * @param \CF_Container $container - * @param string $name - * @return bool - */ - private function removeSubContainer($container, $name) { - if ( ! $name) { - return false; - } - $tmpFile=\OCP\Files::tmpFile(); - $obj=$this->getSubContainerFile($container); - try { - $obj->save_to_filename($tmpFile); - $containers=file($tmpFile); - } catch (\Exception $e) { + public function mkdir($path) { + $path = $this->normalizePath($path); + + if ($this->is_dir($path)) { return false; } - foreach ($containers as &$sub) { - $sub=trim($sub); + + if($path !== '.') { + $path .= '/'; } - $i=array_search($name, $containers); - if ($i===false) { - unlink($tmpFile); + + try { + $object = $this->container->DataObject(); + $object->Create(array( + 'name' => $path, + 'content_type' => 'httpd/unix-directory' + )); + } catch (Exceptions\CreateUpdateError $e) { + \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR); return false; - } else { - unset($containers[$i]); - file_put_contents($tmpFile, implode("\n", $containers)."\n"); } - $obj->load_from_filename($tmpFile); - unlink($tmpFile); return true; } - /** - * ensure a subcontainer file exists and return it's object - * @param \CF_Container $container - * @return \CF_Object - */ - private function getSubContainerFile($container) { - try { - return $container->get_object(self::SUBCONTAINER_FILE); - } catch(\NoSuchObjectException $e) { - return $container->create_object(self::SUBCONTAINER_FILE); - } - } + public function file_exists($path) { + $path = $this->normalizePath($path); - public function __construct($params) { - if (isset($params['token']) && isset($params['host']) && isset($params['user'])) { - $this->token=$params['token']; - $this->host=$params['host']; - $this->user=$params['user']; - $this->root=isset($params['root'])?$params['root']:'/'; - if (isset($params['secure'])) { - if (is_string($params['secure'])) { - $this->secure = ($params['secure'] === 'true'); - } else { - $this->secure = (bool)$params['secure']; - } - } else { - $this->secure = false; - } - if ( ! $this->root || $this->root[0]!='/') { - $this->root='/'.$this->root; - } - $this->id = 'swift:' . $this->host . ':'.$this->root . ':' . $this->user; - } else { - throw new \Exception(); + if ($path !== '.' && $this->is_dir($path)) { + $path .= '/'; } + return $this->doesObjectExist($path); } - private function init(){ - if($this->ready) { - return; + public function rmdir($path) { + $path = $this->normalizePath($path); + + if (!$this->is_dir($path)) { + return false; } - $this->ready = true; - $this->auth = new \CF_Authentication($this->user, $this->token, null, $this->host); - $this->auth->authenticate(); + $dh = $this->opendir($path); + while ($file = readdir($dh)) { + if ($file === '.' || $file === '..') { + continue; + } - $this->conn = new \CF_Connection($this->auth); + if ($this->is_dir($path . '/' . $file)) { + $this->rmdir($path . '/' . $file); + } else { + $this->unlink($path . '/' . $file); + } + } - if ( ! $this->containerExists('/')) { - $this->rootContainer=$this->createContainer('/'); - } else { - $this->rootContainer=$this->getContainer('/'); + try { + $object = $this->container->DataObject($path . '/'); + $object->Delete(); + } catch (Exceptions\DeleteError $e) { + \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR); + return false; } - } - public function getId(){ - return $this->id; + return true; } + public function opendir($path) { + $path = $this->normalizePath($path); - public function mkdir($path) { - $this->init(); - if ($this->containerExists($path)) { - return false; + if ($path === '.') { + $path = ''; } else { - $this->createContainer($path); - return true; + $path .= '/'; } - } - public function rmdir($path) { - $this->init(); - if (!$this->containerExists($path)) { - return false; - } else { - $this->emptyContainer($path); - if ($path!='' and $path!='/') { - $parentContainer=$this->getContainer(dirname($path)); - $this->removeSubContainer($parentContainer, basename($path)); + try { + $files = array(); + $objects = $this->container->ObjectList(array( + 'prefix' => $path, + 'delimiter' => '/' + )); + + while ($object = $objects->Next()) { + $file = basename($object->Name()); + if ($file !== basename($path)) { + $files[] = $file; + } } - $this->conn->delete_container($this->getContainerName($path)); - unset($this->containers[$path]); - return true; + \OC\Files\Stream\Dir::register('swift' . $path, $files); + return opendir('fakedir://swift' . $path); + } catch (Exception $e) { + \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR); + return false; } + } - private function emptyContainer($path) { - $container=$this->getContainer($path); - if (is_null($container)) { - return; - } - $subContainers=$this->getSubContainers($container); - foreach ($subContainers as $sub) { - if ($sub) { - $this->emptyContainer($path.'/'.$sub); - $this->conn->delete_container($this->getContainerName($path.'/'.$sub)); - unset($this->containers[$path.'/'.$sub]); - } - } + public function stat($path) { + $path = $this->normalizePath($path); - $objects=$this->getObjects($container); - foreach ($objects as $object) { - $container->delete_object($object); - unset($this->objects[$path.'/'.$object]); + if ($this->is_dir($path) && $path != '.') { + $path .= '/'; } - } - public function opendir($path) { - $this->init(); - $container=$this->getContainer($path); - $files=$this->getObjects($container); - $i=array_search(self::SUBCONTAINER_FILE, $files); - if ($i!==false) { - unset($files[$i]); - } - $subContainers=$this->getSubContainers($container); - $files=array_merge($files, $subContainers); - $id=$this->getContainerName($path); - \OC\Files\Stream\Dir::register($id, $files); - return opendir('fakedir://'.$id); - } + try { + $object = $this->container->DataObject($path); + } catch (Exceptions\ObjFetchError $e) { + \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR); + return false; + } - public function filetype($path) { - $this->init(); - if ($this->containerExists($path)) { - return 'dir'; - } else { - return 'file'; + $mtime = $object->extra_headers['X-Timestamp']; + if (isset($object->extra_headers['X-Object-Meta-Timestamp'])) { + $mtime = $object->extra_headers['X-Object-Meta-Timestamp']; } - } - public function isReadable($path) { - return true; + $stat = array(); + $stat['size'] = $object->content_length; + $stat['mtime'] = $mtime; + $stat['atime'] = time(); + return $stat; } - public function isUpdatable($path) { - return true; - } + public function filetype($path) { + $path = $this->normalizePath($path); - public function file_exists($path) { - $this->init(); - if ($this->is_dir($path)) { - return true; - } else { - return $this->objectExists($path); + if ($path !== '.' && $this->doesObjectExist($path)) { + return 'file'; } - } - public function file_get_contents($path) { - $this->init(); - $obj=$this->getObject($path); - if (is_null($obj)) { - return false; + if ($path !== '.') { + $path .= '/'; } - return $obj->read(); - } - public function file_put_contents($path, $content) { - $this->init(); - $obj=$this->getObject($path); - if (is_null($obj)) { - $container=$this->getContainer(dirname($path)); - if (is_null($container)) { - return false; - } - $obj=$container->create_object(basename($path)); + if ($this->doesObjectExist($path)) { + return 'dir'; } - $this->resetMTime($obj); - return $obj->write($content); } public function unlink($path) { - $this->init(); - if ($this->containerExists($path)) { - return $this->rmdir($path); - } - if ($this->objectExists($path)) { - $container=$this->getContainer(dirname($path)); - $container->delete_object(basename($path)); - unset($this->objects[$path]); - } else { + $path = $this->normalizePath($path); + + try { + $object = $this->container->DataObject($path); + $object->Delete(); + } catch (Exceptions\DeleteError $e) { + \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR); + return false; + } catch (Exceptions\ObjFetchError $e) { + \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR); return false; } + + return true; } public function fopen($path, $mode) { - $this->init(); - switch($mode) { + $path = $this->normalizePath($path); + + switch ($mode) { case 'r': case 'rb': - $obj=$this->getObject($path); - if (is_null($obj)) { + $tmpFile = \OC_Helper::tmpFile(); + self::$tmpFiles[$tmpFile] = $path; + try { + $object = $this->container->DataObject($path); + } catch (Exceptions\ObjFetchError $e) { + \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR); return false; } - $fp = fopen('php://temp', 'r+'); - $obj->stream($fp); - - rewind($fp); - return $fp; + try { + $object->SaveToFilename($tmpFile); + } catch (Exceptions\IOError $e) { + \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR); + return false; + } + return fopen($tmpFile, 'r'); case 'w': case 'wb': case 'a': @@ -469,119 +318,166 @@ class SWIFT extends \OC\Files\Storage\Common{ case 'x+': case 'c': case 'c+': - $tmpFile=$this->getTmpFile($path); + if (strrpos($path, '.') !== false) { + $ext = substr($path, strrpos($path, '.')); + } else { + $ext = ''; + } + $tmpFile = \OC_Helper::tmpFile($ext); \OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack')); - self::$tempFiles[$tmpFile]=$path; - return fopen('close://'.$tmpFile, $mode); + if ($this->file_exists($path)) { + $source = $this->fopen($path, 'r'); + file_put_contents($tmpFile, $source); + } + self::$tmpFiles[$tmpFile] = $path; + + return fopen('close://' . $tmpFile, $mode); } } - public function writeBack($tmpFile) { - if (isset(self::$tempFiles[$tmpFile])) { - $this->fromTmpFile($tmpFile, self::$tempFiles[$tmpFile]); - unlink($tmpFile); + public function getMimeType($path) { + $path = $this->normalizePath($path); + + if ($this->is_dir($path)) { + return 'httpd/unix-directory'; + } else if ($this->file_exists($path)) { + $object = $this->container->DataObject($path); + return $object->extra_headers["Content-Type"]; } + return false; } - public function touch($path, $mtime=null) { - $this->init(); - $obj=$this->getObject($path); - if (is_null($obj)) { - return false; + public function touch($path, $mtime = null) { + $path = $this->normalizePath($path); + if ($this->file_exists($path)) { + if ($this->is_dir($path) && $path != '.') { + $path .= '/'; + } + + $object = $this->container->DataObject($path); + if( is_null($mtime)) { + $mtime = time(); + } + $settings = array( + 'name' => $path, + 'extra_headers' => array( + 'X-Object-Meta-Timestamp' => $mtime + ) + ); + return $object->Update($settings); + } else { + $object = $this->container->DataObject(); + if (is_null($mtime)) { + $mtime = time(); + } + $settings = array( + 'name' => $path, + 'content_type' => 'text/plain', + 'extra_headers' => array( + 'X-Object-Meta-Timestamp' => $mtime + ) + ); + return $object->Create($settings); } - if (is_null($mtime)) { - $mtime=time(); + } + + public function copy($path1, $path2) { + $path1 = $this->normalizePath($path1); + $path2 = $this->normalizePath($path2); + + if ($this->is_file($path1)) { + try { + $source = $this->container->DataObject($path1); + $target = $this->container->DataObject(); + $target->Create(array( + 'name' => $path2, + )); + $source->Copy($target); + } catch (Exceptions\ObjectCopyError $e) { + \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR); + return false; + } + } else { + if ($this->file_exists($path2)) { + return false; + } + + try { + $source = $this->container->DataObject($path1 . '/'); + $target = $this->container->DataObject(); + $target->Create(array( + 'name' => $path2 . '/', + )); + $source->Copy($target); + } catch (Exceptions\ObjectCopyError $e) { + \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR); + return false; + } + + $dh = $this->opendir($path1); + while ($file = readdir($dh)) { + if ($file === '.' || $file === '..') { + continue; + } + + $source = $path1 . '/' . $file; + $target = $path2 . '/' . $file; + $this->copy($source, $target); + } } - //emulate setting mtime with metadata - $obj->metadata['Mtime']=$mtime; - $obj->sync_metadata(); + return true; } public function rename($path1, $path2) { - $this->init(); - $sourceContainer=$this->getContainer(dirname($path1)); - $targetContainer=$this->getContainer(dirname($path2)); - $result=$sourceContainer->move_object_to(basename($path1), $targetContainer, basename($path2)); - unset($this->objects[$path1]); - if ($result) { - $targetObj=$this->getObject($path2); - $this->resetMTime($targetObj); - } - return $result; - } + $path1 = $this->normalizePath($path1); + $path2 = $this->normalizePath($path2); - public function copy($path1, $path2) { - $this->init(); - $sourceContainer=$this->getContainer(dirname($path1)); - $targetContainer=$this->getContainer(dirname($path2)); - $result=$sourceContainer->copy_object_to(basename($path1), $targetContainer, basename($path2)); - if ($result) { - $targetObj=$this->getObject($path2); - $this->resetMTime($targetObj); - } - return $result; - } + if ($this->is_file($path1)) { + if ($this->copy($path1, $path2) === false) { + return false; + } - public function stat($path) { - $this->init(); - $container=$this->getContainer($path); - if ( ! is_null($container)) { - return array( - 'mtime'=>-1, - 'size'=>$container->bytes_used, - 'ctime'=>-1 - ); - } + if ($this->unlink($path1) === false) { + $this->unlink($path2); + return false; + } + } else { + if ($this->file_exists($path2)) { + return false; + } - $obj=$this->getObject($path); + if ($this->copy($path1, $path2) === false) { + return false; + } - if (is_null($obj)) { - return false; + if ($this->rmdir($path1) === false) { + $this->rmdir($path2); + return false; + } } - if (isset($obj->metadata['Mtime']) and $obj->metadata['Mtime']>-1) { - $mtime=$obj->metadata['Mtime']; - } else { - $mtime=strtotime($obj->last_modified); - } - return array( - 'mtime'=>$mtime, - 'size'=>$obj->content_length, - 'ctime'=>-1, - ); + return true; } - private function getTmpFile($path) { - $this->init(); - $obj=$this->getObject($path); - if ( ! is_null($obj)) { - $tmpFile=\OCP\Files::tmpFile(); - $obj->save_to_filename($tmpFile); - return $tmpFile; - } else { - return \OCP\Files::tmpFile(); - } + public function getId() { + return $this->id; } - private function fromTmpFile($tmpFile, $path) { - $this->init(); - $obj=$this->getObject($path); - if (is_null($obj)) { - $obj=$this->createObject($path); - } - $obj->load_from_filename($tmpFile); - $this->resetMTime($obj); + public function getConnection() { + return $this->connection; } - /** - * remove custom mtime metadata - * @param \CF_Object $obj - */ - private function resetMTime($obj) { - if (isset($obj->metadata['Mtime'])) { - $obj->metadata['Mtime']=-1; - $obj->sync_metadata(); + public function writeBack($tmpFile) { + if (!isset(self::$tmpFiles[$tmpFile])) { + return false; } + + $object = $this->container->DataObject(); + $object->Create(array( + 'name' => self::$tmpFiles[$tmpFile], + 'content_type' => \OC_Helper::getMimeType($tmpFile) + ), $tmpFile); + unlink($tmpFile); } } diff --git a/apps/files_external/lib/webdav.php b/apps/files_external/lib/webdav.php index 66920fc9f64..0f8034e57d9 100644 --- a/apps/files_external/lib/webdav.php +++ b/apps/files_external/lib/webdav.php @@ -14,6 +14,7 @@ class DAV extends \OC\Files\Storage\Common{ private $host; private $secure; private $root; + private $certPath; private $ready; /** * @var \Sabre_DAV_Client @@ -40,6 +41,12 @@ class DAV extends \OC\Files\Storage\Common{ } else { $this->secure = false; } + if ($this->secure === true) { + $certPath=\OC_User::getHome(\OC_User::getUser()) . '/files_external/rootcerts.crt'; + if (file_exists($certPath)) { + $this->certPath=$certPath; + } + } $this->root=isset($params['root'])?$params['root']:'/'; if ( ! $this->root || $this->root[0]!='/') { $this->root='/'.$this->root; @@ -58,20 +65,16 @@ class DAV extends \OC\Files\Storage\Common{ } $this->ready = true; - $settings = array( - 'baseUri' => $this->createBaseUri(), - 'userName' => $this->user, - 'password' => $this->password, - ); + $settings = array( + 'baseUri' => $this->createBaseUri(), + 'userName' => $this->user, + 'password' => $this->password, + ); $this->client = new \Sabre_DAV_Client($settings); - $caview = \OCP\Files::getStorage('files_external'); - if ($caview) { - $certPath=\OCP\Config::getSystemValue('datadirectory').$caview->getAbsolutePath("").'rootcerts.crt'; - if (file_exists($certPath)) { - $this->client->addTrustedCertificates($certPath); - } + if ($this->secure === true && $this->certPath) { + $this->client->addTrustedCertificates($this->certPath); } } @@ -79,7 +82,7 @@ class DAV extends \OC\Files\Storage\Common{ return 'webdav::' . $this->user . '@' . $this->host . '/' . $this->root; } - private function createBaseUri() { + protected function createBaseUri() { $baseUri='http'; if ($this->secure) { $baseUri.='s'; @@ -134,14 +137,6 @@ class DAV extends \OC\Files\Storage\Common{ } } - public function isReadable($path) { - return true;//not properly supported - } - - public function isUpdatable($path) { - return true;//not properly supported - } - public function file_exists($path) { $this->init(); $path=$this->cleanPath($path); @@ -174,7 +169,14 @@ class DAV extends \OC\Files\Storage\Common{ curl_setopt($curl, CURLOPT_URL, $this->createBaseUri().str_replace(' ', '%20', $path)); curl_setopt($curl, CURLOPT_FILE, $fp); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); - + if ($this->secure === true) { + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); + if($this->certPath){ + curl_setopt($curl, CURLOPT_CAINFO, $this->certPath); + } + } + curl_exec ($curl); curl_close ($curl); rewind($fp); @@ -242,6 +244,7 @@ class DAV extends \OC\Files\Storage\Common{ } else { $this->file_put_contents($path, ''); } + return true; } public function getFile($path, $target) { @@ -261,6 +264,13 @@ class DAV extends \OC\Files\Storage\Common{ curl_setopt($curl, CURLOPT_INFILE, $source); // file pointer curl_setopt($curl, CURLOPT_INFILESIZE, filesize($path)); curl_setopt($curl, CURLOPT_PUT, true); + if ($this->secure === true) { + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); + if($this->certPath){ + curl_setopt($curl, CURLOPT_CAINFO, $this->certPath); + } + } curl_exec ($curl); curl_close ($curl); } @@ -268,7 +278,7 @@ class DAV extends \OC\Files\Storage\Common{ public function rename($path1, $path2) { $this->init(); $path1=$this->cleanPath($path1); - $path2=$this->root.$this->cleanPath($path2); + $path2=$this->createBaseUri().$this->cleanPath($path2); try { $this->client->request('MOVE', $path1, null, array('Destination'=>$path2)); return true; @@ -280,7 +290,7 @@ class DAV extends \OC\Files\Storage\Common{ public function copy($path1, $path2) { $this->init(); $path1=$this->cleanPath($path1); - $path2=$this->root.$this->cleanPath($path2); + $path2=$this->createBaseUri().$this->cleanPath($path2); try { $this->client->request('COPY', $path1, null, array('Destination'=>$path2)); return true; @@ -323,11 +333,9 @@ class DAV extends \OC\Files\Storage\Common{ } public function cleanPath($path) { - if ( ! $path || $path[0]=='/') { - return substr($path, 1); - } else { - return $path; - } + $path = \OC\Files\Filesystem::normalizePath($path); + // remove leading slash + return substr($path, 1); } private function simpleResponse($method, $path, $body, $expected) { @@ -340,3 +348,4 @@ class DAV extends \OC\Files\Storage\Common{ } } } + diff --git a/apps/files_external/templates/settings.php b/apps/files_external/templates/settings.php index 028a384cf34..3ca16c3c7a8 100644 --- a/apps/files_external/templates/settings.php +++ b/apps/files_external/templates/settings.php @@ -2,7 +2,7 @@ <fieldset class="personalblock"> <h2><?php p($l->t('External Storage')); ?></h2> <?php if (isset($_['dependencies']) and ($_['dependencies']<>'')) print_unescaped(''.$_['dependencies'].''); ?> - <table id="externalStorage" data-admin='<?php print_unescaped(json_encode($_['isAdminPage'])); ?>'> + <table id="externalStorage" class="grid" data-admin='<?php print_unescaped(json_encode($_['isAdminPage'])); ?>'> <thead> <tr> <th></th> @@ -60,7 +60,7 @@ class="optional" data-parameter="<?php p($parameter); ?>" value="<?php p($value); ?>" - placeholder="<?php p(substr($placeholder, 5)); ?>" /> + placeholder="<?php p(substr($placeholder, 1)); ?>" /> <?php elseif (strpos($placeholder, '#') !== false): ?> <input type="hidden" data-parameter="<?php p($parameter); ?>" diff --git a/apps/files_external/tests/config.php b/apps/files_external/tests/config.php index d4a69d29c0f..e296bfcb5b2 100644 --- a/apps/files_external/tests/config.php +++ b/apps/files_external/tests/config.php @@ -23,6 +23,13 @@ return array( 'password'=>'test', 'root'=>'/owncloud/files/webdav.php', ), + 'owncloud'=>array( + 'run'=>true, + 'host'=>'localhost/owncloud', + 'user'=>'test', + 'password'=>'test', + 'root'=>'', + ), 'google'=>array( 'run'=> false, 'configured' => 'true', @@ -30,12 +37,17 @@ return array( 'client_secret' => '', 'token' => '', ), - 'swift'=>array( - 'run'=>false, - 'user'=>'test:tester', - 'token'=>'testing', - 'host'=>'localhost.local:8080/auth', - 'root'=>'/', + 'swift' => array( + 'run' => false, + 'user' => 'test', + 'bucket' => 'test', + 'region' => 'DFW', + 'key' => 'test', //to be used only with Rackspace Cloud Files + //'tenant' => 'test', //to be used only with OpenStack Object Storage + //'password' => 'test', //to be use only with OpenStack Object Storage + //'service_name' => 'swift', //should be 'swift' for OpenStack Object Storage and 'cloudFiles' for Rackspace Cloud Files (default value) + //'url' => 'https://identity.api.rackspacecloud.com/v2.0/', //to be used with Rackspace Cloud Files and OpenStack Object Storage + //'timeout' => 5 // timeout of HTTP requests in seconds ), 'smb'=>array( 'run'=>false, diff --git a/apps/files_external/tests/dropbox.php b/apps/files_external/tests/dropbox.php index e4e598b06b0..4b052282019 100644 --- a/apps/files_external/tests/dropbox.php +++ b/apps/files_external/tests/dropbox.php @@ -21,6 +21,22 @@ class Dropbox extends Storage { $this->instance = new \OC\Files\Storage\Dropbox($this->config['dropbox']); } + public function directoryProvider() { + // doesn't support leading/trailing spaces + return array(array('folder')); + } + + public function testDropboxTouchReturnValue() { + $this->assertFalse($this->instance->file_exists('foo')); + + // true because succeeded + $this->assertTrue($this->instance->touch('foo')); + $this->assertTrue($this->instance->file_exists('foo')); + + // false because not supported + $this->assertFalse($this->instance->touch('foo')); + } + public function tearDown() { if ($this->instance) { $this->instance->unlink('/'); diff --git a/apps/files_external/tests/ftp.php b/apps/files_external/tests/ftp.php index e146725473a..3037793120a 100644 --- a/apps/files_external/tests/ftp.php +++ b/apps/files_external/tests/ftp.php @@ -34,19 +34,31 @@ class FTP extends Storage { 'password' => 'ftp', 'root' => '/', 'secure' => false ); - $instance = new OC_Filestorage_FTP($config); + $instance = new \OC\Files\Storage\FTP($config); $this->assertEquals('ftp://ftp:ftp@localhost/', $instance->constructUrl('')); $config['secure'] = true; - $instance = new OC_Filestorage_FTP($config); + $instance = new \OC\Files\Storage\FTP($config); $this->assertEquals('ftps://ftp:ftp@localhost/', $instance->constructUrl('')); $config['secure'] = 'false'; - $instance = new OC_Filestorage_FTP($config); + $instance = new \OC\Files\Storage\FTP($config); $this->assertEquals('ftp://ftp:ftp@localhost/', $instance->constructUrl('')); $config['secure'] = 'true'; - $instance = new OC_Filestorage_FTP($config); + $instance = new \OC\Files\Storage\FTP($config); $this->assertEquals('ftps://ftp:ftp@localhost/', $instance->constructUrl('')); + + $config['root'] = ''; + $instance = new \OC\Files\Storage\FTP($config); + $this->assertEquals('ftps://ftp:ftp@localhost/somefile.txt', $instance->constructUrl('somefile.txt')); + + $config['root'] = '/abc'; + $instance = new \OC\Files\Storage\FTP($config); + $this->assertEquals('ftps://ftp:ftp@localhost/abc/somefile.txt', $instance->constructUrl('somefile.txt')); + + $config['root'] = '/abc/'; + $instance = new \OC\Files\Storage\FTP($config); + $this->assertEquals('ftps://ftp:ftp@localhost/abc/somefile.txt', $instance->constructUrl('somefile.txt')); } } diff --git a/apps/files_external/tests/mountconfig.php b/apps/files_external/tests/mountconfig.php new file mode 100644 index 00000000000..941aec680bb --- /dev/null +++ b/apps/files_external/tests/mountconfig.php @@ -0,0 +1,51 @@ +<?php +/** + * ownCloud + * + * @author Vincent Petry + * Copyright (c) 2013 Vincent Petry <pvince81@owncloud.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library 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 along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +require_once __DIR__ . '/../../../lib/base.php'; + +require __DIR__ . '/../lib/config.php'; + +class Test_Mount_Config_Dummy_Storage { + public function test() { + return true; + } +} + +/** + * Class Test_Mount_Config + */ +class Test_Mount_Config extends \PHPUnit_Framework_TestCase { + /** + * Test mount point validation + */ + public function testAddMountPointValidation() { + $storageClass = 'Test_Mount_Config_Dummy_Storage'; + $mountType = 'user'; + $applicable = 'all'; + $isPersonal = false; + $this->assertEquals(false, OC_Mount_Config::addMountPoint('', $storageClass, array(), $mountType, $applicable, $isPersonal)); + $this->assertEquals(false, OC_Mount_Config::addMountPoint('/', $storageClass, array(), $mountType, $applicable, $isPersonal)); + $this->assertEquals(false, OC_Mount_Config::addMountPoint('Shared', $storageClass, array(), $mountType, $applicable, $isPersonal)); + $this->assertEquals(false, OC_Mount_Config::addMountPoint('/Shared', $storageClass, array(), $mountType, $applicable, $isPersonal)); + + } +} diff --git a/apps/files_external/tests/owncloud.php b/apps/files_external/tests/owncloud.php new file mode 100644 index 00000000000..408a55864f2 --- /dev/null +++ b/apps/files_external/tests/owncloud.php @@ -0,0 +1,31 @@ +<?php +/** + * Copyright (c) 2013 Vincent Petry <pvince81@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace Test\Files\Storage; + +class OwnCloud extends Storage { + + private $config; + + public function setUp() { + $id = uniqid(); + $this->config = include('files_external/tests/config.php'); + if ( ! is_array($this->config) or ! isset($this->config['owncloud']) or ! $this->config['owncloud']['run']) { + $this->markTestSkipped('ownCloud backend not configured'); + } + $this->config['owncloud']['root'] .= '/' . $id; //make sure we have an new empty folder to work in + $this->instance = new \OC\Files\Storage\OwnCloud($this->config['owncloud']); + $this->instance->mkdir('/'); + } + + public function tearDown() { + if ($this->instance) { + $this->instance->rmdir('/'); + } + } +} diff --git a/apps/files_external/tests/smb.php b/apps/files_external/tests/smb.php index ca2a93c8944..199e35af676 100644 --- a/apps/files_external/tests/smb.php +++ b/apps/files_external/tests/smb.php @@ -15,7 +15,7 @@ class SMB extends Storage { public function setUp() { $id = uniqid(); $this->config = include('files_external/tests/config.php'); - if ( ! is_array($this->config) or ! isset($this->config['smb']) or ! $this->config['smb']['run']) { + if (!is_array($this->config) or !isset($this->config['smb']) or !$this->config['smb']['run']) { $this->markTestSkipped('Samba backend not configured'); } $this->config['smb']['root'] .= $id; //make sure we have an new empty folder to work in @@ -28,4 +28,16 @@ class SMB extends Storage { \OCP\Files::rmdirr($this->instance->constructUrl('')); } } + + public function directoryProvider() { + // doesn't support leading/trailing spaces + return array(array('folder')); + } + + public function testRenameWithSpaces() { + $this->instance->mkdir('with spaces'); + $result = $this->instance->rename('with spaces', 'foo bar'); + $this->assertTrue($result); + $this->assertTrue($this->instance->is_dir('foo bar')); + } } diff --git a/apps/files_external/tests/smbfunctions.php b/apps/files_external/tests/smbfunctions.php new file mode 100644 index 00000000000..749906d0136 --- /dev/null +++ b/apps/files_external/tests/smbfunctions.php @@ -0,0 +1,41 @@ +<?php +/** + * Copyright (c) 2013 Vincent Petry <pvince81@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace Test\Files\Storage; + +class SMBFunctions extends \PHPUnit_Framework_TestCase { + + public function setUp() { + $id = uniqid(); + // dummy config + $this->config = array( + 'run'=>false, + 'user'=>'test', + 'password'=>'testpassword', + 'host'=>'smbhost', + 'share'=>'/sharename', + 'root'=>'/rootdir/', + ); + + $this->instance = new \OC\Files\Storage\SMB($this->config); + } + + public function tearDown() { + } + + public function testGetId() { + $this->assertEquals('smb::test@smbhost//sharename//rootdir/', $this->instance->getId()); + } + + public function testConstructUrl() { + $this->assertEquals("smb://test:testpassword@smbhost/sharename/rootdir/abc", $this->instance->constructUrl('/abc')); + $this->assertEquals("smb://test:testpassword@smbhost/sharename/rootdir/abc", $this->instance->constructUrl('/abc/')); + $this->assertEquals("smb://test:testpassword@smbhost/sharename/rootdir/abc%2F", $this->instance->constructUrl('/abc/.')); + $this->assertEquals("smb://test:testpassword@smbhost/sharename/rootdir/abc%2Fdef", $this->instance->constructUrl('/abc/def')); + } +} diff --git a/apps/files_external/tests/swift.php b/apps/files_external/tests/swift.php index 5c782840246..bdfdbdeebe9 100644 --- a/apps/files_external/tests/swift.php +++ b/apps/files_external/tests/swift.php @@ -1,30 +1,51 @@ <?php + /** - * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com> - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. + * ownCloud + * + * @author Christian Berendt + * @copyright 2013 Christian Berendt berendt@b1-systems.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library 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 along with this library. If not, see <http://www.gnu.org/licenses/>. */ namespace Test\Files\Storage; -class SWIFT extends Storage { +class Swift extends Storage { + private $config; public function setUp() { - $id = uniqid(); $this->config = include('files_external/tests/config.php'); - if ( ! is_array($this->config) or ! isset($this->config['swift']) or ! $this->config['swift']['run']) { - $this->markTestSkipped('OpenStack SWIFT backend not configured'); + if (!is_array($this->config) or !isset($this->config['swift']) + or !$this->config['swift']['run']) { + $this->markTestSkipped('OpenStack Object Storage backend not configured'); } - $this->config['swift']['root'] .= '/' . $id; //make sure we have an new empty folder to work in - $this->instance = new \OC\Files\Storage\SWIFT($this->config['swift']); + $this->instance = new \OC\Files\Storage\Swift($this->config['swift']); } - public function tearDown() { if ($this->instance) { - $this->instance->rmdir(''); + $connection = $this->instance->getConnection(); + $container = $connection->Container($this->config['swift']['bucket']); + + $objects = $container->ObjectList(); + while($object = $objects->Next()) { + $object->Delete(); + } + + $container->Delete(); } } } diff --git a/apps/files_sharing/ajax/publicpreview.php b/apps/files_sharing/ajax/publicpreview.php index 41a1c178a48..54a9806e8bf 100644 --- a/apps/files_sharing/ajax/publicpreview.php +++ b/apps/files_sharing/ajax/publicpreview.php @@ -9,6 +9,8 @@ if(!\OC_App::isEnabled('files_sharing')){ exit; } +\OC_User::setIncognitoMode(true); + $file = array_key_exists('file', $_GET) ? (string) urldecode($_GET['file']) : ''; $maxX = array_key_exists('x', $_GET) ? (int) $_GET['x'] : '36'; $maxY = array_key_exists('y', $_GET) ? (int) $_GET['y'] : '36'; @@ -34,12 +36,16 @@ if(!isset($linkedItem['uid_owner']) || !isset($linkedItem['file_source'])) { exit; } -$userId = $linkedItem['uid_owner']; +$rootLinkItem = OCP\Share::resolveReShare($linkedItem); +$userId = $rootLinkItem['uid_owner']; + \OC_Util::setupFS($userId); +\OC\Files\Filesystem::initMountPoints($userId); +$view = new \OC\Files\View('/' . $userId . '/files'); $pathId = $linkedItem['file_source']; -$path = \OC\Files\Filesystem::getPath($pathId); -$pathInfo = \OC\Files\Filesystem::getFileInfo($path); +$path = $view->getPath($pathId); +$pathInfo = $view->getFileInfo($path); $sharedFile = null; if($linkedItem['item_type'] === 'folder') { @@ -54,7 +60,7 @@ if($linkedItem['item_type'] === 'folder') { if($linkedItem['item_type'] === 'file') { $parent = $pathInfo['parent']; - $path = \OC\Files\Filesystem::getPath($parent); + $path = $view->getPath($parent); $sharedFile = $pathInfo['name']; } diff --git a/apps/files_sharing/appinfo/app.php b/apps/files_sharing/appinfo/app.php index ffdcbf05109..217bc005faf 100644 --- a/apps/files_sharing/appinfo/app.php +++ b/apps/files_sharing/appinfo/app.php @@ -8,12 +8,15 @@ OC::$CLASSPATH['OC\Files\Cache\Shared_Permissions'] = 'files_sharing/lib/permiss OC::$CLASSPATH['OC\Files\Cache\Shared_Updater'] = 'files_sharing/lib/updater.php'; OC::$CLASSPATH['OC\Files\Cache\Shared_Watcher'] = 'files_sharing/lib/watcher.php'; OC::$CLASSPATH['OCA\Files\Share\Api'] = 'files_sharing/lib/api.php'; +OC::$CLASSPATH['OCA\Files\Share\Maintainer'] = 'files_sharing/lib/maintainer.php'; OCP\Util::connectHook('OC_Filesystem', 'setup', '\OC\Files\Storage\Shared', 'setup'); OCP\Share::registerBackend('file', 'OC_Share_Backend_File'); OCP\Share::registerBackend('folder', 'OC_Share_Backend_Folder', 'file'); OCP\Util::addScript('files_sharing', 'share'); \OC_Hook::connect('OC_Filesystem', 'post_write', '\OC\Files\Cache\Shared_Updater', 'writeHook'); +\OC_Hook::connect('OC_Filesystem', 'post_delete', '\OC\Files\Cache\Shared_Updater', 'postDeleteHook'); \OC_Hook::connect('OC_Filesystem', 'delete', '\OC\Files\Cache\Shared_Updater', 'deleteHook'); \OC_Hook::connect('OC_Filesystem', 'post_rename', '\OC\Files\Cache\Shared_Updater', 'renameHook'); \OC_Hook::connect('OCP\Share', 'post_shared', '\OC\Files\Cache\Shared_Updater', 'shareHook'); \OC_Hook::connect('OCP\Share', 'pre_unshare', '\OC\Files\Cache\Shared_Updater', 'shareHook'); +\OC_Hook::connect('OC_Appconfig', 'post_set_value', '\OCA\Files\Share\Maintainer', 'configChangeHook'); diff --git a/apps/files_sharing/appinfo/update.php b/apps/files_sharing/appinfo/update.php index 48e41e93048..0d827da28ea 100644 --- a/apps/files_sharing/appinfo/update.php +++ b/apps/files_sharing/appinfo/update.php @@ -68,11 +68,21 @@ if (version_compare($installedVersion, '0.3', '<')) { // $query = OCP\DB::prepare('DROP TABLE `*PREFIX*sharing`'); // $query->execute(); } -if (version_compare($installedVersion, '0.3.3', '<')) { - OC_User::useBackend(new OC_User_Database()); - OC_App::loadApps(array('authentication')); - $users = OC_User::getUsers(); - foreach ($users as $user) { -// OC_FileCache::delete('Shared', '/'.$user.'/files/'); + +// clean up oc_share table from files which are no longer exists +if (version_compare($installedVersion, '0.3.5', '<')) { + + // get all shares where the original file no longer exists + $findShares = \OC_DB::prepare('SELECT `file_source` FROM `*PREFIX*share` LEFT JOIN `*PREFIX*filecache` ON `file_source` = `*PREFIX*filecache`.`fileid` WHERE `*PREFIX*filecache`.`fileid` IS NULL AND `*PREFIX*share`.`item_type` IN (\'file\', \'folder\')'); + $sharesFound = $findShares->execute(array())->fetchAll(); + + // delete those shares from the oc_share table + if (is_array($sharesFound) && !empty($sharesFound)) { + $delArray = array(); + foreach ($sharesFound as $share) { + $delArray[] = $share['file_source']; + } + $removeShares = \OC_DB::prepare('DELETE FROM `*PREFIX*share` WHERE `file_source` IN (?)'); + $result = $removeShares->execute(array(implode(',', $delArray))); } } diff --git a/apps/files_sharing/appinfo/version b/apps/files_sharing/appinfo/version index 87a0871112f..09e9157034c 100644 --- a/apps/files_sharing/appinfo/version +++ b/apps/files_sharing/appinfo/version @@ -1 +1 @@ -0.3.3
\ No newline at end of file +0.3.5
\ No newline at end of file diff --git a/apps/files_sharing/css/authenticate.css b/apps/files_sharing/css/authenticate.css new file mode 100644 index 00000000000..cebe906dd59 --- /dev/null +++ b/apps/files_sharing/css/authenticate.css @@ -0,0 +1,26 @@ +#body-login form label.infield { + width: 190px; + padding: 10px; + left: 8px; + top: 8px; +} + +#password { + width: 190px !important; + padding: 10px; + margin: 6px; +} + +input[type="submit"]{ + width: 45px; + height: 45px; + margin: 6px; + background-image: url('%webroot%/core/img/actions/confirm.svg'); + background-repeat: no-repeat; + background-position: center; +} + +#body-login input[type="submit"] { + position: absolute; + top: 0px; +} diff --git a/apps/files_sharing/css/public.css b/apps/files_sharing/css/public.css index 70345c3577d..e948811c032 100644 --- a/apps/files_sharing/css/public.css +++ b/apps/files_sharing/css/public.css @@ -1,17 +1,17 @@ body { - background:#ddd; + height: auto; } #header { background: #1d2d44 url('%webroot%/core/img/noise.png') repeat; - height:40px; + height:32px; left:0; - line-height:40px; + line-height:32px; position:fixed; right:0; top:0; z-index:100; - padding:8px; + padding:7px; } #details { @@ -22,15 +22,20 @@ body { #public_upload, #download { font-weight:700; - margin: 0 6px 0 0; + margin: 0 0 0 6px; padding: 0 5px; - height: 27px; + height: 32px; float: left; } .header-right #details { - margin-right: 32px; + margin-right: 28px; +} + +.header-right { + padding: 0; + height: 32px; } #public_upload { @@ -44,12 +49,14 @@ body { vertical-align:text-bottom; } +#controls { + left: 0; +} + #preview { - background:#eee; - border-bottom:1px solid #f8f8f8; - min-height:480px; - text-align:center; - margin:45px auto; + background: #fff; + text-align: center; + margin: 45px auto 0; } #noPreview { @@ -57,11 +64,16 @@ body { padding-top:90px; } +footer { + margin-top: 65px; +} + p.info { - color:#777; - text-align:center; - width:352px; - margin:32px auto; + color: #777; + text-align: center; + width: 352px; + margin: 0 auto; + padding: 20px; } p.info a { @@ -90,7 +102,7 @@ thead{ #data-upload-form { position: relative; right: 0; - height: 27px; + height: 32px; overflow: hidden; padding: 0; float: right; @@ -109,26 +121,30 @@ thead{ width: 100% !important; } -#download span { - position: relative; - bottom: 3px; -} - #publicUploadButtonMock { position:relative; display:block; width:100%; - height:27px; + height:32px; cursor:pointer; z-index:10; background-image:url('%webroot%/core/img/actions/upload.svg'); background-repeat:no-repeat; - background-position:7px 6px; + background-position:7px 8px; } #publicUploadButtonMock span { margin: 0 5px 0 28px; - position: relative; - top: -2px; color: #555; } + +.directLink { + margin-bottom: 20px; +} + .directLink label { + font-weight: normal; + } + .directLink input { + margin-left: 10px; + width: 300px; + } diff --git a/apps/files_sharing/js/public.js b/apps/files_sharing/js/public.js index 67320b1cdb6..2e34e6f9bc5 100644 --- a/apps/files_sharing/js/public.js +++ b/apps/files_sharing/js/public.js @@ -29,19 +29,19 @@ $(document).ready(function() { } } FileActions.register('dir', 'Open', OC.PERMISSION_READ, '', function(filename) { - var tr = $('tr').filterAttr('data-file', filename); + var tr = FileList.findFileEl(filename); if (tr.length > 0) { window.location = $(tr).find('a.name').attr('href'); } }); FileActions.register('file', 'Download', OC.PERMISSION_READ, '', function(filename) { - var tr = $('tr').filterAttr('data-file', filename); + var tr = FileList.findFileEl(filename); if (tr.length > 0) { window.location = $(tr).find('a.name').attr('href'); } }); FileActions.register('dir', 'Download', OC.PERMISSION_READ, '', function(filename) { - var tr = $('tr').filterAttr('data-file', filename); + var tr = FileList.findFileEl(filename); if (tr.length > 0) { window.location = $(tr).find('a.name').attr('href')+'&download'; } @@ -67,4 +67,6 @@ $(document).ready(function() { procesSelection(); }); + $('#directLink').focus(); + }); diff --git a/apps/files_sharing/js/share.js b/apps/files_sharing/js/share.js index 03ed02f41ef..36de452a55e 100644 --- a/apps/files_sharing/js/share.js +++ b/apps/files_sharing/js/share.js @@ -1,11 +1,19 @@ $(document).ready(function() { - var disableSharing = $('#disableSharing').data('status'); + var disableSharing = $('#disableSharing').data('status'), + sharesLoaded = false; if (typeof OC.Share !== 'undefined' && typeof FileActions !== 'undefined' && !disableSharing) { - $('#fileList').on('fileActionsReady',function(){ - OC.Share.loadIcons('file'); + if (!sharesLoaded){ + OC.Share.loadIcons('file'); + // assume that we got all shares, so switching directories + // will not invalidate that list + sharesLoaded = true; + } + else{ + OC.Share.updateIcons('file'); + } }); FileActions.register('all', 'Share', OC.PERMISSION_READ, OC.imagePath('core', 'actions/share'), function(filename) { @@ -14,7 +22,7 @@ $(document).ready(function() { } else { var item = $('#dir').val() + '/' + filename; } - var tr = $('tr').filterAttr('data-file', filename); + var tr = FileList.findFileEl(filename); if ($(tr).data('type') == 'dir') { var itemType = 'folder'; } else { @@ -27,14 +35,14 @@ $(document).ready(function() { if ($(tr).data('id') != $('#dropdown').attr('data-item-source')) { OC.Share.hideDropDown(function () { $(tr).addClass('mouseOver'); - OC.Share.showDropDown(itemType, $(tr).data('id'), appendTo, true, possiblePermissions); + OC.Share.showDropDown(itemType, $(tr).data('id'), appendTo, true, possiblePermissions, filename); }); } else { OC.Share.hideDropDown(); } } else { $(tr).addClass('mouseOver'); - OC.Share.showDropDown(itemType, $(tr).data('id'), appendTo, true, possiblePermissions); + OC.Share.showDropDown(itemType, $(tr).data('id'), appendTo, true, possiblePermissions, filename); } }); } diff --git a/apps/files_sharing/l10n/ar.php b/apps/files_sharing/l10n/ar.php index ff7b40d16bc..2625af1cc00 100644 --- a/apps/files_sharing/l10n/ar.php +++ b/apps/files_sharing/l10n/ar.php @@ -1,7 +1,6 @@ <?php $TRANSLATIONS = array( "Password" => "كلمة المرور", -"Submit" => "تطبيق", "%s shared the folder %s with you" => "%s شارك المجلد %s معك", "%s shared the file %s with you" => "%s شارك الملف %s معك", "Download" => "تحميل", diff --git a/apps/files_sharing/l10n/bg_BG.php b/apps/files_sharing/l10n/bg_BG.php index 1094870fd0f..f4b9e2dd5fc 100644 --- a/apps/files_sharing/l10n/bg_BG.php +++ b/apps/files_sharing/l10n/bg_BG.php @@ -1,7 +1,6 @@ <?php $TRANSLATIONS = array( "Password" => "Парола", -"Submit" => "Потвърждение", "%s shared the folder %s with you" => "%s сподели папката %s с Вас", "%s shared the file %s with you" => "%s сподели файла %s с Вас", "Download" => "Изтегляне", diff --git a/apps/files_sharing/l10n/bn_BD.php b/apps/files_sharing/l10n/bn_BD.php index 71b948e347b..aaed904d9d7 100644 --- a/apps/files_sharing/l10n/bn_BD.php +++ b/apps/files_sharing/l10n/bn_BD.php @@ -1,7 +1,6 @@ <?php $TRANSLATIONS = array( "Password" => "কূটশব্দ", -"Submit" => "জমা দিন", "%s shared the folder %s with you" => "%s আপনার সাথে %s ফোল্ডারটি ভাগাভাগি করেছেন", "%s shared the file %s with you" => "%s আপনার সাথে %s ফাইলটি ভাগাভাগি করেছেন", "Download" => "ডাউনলোড", diff --git a/apps/files_sharing/l10n/ca.php b/apps/files_sharing/l10n/ca.php index cbe8f86e253..96e59992967 100644 --- a/apps/files_sharing/l10n/ca.php +++ b/apps/files_sharing/l10n/ca.php @@ -1,8 +1,8 @@ <?php $TRANSLATIONS = array( +"This share is password-protected" => "Aquest compartit està protegit amb contrasenya", "The password is wrong. Try again." => "la contrasenya és incorrecta. Intenteu-ho de nou.", "Password" => "Contrasenya", -"Submit" => "Envia", "Sorry, this link doesn’t seem to work anymore." => "Aquest enllaç sembla que no funciona.", "Reasons might be:" => "Les raons podrien ser:", "the item was removed" => "l'element ha estat eliminat", @@ -14,6 +14,7 @@ $TRANSLATIONS = array( "Download" => "Baixa", "Upload" => "Puja", "Cancel upload" => "Cancel·la la pujada", -"No preview available for" => "No hi ha vista prèvia disponible per a" +"No preview available for" => "No hi ha vista prèvia disponible per a", +"Direct link" => "Enllaç directe" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_sharing/l10n/cs_CZ.php b/apps/files_sharing/l10n/cs_CZ.php index 7258dedcf6d..adf099a6d94 100644 --- a/apps/files_sharing/l10n/cs_CZ.php +++ b/apps/files_sharing/l10n/cs_CZ.php @@ -1,8 +1,8 @@ <?php $TRANSLATIONS = array( +"This share is password-protected" => "Toto sdílení je chráněno heslem", "The password is wrong. Try again." => "Heslo není správné. Zkuste to znovu.", "Password" => "Heslo", -"Submit" => "Odeslat", "Sorry, this link doesn’t seem to work anymore." => "Je nám líto, ale tento odkaz již není funkční.", "Reasons might be:" => "Možné důvody:", "the item was removed" => "položka byla odebrána", @@ -14,6 +14,7 @@ $TRANSLATIONS = array( "Download" => "Stáhnout", "Upload" => "Odeslat", "Cancel upload" => "Zrušit odesílání", -"No preview available for" => "Náhled není dostupný pro" +"No preview available for" => "Náhled není dostupný pro", +"Direct link" => "Přímý odkaz" ); $PLURAL_FORMS = "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"; diff --git a/apps/files_sharing/l10n/cy_GB.php b/apps/files_sharing/l10n/cy_GB.php index 66fbc4e1d1c..d2ae28141d4 100644 --- a/apps/files_sharing/l10n/cy_GB.php +++ b/apps/files_sharing/l10n/cy_GB.php @@ -1,7 +1,6 @@ <?php $TRANSLATIONS = array( "Password" => "Cyfrinair", -"Submit" => "Cyflwyno", "%s shared the folder %s with you" => "Rhannodd %s blygell %s â chi", "%s shared the file %s with you" => "Rhannodd %s ffeil %s â chi", "Download" => "Llwytho i lawr", diff --git a/apps/files_sharing/l10n/da.php b/apps/files_sharing/l10n/da.php index 0ca0f38161a..849b0e28d30 100644 --- a/apps/files_sharing/l10n/da.php +++ b/apps/files_sharing/l10n/da.php @@ -1,8 +1,8 @@ <?php $TRANSLATIONS = array( +"This share is password-protected" => "Delingen er beskyttet af kodeord", "The password is wrong. Try again." => "Kodeordet er forkert. Prøv igen.", "Password" => "Kodeord", -"Submit" => "Send", "Sorry, this link doesn’t seem to work anymore." => "Desværre, dette link ser ikke ud til at fungerer længere.", "Reasons might be:" => "Årsagen kan være:", "the item was removed" => "Filen blev fjernet", @@ -14,6 +14,7 @@ $TRANSLATIONS = array( "Download" => "Download", "Upload" => "Upload", "Cancel upload" => "Fortryd upload", -"No preview available for" => "Forhåndsvisning ikke tilgængelig for" +"No preview available for" => "Forhåndsvisning ikke tilgængelig for", +"Direct link" => "Direkte link" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_sharing/l10n/de.php b/apps/files_sharing/l10n/de.php index afed17d8839..d7879833ca9 100644 --- a/apps/files_sharing/l10n/de.php +++ b/apps/files_sharing/l10n/de.php @@ -1,19 +1,20 @@ <?php $TRANSLATIONS = array( -"The password is wrong. Try again." => "Bitte überprüfen sie Ihr Passwort und versuchen Sie es erneut.", +"This share is password-protected" => "Diese Freigabe ist durch ein Passwort geschützt", +"The password is wrong. Try again." => "Bitte überprüfe Dein Passwort und versuche es erneut.", "Password" => "Passwort", -"Submit" => "Absenden", "Sorry, this link doesn’t seem to work anymore." => "Entschuldigung, dieser Link scheint nicht mehr zu funktionieren.", "Reasons might be:" => "Gründe könnten sein:", -"the item was removed" => "Die Elemente wurden entfernt", +"the item was removed" => "Das Element wurde entfernt", "the link expired" => "Der Link ist abgelaufen", "sharing is disabled" => "Teilen ist deaktiviert", -"For more info, please ask the person who sent this link." => "Für mehr Informationen, frage bitte die Person, die dir diesen Link geschickt hat.", +"For more info, please ask the person who sent this link." => "Für mehr Informationen, frage bitte die Person, die Dir diesen Link geschickt hat.", "%s shared the folder %s with you" => "%s hat den Ordner %s mit Dir geteilt", "%s shared the file %s with you" => "%s hat die Datei %s mit Dir geteilt", "Download" => "Download", -"Upload" => "Hochladen", +"Upload" => "Upload", "Cancel upload" => "Upload abbrechen", -"No preview available for" => "Es ist keine Vorschau verfügbar für" +"No preview available for" => "Es ist keine Vorschau verfügbar für", +"Direct link" => "Direkter Link" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_sharing/l10n/de_CH.php b/apps/files_sharing/l10n/de_CH.php index 1bd24f9d9c4..f63714b902f 100644 --- a/apps/files_sharing/l10n/de_CH.php +++ b/apps/files_sharing/l10n/de_CH.php @@ -2,7 +2,6 @@ $TRANSLATIONS = array( "The password is wrong. Try again." => "Das Passwort ist falsch. Bitte versuchen Sie es erneut.", "Password" => "Passwort", -"Submit" => "Bestätigen", "Sorry, this link doesn’t seem to work anymore." => "Entschuldigung, dieser Link scheint nicht mehr zu funktionieren.", "Reasons might be:" => "Gründe könnten sein:", "the item was removed" => "Das Element wurde entfernt", diff --git a/apps/files_sharing/l10n/de_DE.php b/apps/files_sharing/l10n/de_DE.php index 1bd24f9d9c4..3ab95b6690d 100644 --- a/apps/files_sharing/l10n/de_DE.php +++ b/apps/files_sharing/l10n/de_DE.php @@ -1,8 +1,8 @@ <?php $TRANSLATIONS = array( +"This share is password-protected" => "Diese Freigabe ist durch ein Passwort geschützt", "The password is wrong. Try again." => "Das Passwort ist falsch. Bitte versuchen Sie es erneut.", "Password" => "Passwort", -"Submit" => "Bestätigen", "Sorry, this link doesn’t seem to work anymore." => "Entschuldigung, dieser Link scheint nicht mehr zu funktionieren.", "Reasons might be:" => "Gründe könnten sein:", "the item was removed" => "Das Element wurde entfernt", @@ -14,6 +14,7 @@ $TRANSLATIONS = array( "Download" => "Herunterladen", "Upload" => "Hochladen", "Cancel upload" => "Upload abbrechen", -"No preview available for" => "Es ist keine Vorschau verfügbar für" +"No preview available for" => "Es ist keine Vorschau verfügbar für", +"Direct link" => "Direkte Verlinkung" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_sharing/l10n/el.php b/apps/files_sharing/l10n/el.php index 93486a831b1..3ea666504b1 100644 --- a/apps/files_sharing/l10n/el.php +++ b/apps/files_sharing/l10n/el.php @@ -1,19 +1,20 @@ <?php $TRANSLATIONS = array( -"The password is wrong. Try again." => "Εσφαλμένο συνθηματικό. Προσπαθήστε ξανά.", -"Password" => "Συνθηματικό", -"Submit" => "Καταχώρηση", +"This share is password-protected" => "Αυτός ο κοινόχρηστος φάκελος προστατεύεται με κωδικό", +"The password is wrong. Try again." => "Εσφαλμένος κωδικός πρόσβασης. Προσπαθήστε ξανά.", +"Password" => "Κωδικός πρόσβασης", "Sorry, this link doesn’t seem to work anymore." => "Συγγνώμη, αυτός ο σύνδεσμος μοιάζει να μην ισχύει πια.", "Reasons might be:" => "Οι λόγοι μπορεί να είναι:", "the item was removed" => "το αντικείμενο απομακρύνθηκε", "the link expired" => "ο σύνδεσμος έληξε", "sharing is disabled" => "ο διαμοιρασμός απενεργοποιήθηκε", "For more info, please ask the person who sent this link." => "Για περισσότερες πληροφορίες, παρακαλώ ρωτήστε το άτομο που σας έστειλε αυτόν τον σύνδεσμο.", -"%s shared the folder %s with you" => "%s μοιράστηκε τον φάκελο %s μαζί σας", -"%s shared the file %s with you" => "%s μοιράστηκε το αρχείο %s μαζί σας", +"%s shared the folder %s with you" => "Ο %s μοιράστηκε τον φάκελο %s μαζί σας", +"%s shared the file %s with you" => "Ο %s μοιράστηκε το αρχείο %s μαζί σας", "Download" => "Λήψη", "Upload" => "Μεταφόρτωση", -"Cancel upload" => "Ακύρωση αποστολής", -"No preview available for" => "Δεν υπάρχει διαθέσιμη προεπισκόπηση για" +"Cancel upload" => "Ακύρωση μεταφόρτωσης", +"No preview available for" => "Δεν υπάρχει διαθέσιμη προεπισκόπηση για", +"Direct link" => "Άμεσος σύνδεσμος" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_sharing/l10n/en@pirate.php b/apps/files_sharing/l10n/en@pirate.php index a60f1fe72f2..cd3c00d29d2 100644 --- a/apps/files_sharing/l10n/en@pirate.php +++ b/apps/files_sharing/l10n/en@pirate.php @@ -1,7 +1,6 @@ <?php $TRANSLATIONS = array( "Password" => "Secret Code", -"Submit" => "Submit", "%s shared the folder %s with you" => "%s shared the folder %s with you", "%s shared the file %s with you" => "%s shared the file %s with you", "Download" => "Download", diff --git a/apps/files_sharing/l10n/en_GB.php b/apps/files_sharing/l10n/en_GB.php index 337c108651e..3e04d120beb 100644 --- a/apps/files_sharing/l10n/en_GB.php +++ b/apps/files_sharing/l10n/en_GB.php @@ -1,8 +1,8 @@ <?php $TRANSLATIONS = array( +"This share is password-protected" => "This share is password-protected", "The password is wrong. Try again." => "The password is wrong. Try again.", "Password" => "Password", -"Submit" => "Submit", "Sorry, this link doesn’t seem to work anymore." => "Sorry, this link doesn’t seem to work anymore.", "Reasons might be:" => "Reasons might be:", "the item was removed" => "the item was removed", @@ -14,6 +14,7 @@ $TRANSLATIONS = array( "Download" => "Download", "Upload" => "Upload", "Cancel upload" => "Cancel upload", -"No preview available for" => "No preview available for" +"No preview available for" => "No preview available for", +"Direct link" => "Direct link" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_sharing/l10n/eo.php b/apps/files_sharing/l10n/eo.php index 70e703bda91..891b3db9aa8 100644 --- a/apps/files_sharing/l10n/eo.php +++ b/apps/files_sharing/l10n/eo.php @@ -1,12 +1,19 @@ <?php $TRANSLATIONS = array( +"This share is password-protected" => "Ĉi tiu kunhavigo estas protektata per pasvorto", "Password" => "Pasvorto", -"Submit" => "Sendi", +"Sorry, this link doesn’t seem to work anymore." => "Pardonu, ĉi tiu ligilo ŝajne ne plu funkcias.", +"Reasons might be:" => "Kialoj povas esti:", +"the item was removed" => "la ero foriĝis", +"the link expired" => "la ligilo eksvalidiĝis", +"sharing is disabled" => "kunhavigo malkapablas", +"For more info, please ask the person who sent this link." => "Por plia informo, bonvolu peti al la persono, kiu sendis ĉi tiun ligilon.", "%s shared the folder %s with you" => "%s kunhavigis la dosierujon %s kun vi", "%s shared the file %s with you" => "%s kunhavigis la dosieron %s kun vi", "Download" => "Elŝuti", "Upload" => "Alŝuti", "Cancel upload" => "Nuligi alŝuton", -"No preview available for" => "Ne haveblas antaŭvido por" +"No preview available for" => "Ne haveblas antaŭvido por", +"Direct link" => "Direkta ligilo" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_sharing/l10n/es.php b/apps/files_sharing/l10n/es.php index e163da766f3..f986c29b4f7 100644 --- a/apps/files_sharing/l10n/es.php +++ b/apps/files_sharing/l10n/es.php @@ -1,8 +1,8 @@ <?php $TRANSLATIONS = array( +"This share is password-protected" => "Este elemento compartido esta protegido por contraseña", "The password is wrong. Try again." => "La contraseña introducida es errónea. Inténtelo de nuevo.", "Password" => "Contraseña", -"Submit" => "Enviar", "Sorry, this link doesn’t seem to work anymore." => "Vaya, este enlace parece que no volverá a funcionar.", "Reasons might be:" => "Las causas podrían ser:", "the item was removed" => "el elemento fue eliminado", @@ -14,6 +14,7 @@ $TRANSLATIONS = array( "Download" => "Descargar", "Upload" => "Subir", "Cancel upload" => "Cancelar subida", -"No preview available for" => "No hay vista previa disponible para" +"No preview available for" => "No hay vista previa disponible para", +"Direct link" => "Enlace directo" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_sharing/l10n/es_AR.php b/apps/files_sharing/l10n/es_AR.php index 7c9dcb94ac1..989a91a450f 100644 --- a/apps/files_sharing/l10n/es_AR.php +++ b/apps/files_sharing/l10n/es_AR.php @@ -2,7 +2,6 @@ $TRANSLATIONS = array( "The password is wrong. Try again." => "La contraseña no es correcta. Probá de nuevo.", "Password" => "Contraseña", -"Submit" => "Enviar", "Sorry, this link doesn’t seem to work anymore." => "Perdón, este enlace parece no funcionar más.", "Reasons might be:" => "Las causas podrían ser:", "the item was removed" => "el elemento fue borrado", diff --git a/apps/files_sharing/l10n/es_CL.php b/apps/files_sharing/l10n/es_CL.php new file mode 100644 index 00000000000..31dc045870c --- /dev/null +++ b/apps/files_sharing/l10n/es_CL.php @@ -0,0 +1,6 @@ +<?php +$TRANSLATIONS = array( +"Password" => "Clave", +"Upload" => "Subir" +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_sharing/l10n/es_MX.php b/apps/files_sharing/l10n/es_MX.php new file mode 100644 index 00000000000..9100ef8b35f --- /dev/null +++ b/apps/files_sharing/l10n/es_MX.php @@ -0,0 +1,20 @@ +<?php +$TRANSLATIONS = array( +"This share is password-protected" => "Este elemento compartido esta protegido por contraseña", +"The password is wrong. Try again." => "La contraseña introducida es errónea. Inténtelo de nuevo.", +"Password" => "Contraseña", +"Sorry, this link doesn’t seem to work anymore." => "Lo siento, este enlace al parecer ya no funciona.", +"Reasons might be:" => "Las causas podrían ser:", +"the item was removed" => "el elemento fue eliminado", +"the link expired" => "el enlace expiró", +"sharing is disabled" => "compartir está desactivado", +"For more info, please ask the person who sent this link." => "Para mayor información, contacte a la persona que le envió el enlace.", +"%s shared the folder %s with you" => "%s compartió la carpeta %s contigo", +"%s shared the file %s with you" => "%s compartió el archivo %s contigo", +"Download" => "Descargar", +"Upload" => "Subir", +"Cancel upload" => "Cancelar subida", +"No preview available for" => "No hay vista previa disponible para", +"Direct link" => "Enlace directo" +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_sharing/l10n/et_EE.php b/apps/files_sharing/l10n/et_EE.php index fe230902ff1..4b7f975e83d 100644 --- a/apps/files_sharing/l10n/et_EE.php +++ b/apps/files_sharing/l10n/et_EE.php @@ -1,8 +1,8 @@ <?php $TRANSLATIONS = array( +"This share is password-protected" => "See jagamine on parooliga kaitstud", "The password is wrong. Try again." => "Parool on vale. Proovi uuesti.", "Password" => "Parool", -"Submit" => "Saada", "Sorry, this link doesn’t seem to work anymore." => "Vabandust, see link ei tundu enam toimivat.", "Reasons might be:" => "Põhjused võivad olla:", "the item was removed" => "üksus on eemaldatud", @@ -14,6 +14,7 @@ $TRANSLATIONS = array( "Download" => "Lae alla", "Upload" => "Lae üles", "Cancel upload" => "Tühista üleslaadimine", -"No preview available for" => "Eelvaadet pole saadaval" +"No preview available for" => "Eelvaadet pole saadaval", +"Direct link" => "Otsene link" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_sharing/l10n/eu.php b/apps/files_sharing/l10n/eu.php index 7b6a4b08b3c..20de5a085ab 100644 --- a/apps/files_sharing/l10n/eu.php +++ b/apps/files_sharing/l10n/eu.php @@ -1,8 +1,8 @@ <?php $TRANSLATIONS = array( +"This share is password-protected" => "Elkarbanatutako hau pasahitzarekin babestuta dago", "The password is wrong. Try again." => "Pasahitza ez da egokia. Saiatu berriro.", "Password" => "Pasahitza", -"Submit" => "Bidali", "Sorry, this link doesn’t seem to work anymore." => "Barkatu, lotura ez dirudi eskuragarria dagoenik.", "Reasons might be:" => "Arrazoiak hurrengoak litezke:", "the item was removed" => "fitxategia ezbatua izan da", @@ -14,6 +14,7 @@ $TRANSLATIONS = array( "Download" => "Deskargatu", "Upload" => "Igo", "Cancel upload" => "Ezeztatu igoera", -"No preview available for" => "Ez dago aurrebista eskuragarririk hauentzat " +"No preview available for" => "Ez dago aurrebista eskuragarririk hauentzat ", +"Direct link" => "Lotura zuzena" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_sharing/l10n/fa.php b/apps/files_sharing/l10n/fa.php index 48888f798a0..664338723c4 100644 --- a/apps/files_sharing/l10n/fa.php +++ b/apps/files_sharing/l10n/fa.php @@ -2,7 +2,6 @@ $TRANSLATIONS = array( "The password is wrong. Try again." => "رمزعبور اشتباه می باشد. دوباره امتحان کنید.", "Password" => "گذرواژه", -"Submit" => "ثبت", "%s shared the folder %s with you" => "%sپوشه %s را با شما به اشتراک گذاشت", "%s shared the file %s with you" => "%sفایل %s را با شما به اشتراک گذاشت", "Download" => "دانلود", diff --git a/apps/files_sharing/l10n/fi_FI.php b/apps/files_sharing/l10n/fi_FI.php index 42905be57a6..c54c822b1c4 100644 --- a/apps/files_sharing/l10n/fi_FI.php +++ b/apps/files_sharing/l10n/fi_FI.php @@ -1,8 +1,8 @@ <?php $TRANSLATIONS = array( +"This share is password-protected" => "Tämä jako on suojattu salasanalla", "The password is wrong. Try again." => "Väärä salasana. Yritä uudelleen.", "Password" => "Salasana", -"Submit" => "Lähetä", "Sorry, this link doesn’t seem to work anymore." => "Valitettavasti linkki ei vaikuta enää toimivan.", "Reasons might be:" => "Mahdollisia syitä:", "the item was removed" => "kohde poistettiin", @@ -14,6 +14,7 @@ $TRANSLATIONS = array( "Download" => "Lataa", "Upload" => "Lähetä", "Cancel upload" => "Peru lähetys", -"No preview available for" => "Ei esikatselua kohteelle" +"No preview available for" => "Ei esikatselua kohteelle", +"Direct link" => "Suora linkki" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_sharing/l10n/fr.php b/apps/files_sharing/l10n/fr.php index c97a1db97e4..b51f421fa52 100644 --- a/apps/files_sharing/l10n/fr.php +++ b/apps/files_sharing/l10n/fr.php @@ -1,8 +1,8 @@ <?php $TRANSLATIONS = array( +"This share is password-protected" => "Ce partage est protégé par un mot de passe", "The password is wrong. Try again." => "Le mot de passe est incorrect. Veuillez réessayer.", "Password" => "Mot de passe", -"Submit" => "Envoyer", "Sorry, this link doesn’t seem to work anymore." => "Désolé, mais le lien semble ne plus fonctionner.", "Reasons might be:" => "Les raisons peuvent être :", "the item was removed" => "l'item a été supprimé", @@ -14,6 +14,7 @@ $TRANSLATIONS = array( "Download" => "Télécharger", "Upload" => "Envoyer", "Cancel upload" => "Annuler l'envoi", -"No preview available for" => "Pas d'aperçu disponible pour" +"No preview available for" => "Pas d'aperçu disponible pour", +"Direct link" => "Lien direct" ); $PLURAL_FORMS = "nplurals=2; plural=(n > 1);"; diff --git a/apps/files_sharing/l10n/gl.php b/apps/files_sharing/l10n/gl.php index 66b1f0e5ffc..3ea3fe5f1c5 100644 --- a/apps/files_sharing/l10n/gl.php +++ b/apps/files_sharing/l10n/gl.php @@ -1,8 +1,8 @@ <?php $TRANSLATIONS = array( +"This share is password-protected" => "Esta compartición está protexida con contrasinal", "The password is wrong. Try again." => "O contrasinal é incorrecto. Ténteo de novo.", "Password" => "Contrasinal", -"Submit" => "Enviar", "Sorry, this link doesn’t seem to work anymore." => "Semella que esta ligazón non funciona.", "Reasons might be:" => "As razóns poderían ser:", "the item was removed" => "o elemento foi retirado", @@ -14,6 +14,7 @@ $TRANSLATIONS = array( "Download" => "Descargar", "Upload" => "Enviar", "Cancel upload" => "Cancelar o envío", -"No preview available for" => "Sen vista previa dispoñíbel para" +"No preview available for" => "Sen vista previa dispoñíbel para", +"Direct link" => "Ligazón directa" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_sharing/l10n/he.php b/apps/files_sharing/l10n/he.php index f8b304898ce..217298feddf 100644 --- a/apps/files_sharing/l10n/he.php +++ b/apps/files_sharing/l10n/he.php @@ -1,7 +1,6 @@ <?php $TRANSLATIONS = array( "Password" => "סיסמא", -"Submit" => "שליחה", "%s shared the folder %s with you" => "%s שיתף עמך את התיקייה %s", "%s shared the file %s with you" => "%s שיתף עמך את הקובץ %s", "Download" => "הורדה", diff --git a/apps/files_sharing/l10n/hr.php b/apps/files_sharing/l10n/hr.php index 87eb9567067..4a82dd7f71f 100644 --- a/apps/files_sharing/l10n/hr.php +++ b/apps/files_sharing/l10n/hr.php @@ -1,7 +1,6 @@ <?php $TRANSLATIONS = array( "Password" => "Lozinka", -"Submit" => "Pošalji", "Download" => "Preuzimanje", "Upload" => "Učitaj", "Cancel upload" => "Prekini upload" diff --git a/apps/files_sharing/l10n/hu_HU.php b/apps/files_sharing/l10n/hu_HU.php index 7ef69b1e0b6..a06c51b3775 100644 --- a/apps/files_sharing/l10n/hu_HU.php +++ b/apps/files_sharing/l10n/hu_HU.php @@ -1,8 +1,8 @@ <?php $TRANSLATIONS = array( +"This share is password-protected" => "Ez egy jelszóval védett megosztás", "The password is wrong. Try again." => "A megadott jelszó nem megfelelő. Próbálja újra!", "Password" => "Jelszó", -"Submit" => "Elküld", "Sorry, this link doesn’t seem to work anymore." => "Sajnos úgy tűnik, ez a link már nem működik.", "Reasons might be:" => "Ennek az oka a következő lehet:", "the item was removed" => "az állományt időközben eltávolították", @@ -14,6 +14,7 @@ $TRANSLATIONS = array( "Download" => "Letöltés", "Upload" => "Feltöltés", "Cancel upload" => "A feltöltés megszakítása", -"No preview available for" => "Nem áll rendelkezésre előnézet ehhez: " +"No preview available for" => "Nem áll rendelkezésre előnézet ehhez: ", +"Direct link" => "Közvetlen link" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_sharing/l10n/hy.php b/apps/files_sharing/l10n/hy.php index d4cb416f45a..da200623e03 100644 --- a/apps/files_sharing/l10n/hy.php +++ b/apps/files_sharing/l10n/hy.php @@ -1,6 +1,5 @@ <?php $TRANSLATIONS = array( -"Submit" => "Հաստատել", "Download" => "Բեռնել" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_sharing/l10n/ia.php b/apps/files_sharing/l10n/ia.php index 5112501073d..f9d6c33a0b5 100644 --- a/apps/files_sharing/l10n/ia.php +++ b/apps/files_sharing/l10n/ia.php @@ -1,7 +1,6 @@ <?php $TRANSLATIONS = array( "Password" => "Contrasigno", -"Submit" => "Submitter", "Download" => "Discargar", "Upload" => "Incargar" ); diff --git a/apps/files_sharing/l10n/id.php b/apps/files_sharing/l10n/id.php index a4d73bd2b75..865a951c2d2 100644 --- a/apps/files_sharing/l10n/id.php +++ b/apps/files_sharing/l10n/id.php @@ -1,12 +1,20 @@ <?php $TRANSLATIONS = array( +"This share is password-protected" => "Berbagi ini dilindungi sandi", +"The password is wrong. Try again." => "Sandi salah. Coba lagi", "Password" => "Sandi", -"Submit" => "Kirim", +"Sorry, this link doesn’t seem to work anymore." => "Maaf, tautan ini tampaknya tidak berfungsi lagi.", +"Reasons might be:" => "Alasan mungkin:", +"the item was removed" => "item telah dihapus", +"the link expired" => "tautan telah kadaluarsa", +"sharing is disabled" => "berbagi dinonaktifkan", +"For more info, please ask the person who sent this link." => "Untuk info lebih lanjut, silakan tanyakan orang yang mengirim tautan ini.", "%s shared the folder %s with you" => "%s membagikan folder %s dengan Anda", -"%s shared the file %s with you" => "%s membagikan file %s dengan Anda", +"%s shared the file %s with you" => "%s membagikan berkas %s dengan Anda", "Download" => "Unduh", "Upload" => "Unggah", -"Cancel upload" => "Batal pengunggahan", -"No preview available for" => "Tidak ada pratinjau tersedia untuk" +"Cancel upload" => "Batal unggah", +"No preview available for" => "Tidak ada pratinjau yang tersedia untuk", +"Direct link" => "Tautan langsung" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/files_sharing/l10n/is.php b/apps/files_sharing/l10n/is.php index 05241d3f9e6..8ae8e48eff6 100644 --- a/apps/files_sharing/l10n/is.php +++ b/apps/files_sharing/l10n/is.php @@ -1,7 +1,6 @@ <?php $TRANSLATIONS = array( "Password" => "Lykilorð", -"Submit" => "Senda", "%s shared the folder %s with you" => "%s deildi möppunni %s með þér", "%s shared the file %s with you" => "%s deildi skránni %s með þér", "Download" => "Niðurhal", diff --git a/apps/files_sharing/l10n/it.php b/apps/files_sharing/l10n/it.php index a611e0641c8..7967b50d346 100644 --- a/apps/files_sharing/l10n/it.php +++ b/apps/files_sharing/l10n/it.php @@ -1,8 +1,8 @@ <?php $TRANSLATIONS = array( +"This share is password-protected" => "Questa condivione è protetta da password", "The password is wrong. Try again." => "La password è errata. Prova ancora.", "Password" => "Password", -"Submit" => "Invia", "Sorry, this link doesn’t seem to work anymore." => "Spiacenti, questo collegamento sembra non essere più attivo.", "Reasons might be:" => "I motivi potrebbero essere:", "the item was removed" => "l'elemento è stato rimosso", @@ -14,6 +14,7 @@ $TRANSLATIONS = array( "Download" => "Scarica", "Upload" => "Carica", "Cancel upload" => "Annulla il caricamento", -"No preview available for" => "Nessuna anteprima disponibile per" +"No preview available for" => "Nessuna anteprima disponibile per", +"Direct link" => "Collegamento diretto" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_sharing/l10n/ja_JP.php b/apps/files_sharing/l10n/ja_JP.php index 4f7d5b31c2f..fe25cb5b6eb 100644 --- a/apps/files_sharing/l10n/ja_JP.php +++ b/apps/files_sharing/l10n/ja_JP.php @@ -1,8 +1,8 @@ <?php $TRANSLATIONS = array( +"This share is password-protected" => "この共有はパスワードで保護されています", "The password is wrong. Try again." => "パスワードが間違っています。再試行してください。", "Password" => "パスワード", -"Submit" => "送信", "Sorry, this link doesn’t seem to work anymore." => "申し訳ございません。このリンクはもう利用できません。", "Reasons might be:" => "理由は以下の通りと考えられます:", "the item was removed" => "アイテムが削除されました", @@ -14,6 +14,7 @@ $TRANSLATIONS = array( "Download" => "ダウンロード", "Upload" => "アップロード", "Cancel upload" => "アップロードをキャンセル", -"No preview available for" => "プレビューはありません" +"No preview available for" => "プレビューはありません", +"Direct link" => "リンク" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/files_sharing/l10n/ka_GE.php b/apps/files_sharing/l10n/ka_GE.php index a5a80b3c5a1..89a6800b3e4 100644 --- a/apps/files_sharing/l10n/ka_GE.php +++ b/apps/files_sharing/l10n/ka_GE.php @@ -1,7 +1,6 @@ <?php $TRANSLATIONS = array( "Password" => "პაროლი", -"Submit" => "გაგზავნა", "%s shared the folder %s with you" => "%s–მა გაგიზიარათ ფოლდერი %s", "%s shared the file %s with you" => "%s–მა გაგიზიარათ ფაილი %s", "Download" => "ჩამოტვირთვა", diff --git a/apps/files_sharing/l10n/ko.php b/apps/files_sharing/l10n/ko.php index f7eab1ac550..03c4c1aea94 100644 --- a/apps/files_sharing/l10n/ko.php +++ b/apps/files_sharing/l10n/ko.php @@ -1,19 +1,20 @@ <?php $TRANSLATIONS = array( -"The password is wrong. Try again." => "비밀번호가 틀립니다. 다시 입력해주세요.", +"This share is password-protected" => "이 공유는 암호로 보호되어 있습니다", +"The password is wrong. Try again." => "암호가 잘못되었습니다. 다시 입력해 주십시오.", "Password" => "암호", -"Submit" => "제출", -"Sorry, this link doesn’t seem to work anymore." => "죄송합니다만 이 링크는 더이상 작동되지 않습니다.", +"Sorry, this link doesn’t seem to work anymore." => "죄송합니다. 이 링크는 더 이상 작동하지 않습니다.", "Reasons might be:" => "이유는 다음과 같을 수 있습니다:", -"the item was removed" => "이 항목은 삭제되었습니다", -"the link expired" => "링크가 만료되었습니다", -"sharing is disabled" => "공유가 비활성되었습니다", -"For more info, please ask the person who sent this link." => "더 자세한 설명은 링크를 보내신 분에게 여쭤보십시오", +"the item was removed" => "항목이 삭제됨", +"the link expired" => "링크가 만료됨", +"sharing is disabled" => "공유가 비활성화됨", +"For more info, please ask the person who sent this link." => "자세한 정보는 링크를 보낸 사람에게 문의하십시오.", "%s shared the folder %s with you" => "%s 님이 폴더 %s을(를) 공유하였습니다", "%s shared the file %s with you" => "%s 님이 파일 %s을(를) 공유하였습니다", "Download" => "다운로드", "Upload" => "업로드", "Cancel upload" => "업로드 취소", -"No preview available for" => "다음 항목을 미리 볼 수 없음:" +"No preview available for" => "다음 항목을 미리 볼 수 없음:", +"Direct link" => "직접 링크" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/files_sharing/l10n/ku_IQ.php b/apps/files_sharing/l10n/ku_IQ.php index 55576a19c36..6b4b7e4ba9e 100644 --- a/apps/files_sharing/l10n/ku_IQ.php +++ b/apps/files_sharing/l10n/ku_IQ.php @@ -1,7 +1,6 @@ <?php $TRANSLATIONS = array( "Password" => "وشەی تێپەربو", -"Submit" => "ناردن", "%s shared the folder %s with you" => "%s دابهشی کردووه بوخچهی %s لهگهڵ تۆ", "%s shared the file %s with you" => "%s دابهشی کردووه پهڕگهیی %s لهگهڵ تۆ", "Download" => "داگرتن", diff --git a/apps/files_sharing/l10n/lb.php b/apps/files_sharing/l10n/lb.php index d37a1d9d22a..eeb6a3e2dca 100644 --- a/apps/files_sharing/l10n/lb.php +++ b/apps/files_sharing/l10n/lb.php @@ -2,7 +2,6 @@ $TRANSLATIONS = array( "The password is wrong. Try again." => "Den Passwuert ass incorrect. Probeier ed nach eng keier.", "Password" => "Passwuert", -"Submit" => "Fortschécken", "%s shared the folder %s with you" => "%s huet den Dossier %s mad der gedeelt", "%s shared the file %s with you" => "%s deelt den Fichier %s mad dir", "Download" => "Download", diff --git a/apps/files_sharing/l10n/lt_LT.php b/apps/files_sharing/l10n/lt_LT.php index 90ae6a39a07..3786fd08b92 100644 --- a/apps/files_sharing/l10n/lt_LT.php +++ b/apps/files_sharing/l10n/lt_LT.php @@ -1,8 +1,8 @@ <?php $TRANSLATIONS = array( +"This share is password-protected" => "Turinys apsaugotas slaptažodžiu", "The password is wrong. Try again." => "Netinka slaptažodis: Bandykite dar kartą.", "Password" => "Slaptažodis", -"Submit" => "Išsaugoti", "Sorry, this link doesn’t seem to work anymore." => "Atleiskite, panašu, kad nuoroda yra neveiksni.", "Reasons might be:" => "Galimos priežastys:", "the item was removed" => "elementas buvo pašalintas", @@ -14,6 +14,7 @@ $TRANSLATIONS = array( "Download" => "Atsisiųsti", "Upload" => "Įkelti", "Cancel upload" => "Atšaukti siuntimą", -"No preview available for" => "Peržiūra nėra galima" +"No preview available for" => "Peržiūra nėra galima", +"Direct link" => "Tiesioginė nuoroda" ); $PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);"; diff --git a/apps/files_sharing/l10n/lv.php b/apps/files_sharing/l10n/lv.php index 0eb04fb966f..a913ba11525 100644 --- a/apps/files_sharing/l10n/lv.php +++ b/apps/files_sharing/l10n/lv.php @@ -1,7 +1,6 @@ <?php $TRANSLATIONS = array( "Password" => "Parole", -"Submit" => "Iesniegt", "%s shared the folder %s with you" => "%s ar jums dalījās ar mapi %s", "%s shared the file %s with you" => "%s ar jums dalījās ar datni %s", "Download" => "Lejupielādēt", diff --git a/apps/files_sharing/l10n/mk.php b/apps/files_sharing/l10n/mk.php index c913b2beaf7..c132f7aa265 100644 --- a/apps/files_sharing/l10n/mk.php +++ b/apps/files_sharing/l10n/mk.php @@ -1,7 +1,6 @@ <?php $TRANSLATIONS = array( "Password" => "Лозинка", -"Submit" => "Прати", "%s shared the folder %s with you" => "%s ја сподели папката %s со Вас", "%s shared the file %s with you" => "%s ја сподели датотеката %s со Вас", "Download" => "Преземи", diff --git a/apps/files_sharing/l10n/ms_MY.php b/apps/files_sharing/l10n/ms_MY.php index 0a3d08bbc17..9725dd4d1bc 100644 --- a/apps/files_sharing/l10n/ms_MY.php +++ b/apps/files_sharing/l10n/ms_MY.php @@ -1,7 +1,6 @@ <?php $TRANSLATIONS = array( "Password" => "Kata laluan", -"Submit" => "Hantar", "Download" => "Muat turun", "Upload" => "Muat naik", "Cancel upload" => "Batal muat naik" diff --git a/apps/files_sharing/l10n/my_MM.php b/apps/files_sharing/l10n/my_MM.php index f44010004cd..ff92e898ed4 100644 --- a/apps/files_sharing/l10n/my_MM.php +++ b/apps/files_sharing/l10n/my_MM.php @@ -1,7 +1,6 @@ <?php $TRANSLATIONS = array( "Password" => "စကားဝှက်", -"Submit" => "ထည့်သွင်းမည်", "Download" => "ဒေါင်းလုတ်" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/files_sharing/l10n/nb_NO.php b/apps/files_sharing/l10n/nb_NO.php index dd8a8edf313..0452b5275c1 100644 --- a/apps/files_sharing/l10n/nb_NO.php +++ b/apps/files_sharing/l10n/nb_NO.php @@ -2,7 +2,6 @@ $TRANSLATIONS = array( "The password is wrong. Try again." => "Passordet er feil. Prøv på nytt.", "Password" => "Passord", -"Submit" => "Send inn", "%s shared the folder %s with you" => "%s delte mappen %s med deg", "%s shared the file %s with you" => "%s delte filen %s med deg", "Download" => "Last ned", diff --git a/apps/files_sharing/l10n/nl.php b/apps/files_sharing/l10n/nl.php index 9c46a1ab4b3..687c6e134f5 100644 --- a/apps/files_sharing/l10n/nl.php +++ b/apps/files_sharing/l10n/nl.php @@ -1,8 +1,8 @@ <?php $TRANSLATIONS = array( +"This share is password-protected" => "Deze share is met een wachtwoord beveiligd", "The password is wrong. Try again." => "Wachtwoord ongeldig. Probeer het nogmaals.", "Password" => "Wachtwoord", -"Submit" => "Verzenden", "Sorry, this link doesn’t seem to work anymore." => "Sorry, deze link lijkt niet meer in gebruik te zijn.", "Reasons might be:" => "Redenen kunnen zijn:", "the item was removed" => "bestand was verwijderd", @@ -14,6 +14,7 @@ $TRANSLATIONS = array( "Download" => "Downloaden", "Upload" => "Uploaden", "Cancel upload" => "Upload afbreken", -"No preview available for" => "Geen voorbeeldweergave beschikbaar voor" +"No preview available for" => "Geen voorbeeldweergave beschikbaar voor", +"Direct link" => "Directe link" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_sharing/l10n/nn_NO.php b/apps/files_sharing/l10n/nn_NO.php index 94272943e40..1f1e8001e70 100644 --- a/apps/files_sharing/l10n/nn_NO.php +++ b/apps/files_sharing/l10n/nn_NO.php @@ -2,7 +2,6 @@ $TRANSLATIONS = array( "The password is wrong. Try again." => "Passordet er gale. Prøv igjen.", "Password" => "Passord", -"Submit" => "Send", "Sorry, this link doesn’t seem to work anymore." => "Orsak, denne lenkja fungerer visst ikkje lenger.", "Reasons might be:" => "Moglege grunnar:", "the item was removed" => "fila/mappa er fjerna", diff --git a/apps/files_sharing/l10n/oc.php b/apps/files_sharing/l10n/oc.php index 493ddb4dfd3..299d98e58b4 100644 --- a/apps/files_sharing/l10n/oc.php +++ b/apps/files_sharing/l10n/oc.php @@ -1,7 +1,6 @@ <?php $TRANSLATIONS = array( "Password" => "Senhal", -"Submit" => "Sosmetre", "Download" => "Avalcarga", "Upload" => "Amontcarga", "Cancel upload" => " Anulla l'amontcargar" diff --git a/apps/files_sharing/l10n/pl.php b/apps/files_sharing/l10n/pl.php index 43c7e2e3144..4c7498ee1b7 100644 --- a/apps/files_sharing/l10n/pl.php +++ b/apps/files_sharing/l10n/pl.php @@ -1,8 +1,8 @@ <?php $TRANSLATIONS = array( +"This share is password-protected" => "Udział ten jest chroniony hasłem", "The password is wrong. Try again." => "To hasło jest niewłaściwe. Spróbuj ponownie.", "Password" => "Hasło", -"Submit" => "Wyślij", "Sorry, this link doesn’t seem to work anymore." => "Przepraszamy ale wygląda na to, że ten link już nie działa.", "Reasons might be:" => "Możliwe powody:", "the item was removed" => "element został usunięty", @@ -14,6 +14,7 @@ $TRANSLATIONS = array( "Download" => "Pobierz", "Upload" => "Wyślij", "Cancel upload" => "Anuluj wysyłanie", -"No preview available for" => "Podgląd nie jest dostępny dla" +"No preview available for" => "Podgląd nie jest dostępny dla", +"Direct link" => "Bezpośredni link" ); $PLURAL_FORMS = "nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"; diff --git a/apps/files_sharing/l10n/pt_BR.php b/apps/files_sharing/l10n/pt_BR.php index 9fc1cacf7cb..ee03749795b 100644 --- a/apps/files_sharing/l10n/pt_BR.php +++ b/apps/files_sharing/l10n/pt_BR.php @@ -1,8 +1,8 @@ <?php $TRANSLATIONS = array( +"This share is password-protected" => "Este compartilhamento esta protegido por senha", "The password is wrong. Try again." => "Senha incorreta. Tente novamente.", "Password" => "Senha", -"Submit" => "Submeter", "Sorry, this link doesn’t seem to work anymore." => "Desculpe, este link parece não mais funcionar.", "Reasons might be:" => "As razões podem ser:", "the item was removed" => "o item foi removido", @@ -14,6 +14,7 @@ $TRANSLATIONS = array( "Download" => "Baixar", "Upload" => "Upload", "Cancel upload" => "Cancelar upload", -"No preview available for" => "Nenhuma visualização disponível para" +"No preview available for" => "Nenhuma visualização disponível para", +"Direct link" => "Link direto" ); $PLURAL_FORMS = "nplurals=2; plural=(n > 1);"; diff --git a/apps/files_sharing/l10n/pt_PT.php b/apps/files_sharing/l10n/pt_PT.php index 73dc2a3e1f3..cd94211b5d3 100644 --- a/apps/files_sharing/l10n/pt_PT.php +++ b/apps/files_sharing/l10n/pt_PT.php @@ -1,8 +1,8 @@ <?php $TRANSLATIONS = array( +"This share is password-protected" => "Esta partilha está protegida por palavra-chave", "The password is wrong. Try again." => "Password errada, por favor tente de novo", -"Password" => "Password", -"Submit" => "Submeter", +"Password" => "Palavra-passe", "Sorry, this link doesn’t seem to work anymore." => "Desculpe, mas este link parece não estar a funcionar.", "Reasons might be:" => "As razões poderão ser:", "the item was removed" => "O item foi removido", @@ -14,6 +14,7 @@ $TRANSLATIONS = array( "Download" => "Transferir", "Upload" => "Carregar", "Cancel upload" => "Cancelar envio", -"No preview available for" => "Não há pré-visualização para" +"No preview available for" => "Não há pré-visualização para", +"Direct link" => "Link direto" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_sharing/l10n/ro.php b/apps/files_sharing/l10n/ro.php index d17152ff1b1..54e20ed6bb4 100644 --- a/apps/files_sharing/l10n/ro.php +++ b/apps/files_sharing/l10n/ro.php @@ -2,7 +2,6 @@ $TRANSLATIONS = array( "The password is wrong. Try again." => "Parola este incorectă. Încercaţi din nou.", "Password" => "Parolă", -"Submit" => "Trimite", "%s shared the folder %s with you" => "%s a partajat directorul %s cu tine", "%s shared the file %s with you" => "%s a partajat fișierul %s cu tine", "Download" => "Descarcă", diff --git a/apps/files_sharing/l10n/ru.php b/apps/files_sharing/l10n/ru.php index f42f1d9aeb6..8c48096f666 100644 --- a/apps/files_sharing/l10n/ru.php +++ b/apps/files_sharing/l10n/ru.php @@ -1,8 +1,8 @@ <?php $TRANSLATIONS = array( +"This share is password-protected" => "Эта шара защищена паролем", "The password is wrong. Try again." => "Неверный пароль. Попробуйте еще раз.", "Password" => "Пароль", -"Submit" => "Отправить", "Sorry, this link doesn’t seem to work anymore." => "К сожалению, эта ссылка, похоже не будет работать больше.", "Reasons might be:" => "Причиной может быть:", "the item was removed" => "объект был удалён", @@ -14,6 +14,7 @@ $TRANSLATIONS = array( "Download" => "Скачать", "Upload" => "Загрузка", "Cancel upload" => "Отмена загрузки", -"No preview available for" => "Предпросмотр недоступен для" +"No preview available for" => "Предпросмотр недоступен для", +"Direct link" => "Прямая ссылка" ); $PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"; diff --git a/apps/files_sharing/l10n/si_LK.php b/apps/files_sharing/l10n/si_LK.php index 6135f092139..e8401385647 100644 --- a/apps/files_sharing/l10n/si_LK.php +++ b/apps/files_sharing/l10n/si_LK.php @@ -1,7 +1,6 @@ <?php $TRANSLATIONS = array( "Password" => "මුර පදය", -"Submit" => "යොමු කරන්න", "%s shared the folder %s with you" => "%s ඔබව %s ෆෝල්ඩරයට හවුල් කරගත්තේය", "%s shared the file %s with you" => "%s ඔබ සමඟ %s ගොනුව බෙදාහදාගත්තේය", "Download" => "බාන්න", diff --git a/apps/files_sharing/l10n/sk.php b/apps/files_sharing/l10n/sk.php new file mode 100644 index 00000000000..72c9039571e --- /dev/null +++ b/apps/files_sharing/l10n/sk.php @@ -0,0 +1,5 @@ +<?php +$TRANSLATIONS = array( +"Download" => "Stiahnuť" +); +$PLURAL_FORMS = "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"; diff --git a/apps/files_sharing/l10n/sk_SK.php b/apps/files_sharing/l10n/sk_SK.php index 31ecb28b602..4ea8cbdd77d 100644 --- a/apps/files_sharing/l10n/sk_SK.php +++ b/apps/files_sharing/l10n/sk_SK.php @@ -1,8 +1,8 @@ <?php $TRANSLATIONS = array( +"This share is password-protected" => "Toto zdieľanie je chránené heslom", "The password is wrong. Try again." => "Heslo je chybné. Skúste to znova.", "Password" => "Heslo", -"Submit" => "Odoslať", "Sorry, this link doesn’t seem to work anymore." => "To je nepríjemné, ale tento odkaz už nie je funkčný.", "Reasons might be:" => "Možné dôvody:", "the item was removed" => "položka bola presunutá", @@ -12,8 +12,9 @@ $TRANSLATIONS = array( "%s shared the folder %s with you" => "%s zdieľa s vami priečinok %s", "%s shared the file %s with you" => "%s zdieľa s vami súbor %s", "Download" => "Sťahovanie", -"Upload" => "Odoslať", -"Cancel upload" => "Zrušiť odosielanie", -"No preview available for" => "Žiaden náhľad k dispozícii pre" +"Upload" => "Nahrať", +"Cancel upload" => "Zrušiť nahrávanie", +"No preview available for" => "Žiaden náhľad k dispozícii pre", +"Direct link" => "Priama linka" ); $PLURAL_FORMS = "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"; diff --git a/apps/files_sharing/l10n/sl.php b/apps/files_sharing/l10n/sl.php index cbd4f5fea22..d5ef46e180e 100644 --- a/apps/files_sharing/l10n/sl.php +++ b/apps/files_sharing/l10n/sl.php @@ -1,12 +1,20 @@ <?php $TRANSLATIONS = array( +"This share is password-protected" => "To mesto je zaščiteno z geslom.", +"The password is wrong. Try again." => "Geslo je napačno. Poskusite znova.", "Password" => "Geslo", -"Submit" => "Pošlji", +"Sorry, this link doesn’t seem to work anymore." => "Povezava očitno ni več v uporabi.", +"Reasons might be:" => "Vzrok je lahko:", +"the item was removed" => "predmet je odstranjen,", +"the link expired" => "povezava je pretekla,", +"sharing is disabled" => "souporaba je onemogočena.", +"For more info, please ask the person who sent this link." => "Za več podrobnosti stopite v stik s pošiljateljem te povezave.", "%s shared the folder %s with you" => "Oseba %s je določila mapo %s za souporabo", "%s shared the file %s with you" => "Oseba %s je določila datoteko %s za souporabo", "Download" => "Prejmi", "Upload" => "Pošlji", "Cancel upload" => "Prekliči pošiljanje", -"No preview available for" => "Predogled ni na voljo za" +"No preview available for" => "Predogled ni na voljo za", +"Direct link" => "Neposredna povezava" ); $PLURAL_FORMS = "nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);"; diff --git a/apps/files_sharing/l10n/sq.php b/apps/files_sharing/l10n/sq.php index d2077663e8d..473049f75ed 100644 --- a/apps/files_sharing/l10n/sq.php +++ b/apps/files_sharing/l10n/sq.php @@ -2,7 +2,6 @@ $TRANSLATIONS = array( "The password is wrong. Try again." => "Kodi është i gabuar. Provojeni përsëri.", "Password" => "Kodi", -"Submit" => "Parashtro", "Sorry, this link doesn’t seem to work anymore." => "Ju kërkojmë ndjesë, kjo lidhje duket sikur nuk punon më.", "Reasons might be:" => "Arsyet mund të jenë:", "the item was removed" => "elementi është eliminuar", diff --git a/apps/files_sharing/l10n/sr.php b/apps/files_sharing/l10n/sr.php index 3b97d15419a..e484ad25eb6 100644 --- a/apps/files_sharing/l10n/sr.php +++ b/apps/files_sharing/l10n/sr.php @@ -1,7 +1,6 @@ <?php $TRANSLATIONS = array( "Password" => "Лозинка", -"Submit" => "Пошаљи", "Download" => "Преузми", "Upload" => "Отпреми", "Cancel upload" => "Прекини отпремање" diff --git a/apps/files_sharing/l10n/sr@latin.php b/apps/files_sharing/l10n/sr@latin.php index 1a6be625761..08463e15103 100644 --- a/apps/files_sharing/l10n/sr@latin.php +++ b/apps/files_sharing/l10n/sr@latin.php @@ -1,7 +1,6 @@ <?php $TRANSLATIONS = array( "Password" => "Lozinka", -"Submit" => "Pošalji", "Download" => "Preuzmi", "Upload" => "Pošalji" ); diff --git a/apps/files_sharing/l10n/sv.php b/apps/files_sharing/l10n/sv.php index b8a5f8629a6..055ef552d6b 100644 --- a/apps/files_sharing/l10n/sv.php +++ b/apps/files_sharing/l10n/sv.php @@ -1,8 +1,8 @@ <?php $TRANSLATIONS = array( +"This share is password-protected" => "Den här delningen är lösenordsskyddad", "The password is wrong. Try again." => "Lösenordet är fel. Försök igen.", "Password" => "Lösenord", -"Submit" => "Skicka", "Sorry, this link doesn’t seem to work anymore." => "Tyvärr, denna länk verkar inte fungera längre.", "Reasons might be:" => "Orsaker kan vara:", "the item was removed" => "objektet togs bort", @@ -14,6 +14,7 @@ $TRANSLATIONS = array( "Download" => "Ladda ner", "Upload" => "Ladda upp", "Cancel upload" => "Avbryt uppladdning", -"No preview available for" => "Ingen förhandsgranskning tillgänglig för" +"No preview available for" => "Ingen förhandsgranskning tillgänglig för", +"Direct link" => "Direkt länk" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_sharing/l10n/ta_LK.php b/apps/files_sharing/l10n/ta_LK.php index b4eb0fb7fb8..90a2fb417f4 100644 --- a/apps/files_sharing/l10n/ta_LK.php +++ b/apps/files_sharing/l10n/ta_LK.php @@ -1,7 +1,6 @@ <?php $TRANSLATIONS = array( "Password" => "கடவுச்சொல்", -"Submit" => "சமர்ப்பிக்குக", "%s shared the folder %s with you" => "%s கோப்புறையானது %s உடன் பகிரப்பட்டது", "%s shared the file %s with you" => "%s கோப்பானது %s உடன் பகிரப்பட்டது", "Download" => "பதிவிறக்குக", diff --git a/apps/files_sharing/l10n/th_TH.php b/apps/files_sharing/l10n/th_TH.php index 060bd8bed94..e192e0a97cd 100644 --- a/apps/files_sharing/l10n/th_TH.php +++ b/apps/files_sharing/l10n/th_TH.php @@ -1,7 +1,6 @@ <?php $TRANSLATIONS = array( "Password" => "รหัสผ่าน", -"Submit" => "ส่ง", "%s shared the folder %s with you" => "%s ได้แชร์โฟลเดอร์ %s ให้กับคุณ", "%s shared the file %s with you" => "%s ได้แชร์ไฟล์ %s ให้กับคุณ", "Download" => "ดาวน์โหลด", diff --git a/apps/files_sharing/l10n/tr.php b/apps/files_sharing/l10n/tr.php index a5bcff82cf3..22fe8ed0209 100644 --- a/apps/files_sharing/l10n/tr.php +++ b/apps/files_sharing/l10n/tr.php @@ -1,12 +1,20 @@ <?php $TRANSLATIONS = array( +"This share is password-protected" => "Bu paylaşım parola korumalı", +"The password is wrong. Try again." => "Parola hatalı. Yeniden deneyin.", "Password" => "Parola", -"Submit" => "Gönder", -"%s shared the folder %s with you" => "%s sizinle paylaşılan %s klasör", -"%s shared the file %s with you" => "%s sizinle paylaşılan %s klasör", +"Sorry, this link doesn’t seem to work anymore." => "Üzgünüz, bu bağlantı artık çalışıyor gibi görünmüyor", +"Reasons might be:" => "Sebepleri şunlar olabilir:", +"the item was removed" => "öge kaldırılmış", +"the link expired" => "bağlantı süresi dolmuş", +"sharing is disabled" => "paylaşım devre dışı", +"For more info, please ask the person who sent this link." => "Daha fazla bilgi için bu bağlantıyı aldığınız kişi ile iletişime geçin.", +"%s shared the folder %s with you" => "%s, %s klasörünü sizinle paylaştı", +"%s shared the file %s with you" => "%s, %s dosyasını sizinle paylaştı", "Download" => "İndir", "Upload" => "Yükle", "Cancel upload" => "Yüklemeyi iptal et", -"No preview available for" => "Kullanılabilir önizleme yok" +"No preview available for" => "Kullanılabilir önizleme yok", +"Direct link" => "Doğrudan bağlantı" ); $PLURAL_FORMS = "nplurals=2; plural=(n > 1);"; diff --git a/apps/files_sharing/l10n/ug.php b/apps/files_sharing/l10n/ug.php index 43ee9f77bcd..6ffa02f7344 100644 --- a/apps/files_sharing/l10n/ug.php +++ b/apps/files_sharing/l10n/ug.php @@ -1,7 +1,6 @@ <?php $TRANSLATIONS = array( "Password" => "ئىم", -"Submit" => "تاپشۇر", "Download" => "چۈشۈر", "Upload" => "يۈكلە", "Cancel upload" => "يۈكلەشتىن ۋاز كەچ" diff --git a/apps/files_sharing/l10n/uk.php b/apps/files_sharing/l10n/uk.php index b6a7784c690..842b4b8d961 100644 --- a/apps/files_sharing/l10n/uk.php +++ b/apps/files_sharing/l10n/uk.php @@ -1,12 +1,20 @@ <?php $TRANSLATIONS = array( +"This share is password-protected" => "Цей ресурс обміну захищений паролем", +"The password is wrong. Try again." => "Невірний пароль. Спробуйте ще раз.", "Password" => "Пароль", -"Submit" => "Передати", +"Sorry, this link doesn’t seem to work anymore." => "На жаль, посилання більше не працює.", +"Reasons might be:" => "Можливі причини:", +"the item was removed" => "цей пункт був вилучений", +"the link expired" => "посилання застаріло", +"sharing is disabled" => "обмін заборонений", +"For more info, please ask the person who sent this link." => "Для отримання додаткової інформації, будь ласка, зверніться до особи, яка надіслала це посилання.", "%s shared the folder %s with you" => "%s опублікував каталог %s для Вас", "%s shared the file %s with you" => "%s опублікував файл %s для Вас", "Download" => "Завантажити", "Upload" => "Вивантажити", "Cancel upload" => "Перервати завантаження", -"No preview available for" => "Попередній перегляд недоступний для" +"No preview available for" => "Попередній перегляд недоступний для", +"Direct link" => "Пряме посилання" ); $PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"; diff --git a/apps/files_sharing/l10n/vi.php b/apps/files_sharing/l10n/vi.php index 00e8e094c36..4566d3744de 100644 --- a/apps/files_sharing/l10n/vi.php +++ b/apps/files_sharing/l10n/vi.php @@ -1,7 +1,6 @@ <?php $TRANSLATIONS = array( "Password" => "Mật khẩu", -"Submit" => "Xác nhận", "%s shared the folder %s with you" => "%s đã chia sẻ thư mục %s với bạn", "%s shared the file %s with you" => "%s đã chia sẻ tập tin %s với bạn", "Download" => "Tải về", diff --git a/apps/files_sharing/l10n/zh_CN.php b/apps/files_sharing/l10n/zh_CN.php index f541d6c155a..956c161b48e 100644 --- a/apps/files_sharing/l10n/zh_CN.php +++ b/apps/files_sharing/l10n/zh_CN.php @@ -2,7 +2,6 @@ $TRANSLATIONS = array( "The password is wrong. Try again." => "用户名或密码错误!请重试", "Password" => "密码", -"Submit" => "提交", "Sorry, this link doesn’t seem to work anymore." => "抱歉,此链接已失效", "Reasons might be:" => "可能原因是:", "the item was removed" => "此项已移除", diff --git a/apps/files_sharing/l10n/zh_TW.php b/apps/files_sharing/l10n/zh_TW.php index 5cc33fd3830..3854b7ae582 100644 --- a/apps/files_sharing/l10n/zh_TW.php +++ b/apps/files_sharing/l10n/zh_TW.php @@ -1,8 +1,8 @@ <?php $TRANSLATIONS = array( +"This share is password-protected" => "這個分享有密碼保護", "The password is wrong. Try again." => "請檢查您的密碼並再試一次", "Password" => "密碼", -"Submit" => "送出", "Sorry, this link doesn’t seem to work anymore." => "抱歉,此連結已經失效", "Reasons might be:" => "可能的原因:", "the item was removed" => "項目已經移除", diff --git a/apps/files_sharing/lib/api.php b/apps/files_sharing/lib/api.php index e6624624898..84e90c71681 100644 --- a/apps/files_sharing/lib/api.php +++ b/apps/files_sharing/lib/api.php @@ -31,15 +31,22 @@ class Api { * @return \OC_OCS_Result share information */ public static function getAllShares($params) { - // if a file is specified, get the share for this file if (isset($_GET['path'])) { $params['itemSource'] = self::getFileId($_GET['path']); $params['path'] = $_GET['path']; - if (isset($_GET['subfiles']) && $_GET['subfiles'] === 'true') { + $params['itemType'] = self::getItemType($_GET['path']); + + if ( isset($_GET['reshares']) && $_GET['reshares'] !== 'false' ) { + $params['reshares'] = true; + } else { + $params['reshares'] = false; + } + + if (isset($_GET['subfiles']) && $_GET['subfiles'] !== 'false') { return self::getSharesFromFolder($params); } - return self::getShare($params); + return self::collectShares($params); } $share = \OCP\Share::getItemShared('file', null); @@ -60,28 +67,49 @@ class Api { */ public static function getShare($params) { - // either the $params already contains a itemSource if we come from - // getAllShare() or we need to translate the shareID to a itemSource - if(isset($params['itemSource'])) { - $itemSource = $params['itemSource']; - $getSpecificShare = true; - } else { - $s = self::getShareFromId($params['id']); - $itemSource = $s['item_source']; - $getSpecificShare = false; - } + $s = self::getShareFromId($params['id']); + $params['itemSource'] = $s['item_source']; + $params['itemType'] = $s['item_type']; + $params['specificShare'] = true; + + return self::collectShares($params); + } + + /** + * @brief collect all share information, either of a specific share or all + * shares for a given path + * @param array $params + * @return \OC_OCS_Result + */ + private static function collectShares($params) { + + $itemSource = $params['itemSource']; + $itemType = $params['itemType']; + $getSpecificShare = isset($params['specificShare']) ? $params['specificShare'] : false; if ($itemSource !== null) { - $shares = \OCP\Share::getItemShared('file', $itemSource); + $shares = \OCP\Share::getItemShared($itemType, $itemSource); + $receivedFrom = \OCP\Share::getItemSharedWithBySource($itemType, $itemSource); // if a specific share was specified only return this one - if ($getSpecificShare === false) { + if ($getSpecificShare === true) { foreach ($shares as $share) { - if ($share['id'] === (int)$params['id']) { + if ($share['id'] === (int) $params['id']) { $shares = array('element' => $share); break; } } } + + // include also reshares in the lists. This means that the result + // will contain every user with access to the file. + if (isset($params['reshares']) && $params['reshares'] === true) { + $shares = self::addReshares($shares, $itemSource); + } + + if ($receivedFrom) { + $shares['received_from'] = $receivedFrom['uid_owner']; + $shares['received_from_displayname'] = \OCP\User::getDisplayName($receivedFrom['uid_owner']); + } } else { $shares = null; } @@ -94,6 +122,37 @@ class Api { } /** + * @brief add reshares to a array of shares + * @param array $shares array of shares + * @param int $itemSource item source ID + * @return array new shares array which includes reshares + */ + private static function addReshares($shares, $itemSource) { + + // if there are no shares than there are also no reshares + $firstShare = reset($shares); + if ($firstShare) { + $path = $firstShare['path']; + } else { + return $shares; + } + + $select = '`*PREFIX*share`.`id`, `item_type`, `*PREFIX*share`.`parent`, `share_type`, `share_with`, `file_source`, `path` , `permissions`, `stime`, `expiration`, `token`, `storage`, `mail_send`, `mail_send`'; + $getReshares = \OC_DB::prepare('SELECT ' . $select . ' FROM `*PREFIX*share` INNER JOIN `*PREFIX*filecache` ON `file_source` = `*PREFIX*filecache`.`fileid` WHERE `*PREFIX*share`.`file_source` = ? AND `*PREFIX*share`.`item_type` IN (\'file\', \'folder\') AND `uid_owner` != ?'); + $reshares = $getReshares->execute(array($itemSource, \OCP\User::getUser()))->fetchAll(); + + foreach ($reshares as $key => $reshare) { + if (isset($reshare['share_with']) && $reshare['share_with'] !== '') { + $reshares[$key]['share_with_displayname'] = \OCP\User::getDisplayName($reshare['share_with']); + } + // add correct path to the result + $reshares[$key]['path'] = $path; + } + + return array_merge($shares, $reshares); + } + + /** * @brief get share from all files in a given folder (non-recursive) * @param array $params contains 'path' to the folder * @return \OC_OCS_Result @@ -110,7 +169,14 @@ class Api { $result = array(); foreach ($content as $file) { - $share = \OCP\Share::getItemShared('file', $file['fileid']); + // workaround because folders are named 'dir' in this context + $itemType = $file['type'] === 'file' ? 'file' : 'folder'; + $share = \OCP\Share::getItemShared($itemType, $file['fileid']); + $receivedFrom = \OCP\Share::getItemSharedWithBySource($itemType, $file['fileid']); + if ($receivedFrom) { + $share['received_from'] = $receivedFrom['uid_owner']; + $share['received_from_displayname'] = \OCP\User::getDisplayName($receivedFrom['uid_owner']); + } if ($share) { $share['filename'] = $file['name']; $result[] = $share; @@ -132,7 +198,6 @@ class Api { if($path === null) { return new \OC_OCS_Result(null, 400, "please specify a file or folder path"); } - $itemSource = self::getFileId($path); $itemType = self::getItemType($path); @@ -184,7 +249,7 @@ class Api { if ($token) { $data = array(); $data['id'] = 'unknown'; - $shares = \OCP\Share::getItemShared('file', $itemSource); + $shares = \OCP\Share::getItemShared($itemType, $itemSource); if(is_string($token)) { //public link share foreach ($shares as $share) { if ($share['token'] === $token) { @@ -414,7 +479,6 @@ class Api { $view = new \OC\Files\View('/'.\OCP\User::getUser().'/files'); $fileId = null; - $fileInfo = $view->getFileInfo($path); if ($fileInfo) { $fileId = $fileInfo['fileid']; diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index 123268e240a..90440d08f4e 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -99,9 +99,13 @@ class Shared_Cache extends Cache { $data['fileid'] = (int)$data['fileid']; $data['size'] = (int)$data['size']; $data['mtime'] = (int)$data['mtime']; + $data['storage_mtime'] = (int)$data['storage_mtime']; $data['encrypted'] = (bool)$data['encrypted']; $data['mimetype'] = $this->getMimetype($data['mimetype']); $data['mimepart'] = $this->getMimetype($data['mimepart']); + if ($data['storage_mtime'] === 0) { + $data['storage_mtime'] = $data['mtime']; + } return $data; } return false; @@ -228,69 +232,73 @@ class Shared_Cache extends Cache { */ public function search($pattern) { - // normalize pattern - $pattern = $this->normalize($pattern); + $where = '`name` LIKE ? AND '; - $ids = $this->getAll(); + // normalize pattern + $value = $this->normalize($pattern); - $files = array(); - - // divide into 1k chunks - $chunks = array_chunk($ids, 1000); - - foreach ($chunks as $chunk) { - $placeholders = join(',', array_fill(0, count($chunk), '?')); + return $this->searchWithWhere($where, $value); - $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, - `encrypted`, `unencrypted_size`, `etag` - FROM `*PREFIX*filecache` WHERE `name` LIKE ? AND `fileid` IN (' . $placeholders . ')'; - - $result = \OC_DB::executeAudited($sql, array_merge(array($pattern), $chunk)); - - while ($row = $result->fetchRow()) { - if (substr($row['path'], 0, 6)==='files/') { - $row['path'] = substr($row['path'],6); // remove 'files/' from path as it's relative to '/Shared' - } - $row['mimetype'] = $this->getMimetype($row['mimetype']); - $row['mimepart'] = $this->getMimetype($row['mimepart']); - $files[] = $row; - } - } - return $files; } /** * search for files by mimetype * - * @param string $part1 - * @param string $part2 + * @param string $mimetype * @return array */ public function searchByMime($mimetype) { + if (strpos($mimetype, '/')) { - $where = '`mimetype` = ?'; + $where = '`mimetype` = ? AND '; } else { - $where = '`mimepart` = ?'; + $where = '`mimepart` = ? AND '; } - $mimetype = $this->getMimetypeId($mimetype); + + $value = $this->getMimetypeId($mimetype); + + return $this->searchWithWhere($where, $value); + + } + + /** + * The maximum number of placeholders that can be used in an SQL query. + * Value MUST be <= 1000 for oracle: + * see ORA-01795 maximum number of expressions in a list is 1000 + * FIXME we should get this from doctrine as other DBs allow a lot more placeholders + */ + const MAX_SQL_CHUNK_SIZE = 1000; + + /** + * search for files with a custom where clause and value + * the $wherevalue will be array_merge()d with the file id chunks + * + * @param string $sqlwhere + * @param string $wherevalue + * @return array + */ + private function searchWithWhere($sqlwhere, $wherevalue, $chunksize = self::MAX_SQL_CHUNK_SIZE) { + $ids = $this->getAll(); $files = array(); - // divide into 1k chunks - $chunks = array_chunk($ids, 1000); + // divide into chunks + $chunks = array_chunk($ids, $chunksize); foreach ($chunks as $chunk) { - $placeholders = join(',', array_fill(0, count($ids), '?')); + $placeholders = join(',', array_fill(0, count($chunk), '?')); $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `unencrypted_size`, `etag` - FROM `*PREFIX*filecache` WHERE ' . $where . ' AND `fileid` IN (' . $placeholders . ')'; + FROM `*PREFIX*filecache` WHERE ' . $sqlwhere . ' `fileid` IN (' . $placeholders . ')'; - $result = \OC_DB::executeAudited($sql, array_merge(array($mimetype), $chunk)); + $stmt = \OC_DB::prepare($sql); + + $result = $stmt->execute(array_merge(array($wherevalue), $chunk)); while ($row = $result->fetchRow()) { - if (substr($row['path'], 0, 6)==='files/') { - $row['path'] = substr($row['path'],6); // remove 'files/' from path as it's relative to '/Shared' + if (substr($row['path'], 0, 6) === 'files/') { + $row['path'] = substr($row['path'], 6); // remove 'files/' from path as it's relative to '/Shared' } $row['mimetype'] = $this->getMimetype($row['mimetype']); $row['mimepart'] = $this->getMimetype($row['mimepart']); diff --git a/apps/files_sharing/lib/maintainer.php b/apps/files_sharing/lib/maintainer.php new file mode 100644 index 00000000000..bbb3268410e --- /dev/null +++ b/apps/files_sharing/lib/maintainer.php @@ -0,0 +1,44 @@ +<?php +/** + * ownCloud + * + * @author Morris Jobke + * @copyright 2013 Morris Jobke morris.jobke@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library 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 along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +namespace OCA\Files\Share; + +/** + * Maintains stuff around the sharing functionality + * + * for example: on disable of "allow links" it removes all link shares + */ + +class Maintainer { + + /** + * Keeps track of the "allow links" config setting + * and removes all link shares if the config option is set to "no" + * + * @param array with app, key, value as named values + */ + static public function configChangeHook($params) { + if($params['app'] === 'core' && $params['key'] === 'shareapi_allow_links' && $params['value'] === 'no') { + \OCP\Share::removeAllLinkShares(); + } + } + +} diff --git a/apps/files_sharing/lib/permissions.php b/apps/files_sharing/lib/permissions.php index e2978e12bfb..1dc53428a7f 100644 --- a/apps/files_sharing/lib/permissions.php +++ b/apps/files_sharing/lib/permissions.php @@ -42,6 +42,19 @@ class Shared_Permissions extends Permissions { } } + private function getFile($fileId, $user) { + if ($fileId == -1) { + return \OCP\PERMISSION_READ; + } + $source = \OCP\Share::getItemSharedWithBySource('file', $fileId, \OC_Share_Backend_File::FORMAT_SHARED_STORAGE, + null, false); + if ($source) { + return $source['permissions']; + } else { + return -1; + } + } + /** * set the permissions of a file * @@ -82,7 +95,7 @@ class Shared_Permissions extends Permissions { if ($parentId === -1) { return \OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_File::FORMAT_PERMISSIONS); } - $permissions = $this->get($parentId, $user); + $permissions = $this->getFile($parentId, $user); $query = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `parent` = ?'); $result = $query->execute(array($parentId)); $filePermissions = array(); diff --git a/apps/files_sharing/lib/share/file.php b/apps/files_sharing/lib/share/file.php index 07e7a4ca0c5..c956c55a1df 100644 --- a/apps/files_sharing/lib/share/file.php +++ b/apps/files_sharing/lib/share/file.php @@ -172,7 +172,7 @@ class OC_Share_Backend_File implements OCP\Share_Backend_File_Dependent { $source['fileOwner'] = $fileOwner; return $source; } - \OCP\Util::writeLog('files_sharing', 'File source not found for: '.$target, \OCP\Util::ERROR); + \OCP\Util::writeLog('files_sharing', 'File source not found for: '.$target, \OCP\Util::DEBUG); return false; } diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 257da89c84e..afe5dffdebd 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -34,16 +34,16 @@ class Shared extends \OC\Files\Storage\Common { $this->sharedFolder = $arguments['sharedFolder']; } - public function getId(){ + public function getId() { return 'shared::' . $this->sharedFolder; } /** - * @brief Get the source file path, permissions, and owner for a shared file - * @param string Shared target file path - * @return Returns array with the keys path, permissions, and owner or false if not found - */ - private function getFile($target) { + * @brief Get the source file path, permissions, and owner for a shared file + * @param string Shared target file path + * @return Returns array with the keys path, permissions, and owner or false if not found + */ + public function getFile($target) { if (!isset($this->files[$target])) { // Check for partial files if (pathinfo($target, PATHINFO_EXTENSION) === 'part') { @@ -62,18 +62,18 @@ class Shared extends \OC\Files\Storage\Common { } /** - * @brief Get the source file path for a shared file - * @param string Shared target file path - * @return string source file path or false if not found - */ - private function getSourcePath($target) { + * @brief Get the source file path for a shared file + * @param string Shared target file path + * @return string source file path or false if not found + */ + public function getSourcePath($target) { $source = $this->getFile($target); if ($source) { if (!isset($source['fullPath'])) { \OC\Files\Filesystem::initMountPoints($source['fileOwner']); $mount = \OC\Files\Filesystem::getMountByNumericId($source['storage']); if (is_array($mount)) { - $this->files[$target]['fullPath'] = $mount[key($mount)]->getMountPoint().$source['path']; + $this->files[$target]['fullPath'] = $mount[key($mount)]->getMountPoint() . $source['path']; } else { $this->files[$target]['fullPath'] = false; } @@ -84,10 +84,10 @@ class Shared extends \OC\Files\Storage\Common { } /** - * @brief Get the permissions granted for a shared file - * @param string Shared target file path - * @return int CRUDS permissions granted or false if not found - */ + * @brief Get the permissions granted for a shared file + * @param string Shared target file path + * @return int CRUDS permissions granted or false if not found + */ public function getPermissions($target) { $source = $this->getFile($target); if ($source) { @@ -222,7 +222,7 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/') { $mtime = 0; $dh = $this->opendir($path); - if(is_resource($dh)) { + if (is_resource($dh)) { while (($filename = readdir($dh)) !== false) { $tempmtime = $this->filemtime($filename); if ($tempmtime > $mtime) { @@ -244,7 +244,7 @@ class Shared extends \OC\Files\Storage\Common { $source = $this->getSourcePath($path); if ($source) { $info = array( - 'target' => $this->sharedFolder.$path, + 'target' => $this->sharedFolder . $path, 'source' => $source, ); \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_get_contents', $info); @@ -257,13 +257,14 @@ class Shared extends \OC\Files\Storage\Common { if ($source = $this->getSourcePath($path)) { // Check if permission is granted if (($this->file_exists($path) && !$this->isUpdatable($path)) - || ($this->is_dir($path) && !$this->isCreatable($path))) { + || ($this->is_dir($path) && !$this->isCreatable($path)) + ) { return false; } $info = array( - 'target' => $this->sharedFolder.$path, - 'source' => $source, - ); + 'target' => $this->sharedFolder . $path, + 'source' => $source, + ); \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_put_contents', $info); list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); $result = $storage->file_put_contents($internalPath, $data); @@ -278,58 +279,26 @@ class Shared extends \OC\Files\Storage\Common { if ($this->isDeletable($path)) { list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->unlink($internalPath); - } else if (dirname($path) == '/' || dirname($path) == '.') { - // Unshare the file from the user if in the root of the Shared folder - if ($this->is_dir($path)) { - $itemType = 'folder'; - } else { - $itemType = 'file'; - } - return \OCP\Share::unshareFromSelf($itemType, $path); } } return false; } public function rename($path1, $path2) { - // Check for partial files - if (pathinfo($path1, PATHINFO_EXTENSION) === 'part') { - if ($oldSource = $this->getSourcePath($path1)) { + // Renaming/moving is only allowed within shared folders + $pos1 = strpos($path1, '/', 1); + $pos2 = strpos($path2, '/', 1); + if ($pos1 !== false && $pos2 !== false && ($oldSource = $this->getSourcePath($path1))) { + $newSource = $this->getSourcePath(dirname($path2)) . '/' . basename($path2); + // Within the same folder, we only need UPDATE permissions + if (dirname($path1) == dirname($path2) and $this->isUpdatable($path1)) { list($storage, $oldInternalPath) = \OC\Files\Filesystem::resolvePath($oldSource); - $newInternalPath = substr($oldInternalPath, 0, -5); + list(, $newInternalPath) = \OC\Files\Filesystem::resolvePath($newSource); return $storage->rename($oldInternalPath, $newInternalPath); - } - } else { - // Renaming/moving is only allowed within shared folders - $pos1 = strpos($path1, '/', 1); - $pos2 = strpos($path2, '/', 1); - if ($pos1 !== false && $pos2 !== false && ($oldSource = $this->getSourcePath($path1))) { - $newSource = $this->getSourcePath(dirname($path2)).'/'.basename($path2); - if (dirname($path1) == dirname($path2)) { - // Rename the file if UPDATE permission is granted - if ($this->isUpdatable($path1)) { - list($storage, $oldInternalPath) = \OC\Files\Filesystem::resolvePath($oldSource); - list( , $newInternalPath) = \OC\Files\Filesystem::resolvePath($newSource); - return $storage->rename($oldInternalPath, $newInternalPath); - } - } else { - // Move the file if DELETE and CREATE permissions are granted - if ($this->isDeletable($path1) && $this->isCreatable(dirname($path2))) { - // Get the root shared folder - $folder1 = substr($path1, 0, $pos1); - $folder2 = substr($path2, 0, $pos2); - // Copy and unlink the file if it exists in a different shared folder - if ($folder1 != $folder2) { - if ($this->copy($path1, $path2)) { - return $this->unlink($path1); - } - } else { - list($storage, $oldInternalPath) = \OC\Files\Filesystem::resolvePath($oldSource); - list( , $newInternalPath) = \OC\Files\Filesystem::resolvePath($newSource); - return $storage->rename($oldInternalPath, $newInternalPath); - } - } - } + // otherwise DELETE and CREATE permissions required + } elseif ($this->isDeletable($path1) && $this->isCreatable(dirname($path2))) { + $rootView = new \OC\Files\View(''); + return $rootView->rename($oldSource, $newSource); } } return false; @@ -338,10 +307,10 @@ class Shared extends \OC\Files\Storage\Common { public function copy($path1, $path2) { // Copy the file if CREATE permission is granted if ($this->isCreatable(dirname($path2))) { - $source = $this->fopen($path1, 'r'); - $target = $this->fopen($path2, 'w'); - list ($count, $result) = \OC_Helper::streamCopy($source, $target); - return $result; + $oldSource = $this->getSourcePath($path1); + $newSource = $this->getSourcePath(dirname($path2)) . '/' . basename($path2); + $rootView = new \OC\Files\View(''); + return $rootView->copy($oldSource, $newSource); } return false; } @@ -363,16 +332,16 @@ class Shared extends \OC\Files\Storage\Common { case 'xb': case 'a': case 'ab': - $exists = $this->file_exists($path); - if ($exists && !$this->isUpdatable($path)) { - return false; - } - if (!$exists && !$this->isCreatable(dirname($path))) { - return false; - } + $exists = $this->file_exists($path); + if ($exists && !$this->isUpdatable($path)) { + return false; + } + if (!$exists && !$this->isCreatable(dirname($path))) { + return false; + } } $info = array( - 'target' => $this->sharedFolder.$path, + 'target' => $this->sharedFolder . $path, 'source' => $source, 'mode' => $mode, ); @@ -412,6 +381,7 @@ class Shared extends \OC\Files\Storage\Common { } return false; } + public function touch($path, $mtime = null) { if ($source = $this->getSourcePath($path)) { list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); @@ -422,11 +392,12 @@ class Shared extends \OC\Files\Storage\Common { public static function setup($options) { if (!\OCP\User::isLoggedIn() || \OCP\User::getUser() != $options['user'] - || \OCP\Share::getItemsSharedWith('file')) { + || \OCP\Share::getItemsSharedWith('file') + ) { $user_dir = $options['user_dir']; \OC\Files\Filesystem::mount('\OC\Files\Storage\Shared', array('sharedFolder' => '/Shared'), - $user_dir.'/Shared/'); + $user_dir . '/Shared/'); } } diff --git a/apps/files_sharing/lib/updater.php b/apps/files_sharing/lib/updater.php index a43ab2e2a0a..23ebc9fb811 100644 --- a/apps/files_sharing/lib/updater.php +++ b/apps/files_sharing/lib/updater.php @@ -23,6 +23,9 @@ namespace OC\Files\Cache; class Shared_Updater { + // shares which can be removed from oc_share after the delete operation was successful + static private $toRemove = array(); + /** * Correct the parent folders' ETags for all users shared the file at $target * @@ -32,29 +35,43 @@ class Shared_Updater { $uid = \OCP\User::getUser(); $uidOwner = \OC\Files\Filesystem::getOwner($target); $info = \OC\Files\Filesystem::getFileInfo($target); + $checkedUser = array($uidOwner); // Correct Shared folders of other users shared with $users = \OCP\Share::getUsersItemShared('file', $info['fileid'], $uidOwner, true); if (!empty($users)) { while (!empty($users)) { $reshareUsers = array(); foreach ($users as $user) { - if ( $user !== $uidOwner ) { + if ( !in_array($user, $checkedUser) ) { $etag = \OC\Files\Filesystem::getETag(''); \OCP\Config::setUserValue($user, 'files_sharing', 'etag', $etag); // Look for reshares $reshareUsers = array_merge($reshareUsers, \OCP\Share::getUsersItemShared('file', $info['fileid'], $user, true)); + $checkedUser[] = $user; } } $users = $reshareUsers; } - // Correct folders of shared file owner - $target = substr($target, 8); - if ($uidOwner !== $uid && $source = \OC_Share_Backend_File::getSource($target)) { - \OC\Files\Filesystem::initMountPoints($uidOwner); - $source = '/'.$uidOwner.'/'.$source['path']; - \OC\Files\Cache\Updater::correctFolder($source, $info['mtime']); + } + } + + /** + * @brief remove all shares for a given file if the file was deleted + * + * @param string $path + */ + private static function removeShare($path) { + $fileSource = self::$toRemove[$path]; + + if (!\OC\Files\Filesystem::file_exists($path)) { + $query = \OC_DB::prepare('DELETE FROM `*PREFIX*share` WHERE `file_source`=?'); + try { + \OC_DB::executeAudited($query, array($fileSource)); + } catch (\Exception $e) { + \OCP\Util::writeLog('files_sharing', "can't remove share: " . $e->getMessage(), \OCP\Util::WARN); } } + unset(self::$toRemove[$path]); } /** @@ -77,6 +94,17 @@ class Shared_Updater { */ static public function deleteHook($params) { self::correctFolders($params['path']); + $fileInfo = \OC\Files\Filesystem::getFileInfo($params['path']); + // mark file as deleted so that we can clean up the share table if + // the file was deleted successfully + self::$toRemove[$params['path']] = $fileInfo['fileid']; + } + + /** + * @param array $params + */ + static public function postDeleteHook($params) { + self::removeShare($params['path']); } /** @@ -84,8 +112,12 @@ class Shared_Updater { */ static public function shareHook($params) { if ($params['itemType'] === 'file' || $params['itemType'] === 'folder') { - $uidOwner = \OCP\User::getUser(); - $users = \OCP\Share::getUsersItemShared($params['itemType'], $params['fileSource'], $uidOwner, true); + if (isset($params['uidOwner'])) { + $uidOwner = $params['uidOwner']; + } else { + $uidOwner = \OCP\User::getUser(); + } + $users = \OCP\Share::getUsersItemShared($params['itemType'], $params['fileSource'], $uidOwner, true, false); if (!empty($users)) { while (!empty($users)) { $reshareUsers = array(); diff --git a/apps/files_sharing/lib/watcher.php b/apps/files_sharing/lib/watcher.php index 6fdfc1db36d..c40cf6911b8 100644 --- a/apps/files_sharing/lib/watcher.php +++ b/apps/files_sharing/lib/watcher.php @@ -32,9 +32,32 @@ class Shared_Watcher extends Watcher { * @param string $path */ public function checkUpdate($path) { - if ($path != '') { - parent::checkUpdate($path); + if ($path != '' && parent::checkUpdate($path)) { + // since checkUpdate() has already updated the size of the subdirs, + // only apply the update to the owner's parent dirs + + // find last parent before reaching the shared storage root, + // which is the actual shared dir from the owner + $sepPos = strpos($path, '/'); + if ($sepPos > 0) { + $baseDir = substr($path, 0, $sepPos); + } else { + $baseDir = $path; + } + + // find the path relative to the data dir + $file = $this->storage->getFile($baseDir); + $view = new \OC\Files\View('/' . $file['fileOwner']); + + // find the owner's storage and path + list($storage, $internalPath) = $view->resolvePath($file['path']); + + // update the parent dirs' sizes in the owner's cache + $storage->getCache()->correctFolderSize(dirname($internalPath)); + + return true; } + return false; } /** diff --git a/apps/files_sharing/public.php b/apps/files_sharing/public.php index eff38dcc0fd..ef4345da20e 100644 --- a/apps/files_sharing/public.php +++ b/apps/files_sharing/public.php @@ -28,7 +28,7 @@ function determineIcon($file, $sharingRoot, $sharingToken) { $relativePath = substr($file['path'], 6); $relativePath = substr($relativePath, strlen($sharingRoot)); if($file['isPreviewAvailable']) { - return OCP\publicPreview_icon($relativePath, $sharingToken); + return OCP\publicPreview_icon($relativePath, $sharingToken) . '&c=' . $file['etag']; } return OCP\mimetype_icon($file['mimetype']); } @@ -77,6 +77,7 @@ if (isset($path)) { $hasher = new PasswordHash(8, $forcePortable); if (!($hasher->CheckPassword($password.OC_Config::getValue('passwordsalt', ''), $linkItem['share_with']))) { + OCP\Util::addStyle('files_sharing', 'authenticate'); $tmpl = new OCP\Template('files_sharing', 'authenticate', 'guest'); $tmpl->assign('URL', $url); $tmpl->assign('wrongpw', true); @@ -101,6 +102,7 @@ if (isset($path)) { || \OC::$session->get('public_link_authenticated') !== $linkItem['id'] ) { // Prompt for password + OCP\Util::addStyle('files_sharing', 'authenticate'); $tmpl = new OCP\Template('files_sharing', 'authenticate', 'guest'); $tmpl->assign('URL', $url); $tmpl->printPage(); @@ -109,6 +111,7 @@ if (isset($path)) { } } $basePath = $path; + $rootName = basename($path); if (isset($_GET['path']) && \OC\Files\Filesystem::isReadable($basePath . $_GET['path'])) { $getPath = \OC\Files\Filesystem::normalizePath($_GET['path']); $path .= $getPath; @@ -147,11 +150,9 @@ if (isset($path)) { $tmpl->assign('mimetype', \OC\Files\Filesystem::getMimeType($path)); $tmpl->assign('fileTarget', basename($linkItem['file_target'])); $tmpl->assign('dirToken', $linkItem['token']); + $tmpl->assign('sharingToken', $token); $tmpl->assign('disableSharing', true); $allowPublicUploadEnabled = (bool) ($linkItem['permissions'] & OCP\PERMISSION_CREATE); - if (\OCP\App::isEnabled('files_encryption')) { - $allowPublicUploadEnabled = false; - } if (OC_Appconfig::getValue('core', 'shareapi_allow_public_upload', 'yes') === 'no') { $allowPublicUploadEnabled = false; } @@ -216,8 +217,11 @@ if (isset($path)) { $list->assign('sharingroot', $basePath); $breadcrumbNav = new OCP\Template('files', 'part.breadcrumb', ''); $breadcrumbNav->assign('breadcrumb', $breadcrumb); + $breadcrumbNav->assign('rootBreadCrumb', $rootName); $breadcrumbNav->assign('baseURL', OCP\Util::linkToPublic('files') . $urlLinkIdentifiers . '&path='); $maxUploadFilesize=OCP\Util::maxUploadFilesize($path); + $fileHeader = (!isset($files) or count($files) > 0); + $emptyContent = ($allowPublicUploadEnabled and !$fileHeader); $folder = new OCP\Template('files', 'index', ''); $folder->assign('fileList', $list->fetchPage()); $folder->assign('breadcrumb', $breadcrumbNav->fetchPage()); @@ -231,9 +235,15 @@ if (isset($path)) { $folder->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize)); $folder->assign('allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true))); $folder->assign('usedSpacePercent', 0); + $folder->assign('fileHeader', $fileHeader); + $folder->assign('disableSharing', true); + $folder->assign('trash', false); + $folder->assign('emptyContent', $emptyContent); + $folder->assign('ajaxLoad', false); $tmpl->assign('folder', $folder->fetchPage()); + $maxInputFileSize = OCP\Config::getSystemValue('maxZipInputSize', OCP\Util::computerFileSize('800 MB')); $allowZip = OCP\Config::getSystemValue('allowZipDownload', true) - && $totalSize <= OCP\Config::getSystemValue('maxZipInputSize', OCP\Util::computerFileSize('800 MB')); + && ( $maxInputFileSize === 0 || $totalSize <= $maxInputFileSize); $tmpl->assign('allowZipDownload', intval($allowZip)); $tmpl->assign('downloadURL', OCP\Util::linkToPublic('files') . $urlLinkIdentifiers . '&download&path=' . urlencode($getPath)); diff --git a/apps/files_sharing/templates/authenticate.php b/apps/files_sharing/templates/authenticate.php index 2c89b5df3f6..6b98e6c9f34 100644 --- a/apps/files_sharing/templates/authenticate.php +++ b/apps/files_sharing/templates/authenticate.php @@ -1,12 +1,15 @@ <form action="<?php p($_['URL']); ?>" method="post"> <fieldset> + <?php if (!isset($_['wrongpw'])): ?> + <div class="warning-info"><?php p($l->t('This share is password-protected')); ?></div> + <?php endif; ?> <?php if (isset($_['wrongpw'])): ?> - <div class="warning"><?php p($l->t('The password is wrong. Try again.')); ?></div> + <div class="warning"><?php p($l->t('The password is wrong. Try again.')); ?></div> <?php endif; ?> <p class="infield"> <label for="password" class="infield"><?php p($l->t('Password')); ?></label> <input type="password" name="password" id="password" placeholder="" value="" autofocus /> - <input type="submit" value="<?php p($l->t('Submit')); ?>" /> + <input type="submit" value="" class="svg" /> </p> </fieldset> </form> diff --git a/apps/files_sharing/templates/public.php b/apps/files_sharing/templates/public.php index c164b3ea2b7..1d527dca8eb 100644 --- a/apps/files_sharing/templates/public.php +++ b/apps/files_sharing/templates/public.php @@ -2,8 +2,11 @@ <div id="notification" style="display: none;"></div> </div> +<input type="hidden" id="filesApp" name="filesApp" value="1"> +<input type="hidden" id="isPublic" name="isPublic" value="1"> <input type="hidden" name="dir" value="<?php p($_['dir']) ?>" id="dir"> <input type="hidden" name="downloadURL" value="<?php p($_['downloadURL']) ?>" id="downloadURL"> +<input type="hidden" name="sharingToken" value="<?php p($_['sharingToken']) ?>" id="sharingToken"> <input type="hidden" name="filename" value="<?php p($_['filename']) ?>" id="filename"> <input type="hidden" name="mimetype" value="<?php p($_['mimetype']) ?>" id="mimetype"> <header><div id="header"> @@ -13,10 +16,10 @@ <div class="header-right"> <?php if (isset($_['folder'])): ?> <span id="details"><?php p($l->t('%s shared the folder %s with you', - array($_['displayName'], $_['fileTarget']))) ?></span> + array($_['displayName'], $_['filename']))) ?></span> <?php else: ?> <span id="details"><?php p($l->t('%s shared the file %s with you', - array($_['displayName'], $_['fileTarget']))) ?></span> + array($_['displayName'], $_['filename']))) ?></span> <?php endif; ?> @@ -86,13 +89,14 @@ <?php else: ?> <ul id="noPreview"> <li class="error"> - <?php p($l->t('No preview available for').' '.$_['fileTarget']); ?><br /> + <?php p($l->t('No preview available for').' '.$_['filename']); ?><br /> <a href="<?php p($_['downloadURL']); ?>" id="download"><img class="svg" alt="Download" src="<?php print_unescaped(OCP\image_path("core", "actions/download.svg")); ?>" /><?php p($l->t('Download'))?></a> </li> </ul> <?php endif; ?> + <div class="directLink"><label for="directLink"><?php p($l->t('Direct link')) ?></label><input id="directLink" type="text" readonly value="<?php p($_['downloadURL']); ?>"></input></div> <?php endif; ?> </div> <footer> diff --git a/apps/files_sharing/tests/api.php b/apps/files_sharing/tests/api.php index c55c186f089..1278e0c4d1f 100644 --- a/apps/files_sharing/tests/api.php +++ b/apps/files_sharing/tests/api.php @@ -20,83 +20,33 @@ * */ -require_once __DIR__ . '/../../../lib/base.php'; +require_once __DIR__ . '/base.php'; use OCA\Files\Share; /** * Class Test_Files_Sharing_Api */ -class Test_Files_Sharing_Api extends \PHPUnit_Framework_TestCase { - - const TEST_FILES_SHARING_API_USER1 = "test-share-user1"; - const TEST_FILES_SHARING_API_USER2 = "test-share-user2"; - - public $stateFilesEncryption; - public $filename; - public $data; - /** - * @var OC_FilesystemView - */ - public $view; - public $folder; - - public static function setUpBeforeClass() { - // reset backend - \OC_User::clearBackends(); - \OC_User::useBackend('database'); - - // clear share hooks - \OC_Hook::clear('OCP\\Share'); - \OC::registerShareHooks(); - \OCP\Util::connectHook('OC_Filesystem', 'setup', '\OC\Files\Storage\Shared', 'setup'); - - // create users - self::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1, true); - self::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2, true); - - } +class Test_Files_Sharing_Api extends Test_Files_Sharing_Base { function setUp() { - $this->data = 'foobar'; - $this->view = new \OC_FilesystemView('/' . \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1 . '/files'); + parent::setUp(); $this->folder = '/folder_share_api_test'; $this->filename = 'share-api-test.txt'; - // remember files_encryption state - $this->stateFilesEncryption = \OC_App::isEnabled('files_encryption'); - - //we don't want to tests with app files_encryption enabled - \OC_App::disable('files_encryption'); - - - $this->assertTrue(!\OC_App::isEnabled('files_encryption')); - // save file with content $this->view->file_put_contents($this->filename, $this->data); $this->view->mkdir($this->folder); $this->view->file_put_contents($this->folder.'/'.$this->filename, $this->data); - } function tearDown() { $this->view->unlink($this->filename); $this->view->deleteAll($this->folder); - // reset app files_encryption - if ($this->stateFilesEncryption) { - \OC_App::enable('files_encryption'); - } else { - \OC_App::disable('files_encryption'); - } - } - - public static function tearDownAfterClass() { - // cleanup users - \OC_User::deleteUser(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1); - \OC_User::deleteUser(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2); + parent::tearDown(); } /** @@ -104,9 +54,6 @@ class Test_Files_Sharing_Api extends \PHPUnit_Framework_TestCase { */ function testCreateShare() { - //login as user1 - \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1); - // share to user // simulate a post request @@ -196,9 +143,9 @@ class Test_Files_Sharing_Api extends \PHPUnit_Framework_TestCase { \OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_LINK, null, 1); - $params = array('itemSource' => $fileInfo['fileid']); + $_GET['path'] = $this->filename; - $result = Share\Api::getShare($params); + $result = Share\Api::getAllShares(array()); $this->assertTrue($result->succeeded()); @@ -216,6 +163,60 @@ class Test_Files_Sharing_Api extends \PHPUnit_Framework_TestCase { * @medium * @depends testCreateShare */ + function testGetShareFromSourceWithReshares() { + + $fileInfo = $this->view->getFileInfo($this->filename); + + // share the file as user1 to user2 + \OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2, 31); + + // login as user2 and reshare the file to user3 + \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2); + + \OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER3, 31); + + // login as user1 again + \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1); + + $_GET['path'] = $this->filename; + + $result = Share\Api::getAllShares(array()); + + $this->assertTrue($result->succeeded()); + + // test should return one share + $this->assertTrue(count($result->getData()) === 1); + + // now also ask for the reshares + $_GET['reshares'] = 'true'; + + $result = Share\Api::getAllShares(array()); + + $this->assertTrue($result->succeeded()); + + // now we should get two shares, the initial share and the reshare + $this->assertTrue(count($result->getData()) === 2); + + // unshare files again + + \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2); + + \OCP\Share::unshare('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER3); + + \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1); + + \OCP\Share::unshare('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2); + + } + + /** + * @medium + * @depends testCreateShare + */ function testGetShareFromId() { $fileInfo = $this->view->getFileInfo($this->filename); @@ -295,7 +296,8 @@ class Test_Files_Sharing_Api extends \PHPUnit_Framework_TestCase { $result = Share\Api::getShare($params); $this->assertEquals(404, $result->getStatusCode()); - $this->assertEquals('share doesn\'t exist', $result->getMeta()['message']); + $meta = $result->getMeta(); + $this->assertEquals('share doesn\'t exist', $meta['message']); } @@ -351,7 +353,8 @@ class Test_Files_Sharing_Api extends \PHPUnit_Framework_TestCase { $result = Share\Api::updateShare($params); - $this->assertTrue($result->succeeded(), $result->getMeta()['message']); + $meta = $result->getMeta(); + $this->assertTrue($result->succeeded(), $meta['message']); $items = \OCP\Share::getItemShared('file', $userShare['file_source']); @@ -488,50 +491,4 @@ class Test_Files_Sharing_Api extends \PHPUnit_Framework_TestCase { $this->assertTrue(empty($itemsAfterDelete)); } - - /** - * @param $user - * @param bool $create - * @param bool $password - */ - private static function loginHelper($user, $create = false, $password = false) { - if ($create) { - \OC_User::createUser($user, $user); - } - - if ($password === false) { - $password = $user; - } - - \OC_Util::tearDownFS(); - \OC_User::setUserId(''); - \OC\Files\Filesystem::tearDown(); - \OC_Util::setupFS($user); - \OC_User::setUserId($user); - - $params['uid'] = $user; - $params['password'] = $password; - } - - /** - * @brief get some information from a given share - * @param int $shareID - * @return array with: item_source, share_type, share_with, item_type, permissions - */ - private function getShareFromId($shareID) { - $sql = 'SELECT `item_source`, `share_type`, `share_with`, `item_type`, `permissions` FROM `*PREFIX*share` WHERE `id` = ?'; - $args = array($shareID); - $query = \OCP\DB::prepare($sql); - $result = $query->execute($args); - - $share = Null; - - if ($result && $result->numRows() > 0) { - $share = $result->fetchRow(); - } - - return $share; - - } - } diff --git a/apps/files_sharing/tests/base.php b/apps/files_sharing/tests/base.php new file mode 100644 index 00000000000..3e283271f5d --- /dev/null +++ b/apps/files_sharing/tests/base.php @@ -0,0 +1,143 @@ +<?php +/** + * ownCloud + * + * @author Bjoern Schiessle + * @copyright 2013 Bjoern Schiessle <schiessle@owncloud.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library 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 along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +require_once __DIR__ . '/../../../lib/base.php'; + +use OCA\Files\Share; + +/** + * Class Test_Files_Sharing_Base + * + * Base class for sharing tests. + */ +abstract class Test_Files_Sharing_Base extends \PHPUnit_Framework_TestCase { + + const TEST_FILES_SHARING_API_USER1 = "test-share-user1"; + const TEST_FILES_SHARING_API_USER2 = "test-share-user2"; + const TEST_FILES_SHARING_API_USER3 = "test-share-user3"; + + public $stateFilesEncryption; + public $filename; + public $data; + /** + * @var OC_FilesystemView + */ + public $view; + public $folder; + + public static function setUpBeforeClass() { + // reset backend + \OC_User::clearBackends(); + \OC_User::useBackend('database'); + + // clear share hooks + \OC_Hook::clear('OCP\\Share'); + \OC::registerShareHooks(); + \OCP\Util::connectHook('OC_Filesystem', 'setup', '\OC\Files\Storage\Shared', 'setup'); + + // create users + self::loginHelper(self::TEST_FILES_SHARING_API_USER1, true); + self::loginHelper(self::TEST_FILES_SHARING_API_USER2, true); + self::loginHelper(self::TEST_FILES_SHARING_API_USER3, true); + + } + + function setUp() { + + //login as user1 + self::loginHelper(self::TEST_FILES_SHARING_API_USER1); + + $this->data = 'foobar'; + $this->view = new \OC_FilesystemView('/' . self::TEST_FILES_SHARING_API_USER1 . '/files'); + // remember files_encryption state + $this->stateFilesEncryption = \OC_App::isEnabled('files_encryption'); + + //we don't want to tests with app files_encryption enabled + \OC_App::disable('files_encryption'); + + + $this->assertTrue(!\OC_App::isEnabled('files_encryption')); + } + + function tearDown() { + // reset app files_encryption + if ($this->stateFilesEncryption) { + \OC_App::enable('files_encryption'); + } else { + \OC_App::disable('files_encryption'); + } + } + + public static function tearDownAfterClass() { + + // cleanup users + \OC_User::deleteUser(self::TEST_FILES_SHARING_API_USER1); + \OC_User::deleteUser(self::TEST_FILES_SHARING_API_USER2); + \OC_User::deleteUser(self::TEST_FILES_SHARING_API_USER3); + } + + /** + * @param $user + * @param bool $create + * @param bool $password + */ + protected static function loginHelper($user, $create = false, $password = false) { + if ($create) { + \OC_User::createUser($user, $user); + } + + if ($password === false) { + $password = $user; + } + + \OC_Util::tearDownFS(); + \OC_User::setUserId(''); + \OC\Files\Filesystem::tearDown(); + \OC_Util::setupFS($user); + \OC_User::setUserId($user); + + $params['uid'] = $user; + $params['password'] = $password; + } + + /** + * @brief get some information from a given share + * @param int $shareID + * @return array with: item_source, share_type, share_with, item_type, permissions + */ + protected function getShareFromId($shareID) { + $sql = 'SELECT `item_source`, `share_type`, `share_with`, `item_type`, `permissions` FROM `*PREFIX*share` WHERE `id` = ?'; + $args = array($shareID); + $query = \OCP\DB::prepare($sql); + $result = $query->execute($args); + + $share = Null; + + if ($result) { + $share = $result->fetchRow(); + } + + return $share; + + } + +} diff --git a/apps/files_sharing/tests/permissions.php b/apps/files_sharing/tests/permissions.php new file mode 100644 index 00000000000..e301d384a49 --- /dev/null +++ b/apps/files_sharing/tests/permissions.php @@ -0,0 +1,110 @@ +<?php +/** + * ownCloud + * + * @author Vincent Petry + * @copyright 2013 Vincent Petry <pvince81@owncloud.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library 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 along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ +require_once __DIR__ . '/base.php'; + +class Test_Files_Sharing_Permissions extends Test_Files_Sharing_Base { + + function setUp() { + parent::setUp(); + + self::loginHelper(self::TEST_FILES_SHARING_API_USER1); + + // prepare user1's dir structure + $textData = "dummy file data\n"; + $this->view->mkdir('container'); + $this->view->mkdir('container/shareddir'); + $this->view->mkdir('container/shareddir/subdir'); + $this->view->mkdir('container/shareddirrestricted'); + $this->view->mkdir('container/shareddirrestricted/subdir'); + $this->view->file_put_contents('container/shareddir/textfile.txt', $textData); + $this->view->file_put_contents('container/shareddirrestricted/textfile1.txt', $textData); + + list($this->ownerStorage, $internalPath) = $this->view->resolvePath(''); + $this->ownerCache = $this->ownerStorage->getCache(); + $this->ownerStorage->getScanner()->scan(''); + + // share "shareddir" with user2 + $fileinfo = $this->view->getFileInfo('container/shareddir'); + \OCP\Share::shareItem('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + self::TEST_FILES_SHARING_API_USER2, 31); + $fileinfo2 = $this->view->getFileInfo('container/shareddirrestricted'); + \OCP\Share::shareItem('folder', $fileinfo2['fileid'], \OCP\Share::SHARE_TYPE_USER, + self::TEST_FILES_SHARING_API_USER2, 7); + + // login as user2 + self::loginHelper(self::TEST_FILES_SHARING_API_USER2); + + // retrieve the shared storage + $this->secondView = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2); + list($this->sharedStorage, $internalPath) = $this->secondView->resolvePath('files/Shared/shareddir'); + $this->sharedCache = $this->sharedStorage->getCache(); + } + + function tearDown() { + $this->sharedCache->clear(); + + self::loginHelper(self::TEST_FILES_SHARING_API_USER1); + + $fileinfo = $this->view->getFileInfo('container/shareddir'); + \OCP\Share::unshare('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + self::TEST_FILES_SHARING_API_USER2); + $fileinfo2 = $this->view->getFileInfo('container/shareddirrestricted'); + \OCP\Share::unshare('folder', $fileinfo2['fileid'], \OCP\Share::SHARE_TYPE_USER, + self::TEST_FILES_SHARING_API_USER2); + + $this->view->deleteAll('container'); + + $this->ownerCache->clear(); + + parent::tearDown(); + } + + /** + * Test that the permissions of shared directory are returned correctly + */ + function testGetPermissions() { + $sharedDirPerms = $this->sharedStorage->getPermissions('shareddir'); + $this->assertEquals(31, $sharedDirPerms); + $sharedDirPerms = $this->sharedStorage->getPermissions('shareddir/textfile.txt'); + $this->assertEquals(31, $sharedDirPerms); + $sharedDirRestrictedPerms = $this->sharedStorage->getPermissions('shareddirrestricted'); + $this->assertEquals(7, $sharedDirRestrictedPerms); + $sharedDirRestrictedPerms = $this->sharedStorage->getPermissions('shareddirrestricted/textfile.txt'); + $this->assertEquals(7, $sharedDirRestrictedPerms); + } + + /** + * Test that the permissions of shared directory are returned correctly + */ + function testGetDirectoryPermissions() { + $contents = $this->secondView->getDirectoryContent('files/Shared/shareddir'); + $this->assertEquals('subdir', $contents[0]['name']); + $this->assertEquals(31, $contents[0]['permissions']); + $this->assertEquals('textfile.txt', $contents[1]['name']); + $this->assertEquals(31, $contents[1]['permissions']); + $contents = $this->secondView->getDirectoryContent('files/Shared/shareddirrestricted'); + $this->assertEquals('subdir', $contents[0]['name']); + $this->assertEquals(7, $contents[0]['permissions']); + $this->assertEquals('textfile1.txt', $contents[1]['name']); + $this->assertEquals(7, $contents[1]['permissions']); + } +} diff --git a/apps/files_sharing/tests/watcher.php b/apps/files_sharing/tests/watcher.php new file mode 100644 index 00000000000..1a9a54cbcf8 --- /dev/null +++ b/apps/files_sharing/tests/watcher.php @@ -0,0 +1,161 @@ +<?php +/** + * ownCloud + * + * @author Vincent Petry + * @copyright 2013 Vincent Petry <pvince81@owncloud.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library 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 along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ +require_once __DIR__ . '/base.php'; + +class Test_Files_Sharing_Watcher extends Test_Files_Sharing_Base { + + function setUp() { + parent::setUp(); + + self::loginHelper(self::TEST_FILES_SHARING_API_USER1); + + // prepare user1's dir structure + $textData = "dummy file data\n"; + $this->view->mkdir('container'); + $this->view->mkdir('container/shareddir'); + $this->view->mkdir('container/shareddir/subdir'); + + list($this->ownerStorage, $internalPath) = $this->view->resolvePath(''); + $this->ownerCache = $this->ownerStorage->getCache(); + $this->ownerStorage->getScanner()->scan(''); + + // share "shareddir" with user2 + $fileinfo = $this->view->getFileInfo('container/shareddir'); + \OCP\Share::shareItem('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + self::TEST_FILES_SHARING_API_USER2, 31); + + // login as user2 + self::loginHelper(self::TEST_FILES_SHARING_API_USER2); + + // retrieve the shared storage + $secondView = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2); + list($this->sharedStorage, $internalPath) = $secondView->resolvePath('files/Shared/shareddir'); + $this->sharedCache = $this->sharedStorage->getCache(); + } + + function tearDown() { + $this->sharedCache->clear(); + + self::loginHelper(self::TEST_FILES_SHARING_API_USER1); + + $fileinfo = $this->view->getFileInfo('container/shareddir'); + \OCP\Share::unshare('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + self::TEST_FILES_SHARING_API_USER2); + + $this->view->deleteAll('container'); + + $this->ownerCache->clear(); + + parent::tearDown(); + } + + /** + * Tests that writing a file using the shared storage will propagate the file + * size to the owner's parent folders. + */ + function testFolderSizePropagationToOwnerStorage() { + $initialSizes = self::getOwnerDirSizes('files/container/shareddir'); + + $textData = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; + $dataLen = strlen($textData); + $this->sharedCache->put('shareddir/bar.txt', array('storage_mtime' => 10)); + $this->sharedStorage->file_put_contents('shareddir/bar.txt', $textData); + $this->sharedCache->put('shareddir', array('storage_mtime' => 10)); + + // run the propagation code + $result = $this->sharedStorage->getWatcher()->checkUpdate('shareddir'); + + $this->assertTrue($result); + + // the owner's parent dirs must have increase size + $newSizes = self::getOwnerDirSizes('files/container/shareddir'); + $this->assertEquals($initialSizes[''] + $dataLen, $newSizes['']); + $this->assertEquals($initialSizes['files'] + $dataLen, $newSizes['files']); + $this->assertEquals($initialSizes['files/container'] + $dataLen, $newSizes['files/container']); + $this->assertEquals($initialSizes['files/container/shareddir'] + $dataLen, $newSizes['files/container/shareddir']); + + // no more updates + $result = $this->sharedStorage->getWatcher()->checkUpdate('shareddir'); + + $this->assertFalse($result); + } + + /** + * Tests that writing a file using the shared storage will propagate the file + * size to the owner's parent folders. + */ + function testSubFolderSizePropagationToOwnerStorage() { + $initialSizes = self::getOwnerDirSizes('files/container/shareddir/subdir'); + + $textData = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; + $dataLen = strlen($textData); + $this->sharedCache->put('shareddir/subdir/bar.txt', array('storage_mtime' => 10)); + $this->sharedStorage->file_put_contents('shareddir/subdir/bar.txt', $textData); + $this->sharedCache->put('shareddir/subdir', array('storage_mtime' => 10)); + + // run the propagation code + $result = $this->sharedStorage->getWatcher()->checkUpdate('shareddir/subdir'); + + $this->assertTrue($result); + + // the owner's parent dirs must have increase size + $newSizes = self::getOwnerDirSizes('files/container/shareddir/subdir'); + $this->assertEquals($initialSizes[''] + $dataLen, $newSizes['']); + $this->assertEquals($initialSizes['files'] + $dataLen, $newSizes['files']); + $this->assertEquals($initialSizes['files/container'] + $dataLen, $newSizes['files/container']); + $this->assertEquals($initialSizes['files/container/shareddir'] + $dataLen, $newSizes['files/container/shareddir']); + $this->assertEquals($initialSizes['files/container/shareddir/subdir'] + $dataLen, $newSizes['files/container/shareddir/subdir']); + + // no more updates + $result = $this->sharedStorage->getWatcher()->checkUpdate('shareddir/subdir'); + + $this->assertFalse($result); + } + + function testNoUpdateOnRoot() { + // no updates when called for root path + $result = $this->sharedStorage->getWatcher()->checkUpdate(''); + + $this->assertFalse($result); + + // FIXME: for some reason when running this "naked" test, + // there will be remaining nonsensical entries in the + // database with a path "test-share-user1/container/..." + } + + /** + * Returns the sizes of the path and its parent dirs in a hash + * where the key is the path and the value is the size. + */ + function getOwnerDirSizes($path) { + $result = array(); + + while ($path != '' && $path != '' && $path != '.') { + $cachedData = $this->ownerCache->get($path); + $result[$path] = $cachedData['size']; + $path = dirname($path); + } + $cachedData = $this->ownerCache->get(''); + $result[''] = $cachedData['size']; + return $result; + } +} diff --git a/apps/files_trashbin/ajax/delete.php b/apps/files_trashbin/ajax/delete.php index 92361b65f63..75d481768ad 100644 --- a/apps/files_trashbin/ajax/delete.php +++ b/apps/files_trashbin/ajax/delete.php @@ -3,17 +3,36 @@ OCP\JSON::checkLoggedIn(); OCP\JSON::callCheck(); -$files = $_POST['files']; -$dirlisting = $_POST['dirlisting']; -$list = json_decode($files); - +// "empty trash" command +if (isset($_POST['allfiles']) and $_POST['allfiles'] === 'true'){ + $deleteAll = true; + $folder = isset($_POST['dir']) ? $_POST['dir'] : '/'; + if ($folder === '/' || $folder === '') { + OCA\Files_Trashbin\Trashbin::deleteAll(); + $list = array(); + } else { + $dirname = dirname($folder); + if ( $dirname !== '/' && $dirname !== '.' ) { + $dirlisting = '1'; + } else { + $dirlisting = '0'; + } + $list[] = $folder; + } +} +else { + $deleteAll = false; + $files = $_POST['files']; + $dirlisting = $_POST['dirlisting']; + $list = json_decode($files); +} $error = array(); $success = array(); - $i = 0; foreach ($list as $file) { if ( $dirlisting === '0') { + $file = ltrim($file, '/'); $delimiter = strrpos($file, '.d'); $filename = substr($file, 0, $delimiter); $timestamp = substr($file, $delimiter+2); @@ -23,13 +42,15 @@ foreach ($list as $file) { } OCA\Files_Trashbin\Trashbin::delete($filename, $timestamp); - if (!OCA\Files_Trashbin\Trashbin::file_exists($filename, $timestamp)) { + if (OCA\Files_Trashbin\Trashbin::file_exists($filename, $timestamp)) { + $error[] = $filename; + OC_Log::write('trashbin','can\'t delete ' . $filename . ' permanently.', OC_Log::ERROR); + } + // only list deleted files if not deleting everything + else if (!$deleteAll) { $success[$i]['filename'] = $file; $success[$i]['timestamp'] = $timestamp; $i++; - } else { - $error[] = $filename; - OC_Log::write('trashbin','can\'t delete ' . $filename . ' permanently.', OC_Log::ERROR); } } diff --git a/apps/files_trashbin/ajax/preview.php b/apps/files_trashbin/ajax/preview.php index a0846b051c7..ce432f4d14e 100644 --- a/apps/files_trashbin/ajax/preview.php +++ b/apps/files_trashbin/ajax/preview.php @@ -29,8 +29,14 @@ if($maxX === 0 || $maxY === 0) { } try{ - $preview = new \OC\Preview(\OC_User::getUser(), 'files_trashbin/files'); - $preview->setFile($file); + $preview = new \OC\Preview(\OC_User::getUser(), 'files_trashbin/files', $file); + $view = new \OC\Files\View('/'.\OC_User::getUser(). '/files_trashbin/files'); + if ($view->is_dir($file)) { + $mimetype = 'httpd/unix-directory'; + } else { + $mimetype = \OC_Helper::getFileNameMimeType(pathinfo($file, PATHINFO_FILENAME)); + } + $preview->setMimetype($mimetype); $preview->setMaxX($maxX); $preview->setMaxY($maxY); $preview->setScalingUp($scalingUp); diff --git a/apps/files_trashbin/ajax/undelete.php b/apps/files_trashbin/ajax/undelete.php index e39004cc0d5..876ad269a70 100644 --- a/apps/files_trashbin/ajax/undelete.php +++ b/apps/files_trashbin/ajax/undelete.php @@ -13,6 +13,7 @@ $success = array(); $i = 0; foreach ($list as $file) { if ( $dirlisting === '0') { + $file = ltrim($file, '/'); $delimiter = strrpos($file, '.d'); $filename = substr($file, 0, $delimiter); $timestamp = substr($file, $delimiter+2); diff --git a/apps/files_trashbin/appinfo/info.xml b/apps/files_trashbin/appinfo/info.xml index e9cbdafc1cd..2cc7d9a7ac3 100644 --- a/apps/files_trashbin/appinfo/info.xml +++ b/apps/files_trashbin/appinfo/info.xml @@ -6,7 +6,7 @@ ownCloud keeps a copy of your deleted files in case you need them again. To make sure that the user doesn't run out of memory the deleted files app manages the size of the deleted files for the user. By default deleted files - stay in the trash bin for 180 days. ownCloud checks the age of the files + stay in the trash bin for 90 days. ownCloud checks the age of the files every time a new files gets moved to the deleted files and remove all files older than 180 days. The user can adjust this value in the config.php by setting the "trashbin_retention_obligation" value. diff --git a/apps/files_trashbin/css/trash.css b/apps/files_trashbin/css/trash.css new file mode 100644 index 00000000000..97819f4e80b --- /dev/null +++ b/apps/files_trashbin/css/trash.css @@ -0,0 +1,3 @@ +#fileList td a.file, #fileList td a.file span { + cursor: default; +} diff --git a/apps/files_trashbin/download.php b/apps/files_trashbin/download.php deleted file mode 100644 index 60328e1dddb..00000000000 --- a/apps/files_trashbin/download.php +++ /dev/null @@ -1,51 +0,0 @@ -<?php - -/** -* ownCloud - trash bin -* -* @author Bjoern Schiessle -* @copyright 2013 Bjoern Schiessle schiessle@owncloud.com -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library 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 along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ - -// Check if we are a user -OCP\User::checkLoggedIn(); - -$filename = $_GET["file"]; - -$view = new OC_FilesystemView('/'.\OCP\User::getUser().'/files_trashbin/files'); - -if(!$view->file_exists($filename)) { - header("HTTP/1.0 404 Not Found"); - $tmpl = new OCP\Template( '', '404', 'guest' ); - $tmpl->assign('file', $filename); - $tmpl->printPage(); - exit; -} - -$ftype=$view->getMimeType( $filename ); - -header('Content-Type:'.$ftype);if ( preg_match( "/MSIE/", $_SERVER["HTTP_USER_AGENT"] ) ) { - header( 'Content-Disposition: attachment; filename="' . rawurlencode( basename($filename) ) . '"' ); -} else { - header( 'Content-Disposition: attachment; filename*=UTF-8\'\'' . rawurlencode( basename($filename) ) - . '; filename="' . rawurlencode( basename($filename) ) . '"' ); -} -OCP\Response::disableCaching(); -header('Content-Length: '. $view->filesize($filename)); - -OC_Util::obEnd(); -$view->readfile( $filename ); diff --git a/apps/files_trashbin/index.php b/apps/files_trashbin/index.php index d8661e170a5..93f385dd30b 100644 --- a/apps/files_trashbin/index.php +++ b/apps/files_trashbin/index.php @@ -5,16 +5,17 @@ OCP\User::checkLoggedIn(); OCP\App::setActiveNavigationEntry('files_index'); -OCP\Util::addScript('files_trashbin', 'trash'); OCP\Util::addScript('files_trashbin', 'disableDefaultActions'); OCP\Util::addScript('files', 'fileactions'); $tmpl = new OCP\Template('files_trashbin', 'index', 'user'); OCP\Util::addStyle('files', 'files'); +OCP\Util::addStyle('files_trashbin', 'trash'); OCP\Util::addScript('files', 'filelist'); // filelist overrides OCP\Util::addScript('files_trashbin', 'filelist'); OCP\Util::addscript('files', 'files'); +OCP\Util::addScript('files_trashbin', 'trash'); $dir = isset($_GET['dir']) ? stripslashes($_GET['dir']) : ''; diff --git a/apps/files_trashbin/js/filelist.js b/apps/files_trashbin/js/filelist.js index cd5a67ddfe0..f42abb6d029 100644 --- a/apps/files_trashbin/js/filelist.js +++ b/apps/files_trashbin/js/filelist.js @@ -22,3 +22,10 @@ FileList.reload = function(){ FileList.linkTo = function(dir){ return OC.linkTo('files_trashbin', 'index.php')+"?dir="+ encodeURIComponent(dir).replace(/%2F/g, '/'); } + +FileList.updateEmptyContent = function(){ + var $fileList = $('#fileList'); + var exists = $fileList.find('tr:first').exists(); + $('#emptycontent').toggleClass('hidden', exists); + $('#filestable th').toggleClass('hidden', !exists); +} diff --git a/apps/files_trashbin/js/trash.js b/apps/files_trashbin/js/trash.js index d73eadb6011..46d8b56308c 100644 --- a/apps/files_trashbin/js/trash.js +++ b/apps/files_trashbin/js/trash.js @@ -3,15 +3,40 @@ $(document).ready(function() { if (typeof FileActions !== 'undefined') { FileActions.register('all', 'Restore', OC.PERMISSION_READ, OC.imagePath('core', 'actions/history'), function(filename) { - var tr=$('tr').filterAttr('data-file', filename); - var spinner = '<img class="move2trash" title="'+t('files_trashbin', 'perform restore operation')+'" src="'+ OC.imagePath('core', 'loading.gif') +'"></a>'; - var undeleteAction = $('tr').filterAttr('data-file',filename).children("td.date"); - var files = tr.attr('data-file'); - undeleteAction[0].innerHTML = undeleteAction[0].innerHTML+spinner; + var tr = FileList.findFileEl(filename); + var deleteAction = tr.children("td.date").children(".action.delete"); + deleteAction.removeClass('delete-icon').addClass('progress-icon'); disableActions(); - $.post(OC.filePath('files_trashbin','ajax','undelete.php'), - {files:JSON.stringify([files]), dirlisting:tr.attr('data-dirlisting') }, - function(result){ + $.post(OC.filePath('files_trashbin', 'ajax', 'undelete.php'), + {files: JSON.stringify([$('#dir').val() + '/' + filename]), dirlisting: tr.attr('data-dirlisting')}, + function(result) { + for (var i = 0; i < result.data.success.length; i++) { + var row = document.getElementById(result.data.success[i].filename); + row.parentNode.removeChild(row); + } + if (result.status !== 'success') { + OC.dialogs.alert(result.data.message, t('core', 'Error')); + } + enableActions(); + FileList.updateFileSummary(); + FileList.updateEmptyContent(); + } + ); + + }); + }; + + FileActions.register('all', 'Delete', OC.PERMISSION_READ, function() { + return OC.imagePath('core', 'actions/delete'); + }, function(filename) { + $('.tipsy').remove(); + var tr = FileList.findFileEl(filename); + var deleteAction = tr.children("td.date").children(".action.delete"); + deleteAction.removeClass('delete-icon').addClass('progress-icon'); + disableActions(); + $.post(OC.filePath('files_trashbin', 'ajax', 'delete.php'), + {files: JSON.stringify([$('#dir').val() + '/' +filename]), dirlisting: tr.attr('data-dirlisting')}, + function(result) { for (var i = 0; i < result.data.success.length; i++) { var row = document.getElementById(result.data.success[i].filename); row.parentNode.removeChild(row); @@ -21,26 +46,40 @@ $(document).ready(function() { } enableActions(); FileList.updateFileSummary(); - }); + FileList.updateEmptyContent(); + } + ); - }); - }; + }); + + // Sets the select_all checkbox behaviour : + $('#select_all').click(function() { + if ($(this).attr('checked')) { + // Check all + $('td.filename input:checkbox').attr('checked', true); + $('td.filename input:checkbox').parent().parent().addClass('selected'); + } else { + // Uncheck all + $('td.filename input:checkbox').attr('checked', false); + $('td.filename input:checkbox').parent().parent().removeClass('selected'); + } + procesSelection(); + }); - FileActions.register('all', 'Delete', OC.PERMISSION_READ, function () { - return OC.imagePath('core', 'actions/delete'); - }, function (filename) { - $('.tipsy').remove(); + $('.undelete').click('click', function(event) { + event.preventDefault(); + var files = getSelectedFiles('file'); + var fileslist = JSON.stringify(files); + var dirlisting = getSelectedFiles('dirlisting')[0]; + disableActions(); + for (var i = 0; i < files.length; i++) { + var deleteAction = FileList.findFileEl(files[i]).children("td.date").children(".action.delete"); + deleteAction.removeClass('delete-icon').addClass('progress-icon'); + } - var tr=$('tr').filterAttr('data-file', filename); - var deleteAction = $('tr').filterAttr('data-file',filename).children("td.date").children(".action.delete"); - var oldHTML = deleteAction[0].outerHTML; - var newHTML = '<img class="move2trash" data-action="Delete" title="'+t('files', 'delete file permanently')+'" src="'+ OC.imagePath('core', 'loading.gif') +'"></a>'; - var files = tr.attr('data-file'); - deleteAction[0].outerHTML = newHTML; - disableActions(); - $.post(OC.filePath('files_trashbin','ajax','delete.php'), - {files:JSON.stringify([files]), dirlisting:tr.attr('data-dirlisting') }, - function(result){ + $.post(OC.filePath('files_trashbin', 'ajax', 'undelete.php'), + {files: fileslist, dirlisting: dirlisting}, + function(result) { for (var i = 0; i < result.data.success.length; i++) { var row = document.getElementById(result.data.success[i].filename); row.parentNode.removeChild(row); @@ -50,106 +89,79 @@ $(document).ready(function() { } enableActions(); FileList.updateFileSummary(); - }); - - }); - - // Sets the select_all checkbox behaviour : - $('#select_all').click(function() { - if($(this).attr('checked')){ - // Check all - $('td.filename input:checkbox').attr('checked', true); - $('td.filename input:checkbox').parent().parent().addClass('selected'); - }else{ - // Uncheck all - $('td.filename input:checkbox').attr('checked', false); - $('td.filename input:checkbox').parent().parent().removeClass('selected'); - } - processSelection(); - }); - - $('td.filename input:checkbox').live('change',function(event) { - if (event.shiftKey) { - var last = $(lastChecked).parent().parent().prevAll().length; - var first = $(this).parent().parent().prevAll().length; - var start = Math.min(first, last); - var end = Math.max(first, last); - var rows = $(this).parent().parent().parent().children('tr'); - for (var i = start; i < end; i++) { - $(rows).each(function(index) { - if (index === i) { - var checkbox = $(this).children().children('input:checkbox'); - $(checkbox).attr('checked', 'checked'); - $(checkbox).parent().parent().addClass('selected'); - } - }); + FileList.updateEmptyContent(); } - } - var selectedCount=$('td.filename input:checkbox:checked').length; - $(this).parent().parent().toggleClass('selected'); - if(!$(this).attr('checked')){ - $('#select_all').attr('checked',false); - }else{ - if(selectedCount==$('td.filename input:checkbox').length){ - $('#select_all').attr('checked',true); - } - } - processSelection(); - }); + ); + }); - $('.undelete').click('click',function(event) { - event.preventDefault(); - var spinner = '<img class="move2trash" title="'+t('files_trashbin', 'perform restore operation')+'" src="'+ OC.imagePath('core', 'loading.gif') +'"></a>'; - var files=getSelectedFiles('file'); - var fileslist = JSON.stringify(files); - var dirlisting=getSelectedFiles('dirlisting')[0]; - disableActions(); - for (var i=0; i<files.length; i++) { - var undeleteAction = $('tr').filterAttr('data-file',files[i]).children("td.date"); - undeleteAction[0].innerHTML = undeleteAction[0].innerHTML+spinner; + $('.delete').click('click', function(event) { + event.preventDefault(); + var allFiles = $('#select_all').is(':checked'); + var files = []; + var params = {}; + if (allFiles) { + params = { + allfiles: true, + dir: $('#dir').val() + }; + } + else { + files = getSelectedFiles('file'); + params = { + files: JSON.stringify(files), + dirlisting: getSelectedFiles('dirlisting')[0] + }; + }; + + disableActions(); + if (allFiles) { + FileList.showMask(); + } + else { + for (var i = 0; i < files.length; i++) { + var deleteAction = FileList.findFileEl(files[i]).children("td.date").children(".action.delete"); + deleteAction.removeClass('delete-icon').addClass('progress-icon'); } + } - $.post(OC.filePath('files_trashbin','ajax','undelete.php'), - {files:fileslist, dirlisting:dirlisting}, - function(result){ + $.post(OC.filePath('files_trashbin', 'ajax', 'delete.php'), + params, + function(result) { + if (allFiles) { + FileList.hideMask(); + // simply remove all files + $('#fileList').empty(); + } + else { for (var i = 0; i < result.data.success.length; i++) { var row = document.getElementById(result.data.success[i].filename); row.parentNode.removeChild(row); } - if (result.status !== 'success') { - OC.dialogs.alert(result.data.message, t('core', 'Error')); - } - enableActions(); - }); - }); + } + if (result.status !== 'success') { + OC.dialogs.alert(result.data.message, t('core', 'Error')); + } + enableActions(); + FileList.updateFileSummary(); + FileList.updateEmptyContent(); + } + ); - $('.delete').click('click',function(event) { - event.preventDefault(); - console.log("delete selected"); - var spinner = '<img class="move2trash" title="'+t('files_trashbin', 'Delete permanently')+'" src="'+ OC.imagePath('core', 'loading.gif') +'"></a>'; - var files=getSelectedFiles('file'); - var fileslist = JSON.stringify(files); - var dirlisting=getSelectedFiles('dirlisting')[0]; + }); - disableActions(); - for (var i=0; i<files.length; i++) { - var deleteAction = $('tr').filterAttr('data-file',files[i]).children("td.date"); - deleteAction[0].innerHTML = deleteAction[0].innerHTML+spinner; + $('#fileList').on('click', 'td.filename input', function() { + var checkbox = $(this).parent().children('input:checkbox'); + $(checkbox).parent().parent().toggleClass('selected'); + if ($(checkbox).is(':checked')) { + var selectedCount = $('td.filename input:checkbox:checked').length; + if (selectedCount === $('td.filename input:checkbox').length) { + $('#select_all').prop('checked', true); } - - $.post(OC.filePath('files_trashbin','ajax','delete.php'), - {files:fileslist, dirlisting:dirlisting}, - function(result){ - for (var i = 0; i < result.data.success.length; i++) { - var row = document.getElementById(result.data.success[i].filename); - row.parentNode.removeChild(row); - } - if (result.status !== 'success') { - OC.dialogs.alert(result.data.message, t('core', 'Error')); - } - enableActions(); - }); - }); + } else { + $('#select_all').prop('checked',false); + } + procesSelection(); + }); $('#fileList').on('click', 'td.filename a', function(event) { var mime = $(this).parent().parent().data('mime'); @@ -157,7 +169,7 @@ $(document).ready(function() { event.preventDefault(); } var filename = $(this).parent().parent().attr('data-file'); - var tr = $('tr').filterAttr('data-file',filename); + var tr = FileList.findFileEl(filename); var renaming = tr.data('renaming'); if(!renaming && !FileList.isLoading(filename)){ if(mime.substr(0, 5) === 'text/'){ //no texteditor for now @@ -182,34 +194,6 @@ $(document).ready(function() { }; }); -function processSelection(){ - var selected=getSelectedFiles(); - var selectedFiles=selected.filter(function(el){return el.type === 'file'}); - var selectedFolders=selected.filter(function(el){return el.type === 'dir'}); - if(selectedFiles.length === 0 && selectedFolders.length === 0) { - $('#headerName>span.name').text(t('files','Name')); - $('#modified').text(t('files','Deleted')); - $('table').removeClass('multiselect'); - $('.selectedActions').hide(); - } - else { - $('.selectedActions').show(); - var selection=''; - if(selectedFolders.length>0){ - selection += n('files', '%n folder', '%n folders', selectedFolders.length); - if(selectedFiles.length>0){ - selection+=' & '; - } - } - if(selectedFiles.length>0){ - selection += n('files', '%n file', '%n files', selectedFiles.length); - } - $('#headerName>span.name').text(selection); - $('#modified').text(''); - $('table').addClass('multiselect'); - } -} - /** * @brief get a list of selected files * @param string property (option) the property of the file requested @@ -225,7 +209,7 @@ function getSelectedFiles(property){ elements.each(function(i,element){ var file={ name:$(element).attr('data-filename'), - file:$(element).attr('data-file'), + file:$('#dir').val() + "/" + $(element).attr('data-file'), timestamp:$(element).attr('data-timestamp'), type:$(element).attr('data-type'), dirlisting:$(element).attr('data-dirlisting') @@ -252,9 +236,4 @@ function disableActions() { $(".action").css("display", "none"); $(":input:checkbox").css("display", "none"); } -function onClickBreadcrumb(e){ - var $el = $(e.target).closest('.crumb'); - e.preventDefault(); - FileList.changeDirectory(decodeURIComponent($el.data('dir'))); -} diff --git a/apps/files_trashbin/l10n/ady.php b/apps/files_trashbin/l10n/ady.php new file mode 100644 index 00000000000..0acad00e8b5 --- /dev/null +++ b/apps/files_trashbin/l10n/ady.php @@ -0,0 +1,6 @@ +<?php +$TRANSLATIONS = array( +"_%n folder_::_%n folders_" => array("",""), +"_%n file_::_%n files_" => array("","") +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_trashbin/l10n/ar.php b/apps/files_trashbin/l10n/ar.php index 710a9d14196..9733e6b100e 100644 --- a/apps/files_trashbin/l10n/ar.php +++ b/apps/files_trashbin/l10n/ar.php @@ -2,16 +2,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "تعذّر حذف%s بشكل دائم", "Couldn't restore %s" => "تعذّر استرجاع %s ", -"perform restore operation" => "إبدء عملية الإستعادة", "Error" => "خطأ", -"delete file permanently" => "حذف بشكل دائم", -"Delete permanently" => "حذف بشكل دائم", -"Name" => "اسم", -"Deleted" => "تم الحذف", -"_%n folder_::_%n folders_" => array("","","","","",""), -"_%n file_::_%n files_" => array("","","","","",""), "Nothing in here. Your trash bin is empty!" => "لا يوجد شيء هنا. سلة المهملات خاليه.", +"Name" => "اسم", "Restore" => "استعيد", +"Deleted" => "تم الحذف", "Delete" => "إلغاء", "Deleted Files" => "الملفات المحذوفه" ); diff --git a/apps/files_trashbin/l10n/be.php b/apps/files_trashbin/l10n/be.php index 50df7ff5a97..6a34f1fe246 100644 --- a/apps/files_trashbin/l10n/be.php +++ b/apps/files_trashbin/l10n/be.php @@ -1,6 +1,5 @@ <?php $TRANSLATIONS = array( -"_%n folder_::_%n folders_" => array("","","",""), -"_%n file_::_%n files_" => array("","","","") +"Error" => "Памылка" ); $PLURAL_FORMS = "nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"; diff --git a/apps/files_trashbin/l10n/bg_BG.php b/apps/files_trashbin/l10n/bg_BG.php index 3c12e6906ed..2f1521feaa5 100644 --- a/apps/files_trashbin/l10n/bg_BG.php +++ b/apps/files_trashbin/l10n/bg_BG.php @@ -2,16 +2,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Невъзможно перманентното изтриване на %s", "Couldn't restore %s" => "Невъзможно възтановяване на %s", -"perform restore operation" => "извършване на действие по възстановяване", "Error" => "Грешка", -"delete file permanently" => "изтриване на файла завинаги", -"Delete permanently" => "Изтриване завинаги", -"Name" => "Име", -"Deleted" => "Изтрито", -"_%n folder_::_%n folders_" => array("",""), -"_%n file_::_%n files_" => array("",""), "Nothing in here. Your trash bin is empty!" => "Няма нищо. Кофата е празна!", +"Name" => "Име", "Restore" => "Възтановяване", +"Deleted" => "Изтрито", "Delete" => "Изтриване", "Deleted Files" => "Изтрити файлове" ); diff --git a/apps/files_trashbin/l10n/bn_BD.php b/apps/files_trashbin/l10n/bn_BD.php index c3741dbd1db..d3a9f23b377 100644 --- a/apps/files_trashbin/l10n/bn_BD.php +++ b/apps/files_trashbin/l10n/bn_BD.php @@ -2,8 +2,6 @@ $TRANSLATIONS = array( "Error" => "সমস্যা", "Name" => "রাম", -"_%n folder_::_%n folders_" => array("",""), -"_%n file_::_%n files_" => array("",""), "Delete" => "মুছে" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_trashbin/l10n/bs.php b/apps/files_trashbin/l10n/bs.php index af7033bd183..08ef9b4fdbb 100644 --- a/apps/files_trashbin/l10n/bs.php +++ b/apps/files_trashbin/l10n/bs.php @@ -1,7 +1,5 @@ <?php $TRANSLATIONS = array( -"Name" => "Ime", -"_%n folder_::_%n folders_" => array("","",""), -"_%n file_::_%n files_" => array("","","") +"Name" => "Ime" ); $PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"; diff --git a/apps/files_trashbin/l10n/ca.php b/apps/files_trashbin/l10n/ca.php index eb57aa16aa5..fa3f63ddb22 100644 --- a/apps/files_trashbin/l10n/ca.php +++ b/apps/files_trashbin/l10n/ca.php @@ -2,17 +2,12 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "No s'ha pogut esborrar permanentment %s", "Couldn't restore %s" => "No s'ha pogut restaurar %s", -"perform restore operation" => "executa l'operació de restauració", "Error" => "Error", -"delete file permanently" => "esborra el fitxer permanentment", -"Delete permanently" => "Esborra permanentment", -"Name" => "Nom", -"Deleted" => "Eliminat", -"_%n folder_::_%n folders_" => array("","%n carpetes"), -"_%n file_::_%n files_" => array("","%n fitxers"), "restored" => "restaurat", "Nothing in here. Your trash bin is empty!" => "La paperera està buida!", +"Name" => "Nom", "Restore" => "Recupera", +"Deleted" => "Eliminat", "Delete" => "Esborra", "Deleted Files" => "Fitxers eliminats" ); diff --git a/apps/files_trashbin/l10n/cs_CZ.php b/apps/files_trashbin/l10n/cs_CZ.php index f0bebee742f..ff0a69572f5 100644 --- a/apps/files_trashbin/l10n/cs_CZ.php +++ b/apps/files_trashbin/l10n/cs_CZ.php @@ -2,17 +2,12 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Nelze trvale odstranit %s", "Couldn't restore %s" => "Nelze obnovit %s", -"perform restore operation" => "provést obnovu", "Error" => "Chyba", -"delete file permanently" => "trvale odstranit soubor", -"Delete permanently" => "Trvale odstranit", -"Name" => "Název", -"Deleted" => "Smazáno", -"_%n folder_::_%n folders_" => array("%n adresář","%n adresáře","%n adresářů"), -"_%n file_::_%n files_" => array("%n soubor","%n soubory","%n souborů"), "restored" => "obnoveno", "Nothing in here. Your trash bin is empty!" => "Žádný obsah. Váš koš je prázdný.", +"Name" => "Název", "Restore" => "Obnovit", +"Deleted" => "Smazáno", "Delete" => "Smazat", "Deleted Files" => "Smazané soubory" ); diff --git a/apps/files_trashbin/l10n/cy_GB.php b/apps/files_trashbin/l10n/cy_GB.php index 123a445c2c1..f2eb81d67d2 100644 --- a/apps/files_trashbin/l10n/cy_GB.php +++ b/apps/files_trashbin/l10n/cy_GB.php @@ -2,16 +2,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Methwyd dileu %s yn barhaol", "Couldn't restore %s" => "Methwyd adfer %s", -"perform restore operation" => "gweithrediad adfer", "Error" => "Gwall", -"delete file permanently" => "dileu ffeil yn barhaol", -"Delete permanently" => "Dileu'n barhaol", -"Name" => "Enw", -"Deleted" => "Wedi dileu", -"_%n folder_::_%n folders_" => array("","","",""), -"_%n file_::_%n files_" => array("","","",""), "Nothing in here. Your trash bin is empty!" => "Does dim byd yma. Mae eich bin sbwriel yn wag!", +"Name" => "Enw", "Restore" => "Adfer", +"Deleted" => "Wedi dileu", "Delete" => "Dileu", "Deleted Files" => "Ffeiliau Ddilewyd" ); diff --git a/apps/files_trashbin/l10n/da.php b/apps/files_trashbin/l10n/da.php index 2fbc0893878..c396706d152 100644 --- a/apps/files_trashbin/l10n/da.php +++ b/apps/files_trashbin/l10n/da.php @@ -2,17 +2,12 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Kunne ikke slette %s permanent", "Couldn't restore %s" => "Kunne ikke gendanne %s", -"perform restore operation" => "udfør gendannelsesoperation", "Error" => "Fejl", -"delete file permanently" => "slet fil permanent", -"Delete permanently" => "Slet permanent", -"Name" => "Navn", -"Deleted" => "Slettet", -"_%n folder_::_%n folders_" => array("%n mappe","%n mapper"), -"_%n file_::_%n files_" => array("%n fil","%n filer"), "restored" => "Gendannet", "Nothing in here. Your trash bin is empty!" => "Intet at se her. Din papirkurv er tom!", +"Name" => "Navn", "Restore" => "Gendan", +"Deleted" => "Slettet", "Delete" => "Slet", "Deleted Files" => "Slettede filer" ); diff --git a/apps/files_trashbin/l10n/de.php b/apps/files_trashbin/l10n/de.php index ad6e0839bd6..2b6703dd058 100644 --- a/apps/files_trashbin/l10n/de.php +++ b/apps/files_trashbin/l10n/de.php @@ -2,17 +2,12 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Konnte %s nicht dauerhaft löschen", "Couldn't restore %s" => "Konnte %s nicht wiederherstellen", -"perform restore operation" => "Wiederherstellung ausführen", "Error" => "Fehler", -"delete file permanently" => "Datei dauerhaft löschen", -"Delete permanently" => "Endgültig löschen", -"Name" => "Name", -"Deleted" => "gelöscht", -"_%n folder_::_%n folders_" => array("","%n Ordner"), -"_%n file_::_%n files_" => array("","%n Dateien"), "restored" => "Wiederhergestellt", "Nothing in here. Your trash bin is empty!" => "Nichts zu löschen, der Papierkorb ist leer!", +"Name" => "Name", "Restore" => "Wiederherstellen", +"Deleted" => "gelöscht", "Delete" => "Löschen", "Deleted Files" => "Gelöschte Dateien" ); diff --git a/apps/files_trashbin/l10n/de_CH.php b/apps/files_trashbin/l10n/de_CH.php index 92290a0de50..ec9f0b5309d 100644 --- a/apps/files_trashbin/l10n/de_CH.php +++ b/apps/files_trashbin/l10n/de_CH.php @@ -2,17 +2,12 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Konnte %s nicht dauerhaft löschen", "Couldn't restore %s" => "Konnte %s nicht wiederherstellen", -"perform restore operation" => "Wiederherstellung ausführen", "Error" => "Fehler", -"delete file permanently" => "Datei dauerhaft löschen", -"Delete permanently" => "Endgültig löschen", -"Name" => "Name", -"Deleted" => "Gelöscht", -"_%n folder_::_%n folders_" => array("%n Ordner","%n Ordner"), -"_%n file_::_%n files_" => array("%n Datei","%n Dateien"), "restored" => "Wiederhergestellt", "Nothing in here. Your trash bin is empty!" => "Nichts zu löschen, Ihr Papierkorb ist leer!", +"Name" => "Name", "Restore" => "Wiederherstellen", +"Deleted" => "Gelöscht", "Delete" => "Löschen", "Deleted Files" => "Gelöschte Dateien" ); diff --git a/apps/files_trashbin/l10n/de_DE.php b/apps/files_trashbin/l10n/de_DE.php index 0df69412801..ec9f0b5309d 100644 --- a/apps/files_trashbin/l10n/de_DE.php +++ b/apps/files_trashbin/l10n/de_DE.php @@ -2,17 +2,12 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Konnte %s nicht dauerhaft löschen", "Couldn't restore %s" => "Konnte %s nicht wiederherstellen", -"perform restore operation" => "Wiederherstellung ausführen", "Error" => "Fehler", -"delete file permanently" => "Datei dauerhaft löschen", -"Delete permanently" => "Endgültig löschen", -"Name" => "Name", -"Deleted" => "Gelöscht", -"_%n folder_::_%n folders_" => array("%n Ordner","%n Ordner"), -"_%n file_::_%n files_" => array("%n Dateien","%n Dateien"), "restored" => "Wiederhergestellt", "Nothing in here. Your trash bin is empty!" => "Nichts zu löschen, Ihr Papierkorb ist leer!", +"Name" => "Name", "Restore" => "Wiederherstellen", +"Deleted" => "Gelöscht", "Delete" => "Löschen", "Deleted Files" => "Gelöschte Dateien" ); diff --git a/apps/files_trashbin/l10n/el.php b/apps/files_trashbin/l10n/el.php index 939c7fed614..b4ee30c578d 100644 --- a/apps/files_trashbin/l10n/el.php +++ b/apps/files_trashbin/l10n/el.php @@ -2,17 +2,12 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Αδύνατη η μόνιμη διαγραφή του %s", "Couldn't restore %s" => "Αδυναμία επαναφοράς %s", -"perform restore operation" => "εκτέλεση λειτουργία επαναφοράς", "Error" => "Σφάλμα", -"delete file permanently" => "μόνιμη διαγραφή αρχείου", -"Delete permanently" => "Μόνιμη διαγραφή", -"Name" => "Όνομα", -"Deleted" => "Διαγράφηκε", -"_%n folder_::_%n folders_" => array("","%n φάκελοι"), -"_%n file_::_%n files_" => array("","%n αρχεία"), -"restored" => "έγινε επαναφορά", +"restored" => "επαναφέρθηκαν", "Nothing in here. Your trash bin is empty!" => "Δεν υπάρχει τίποτα εδώ. Ο κάδος σας είναι άδειος!", +"Name" => "Όνομα", "Restore" => "Επαναφορά", +"Deleted" => "Διαγραμμένα", "Delete" => "Διαγραφή", "Deleted Files" => "Διαγραμμένα Αρχεία" ); diff --git a/apps/files_trashbin/l10n/en_GB.php b/apps/files_trashbin/l10n/en_GB.php index be9d8b9f520..6b179c86532 100644 --- a/apps/files_trashbin/l10n/en_GB.php +++ b/apps/files_trashbin/l10n/en_GB.php @@ -2,17 +2,12 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Couldn't delete %s permanently", "Couldn't restore %s" => "Couldn't restore %s", -"perform restore operation" => "perform restore operation", "Error" => "Error", -"delete file permanently" => "delete file permanently", -"Delete permanently" => "Delete permanently", -"Name" => "Name", -"Deleted" => "Deleted", -"_%n folder_::_%n folders_" => array("%n folder","%n folders"), -"_%n file_::_%n files_" => array("%n file","%n files"), "restored" => "restored", "Nothing in here. Your trash bin is empty!" => "Nothing in here. Your recycle bin is empty!", +"Name" => "Name", "Restore" => "Restore", +"Deleted" => "Deleted", "Delete" => "Delete", "Deleted Files" => "Deleted Files" ); diff --git a/apps/files_trashbin/l10n/eo.php b/apps/files_trashbin/l10n/eo.php index d1e30cba588..b8f999eaafa 100644 --- a/apps/files_trashbin/l10n/eo.php +++ b/apps/files_trashbin/l10n/eo.php @@ -1,11 +1,13 @@ <?php $TRANSLATIONS = array( +"Couldn't delete %s permanently" => "Ne povis foriĝi %s por ĉiam", +"Couldn't restore %s" => "Ne povis restaŭriĝi %s", "Error" => "Eraro", -"Delete permanently" => "Forigi por ĉiam", +"restored" => "restaŭrita", +"Nothing in here. Your trash bin is empty!" => "Nenio estas ĉi tie. Via rubujo malplenas!", "Name" => "Nomo", -"_%n folder_::_%n folders_" => array("",""), -"_%n file_::_%n files_" => array("",""), "Restore" => "Restaŭri", +"Deleted" => "Forigita", "Delete" => "Forigi", "Deleted Files" => "Forigitaj dosieroj" ); diff --git a/apps/files_trashbin/l10n/es.php b/apps/files_trashbin/l10n/es.php index a5639c2c714..db7a617729b 100644 --- a/apps/files_trashbin/l10n/es.php +++ b/apps/files_trashbin/l10n/es.php @@ -2,17 +2,12 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "No se puede eliminar %s permanentemente", "Couldn't restore %s" => "No se puede restaurar %s", -"perform restore operation" => "restaurar", "Error" => "Error", -"delete file permanently" => "eliminar archivo permanentemente", -"Delete permanently" => "Eliminar permanentemente", -"Name" => "Nombre", -"Deleted" => "Eliminado", -"_%n folder_::_%n folders_" => array("%n carpeta","%n carpetas"), -"_%n file_::_%n files_" => array("%n archivo","%n archivos"), "restored" => "recuperado", "Nothing in here. Your trash bin is empty!" => "No hay nada aquí. ¡Tu papelera esta vacía!", +"Name" => "Nombre", "Restore" => "Recuperar", +"Deleted" => "Eliminado", "Delete" => "Eliminar", "Deleted Files" => "Archivos Eliminados" ); diff --git a/apps/files_trashbin/l10n/es_AR.php b/apps/files_trashbin/l10n/es_AR.php index 0cb969a3483..842101d33be 100644 --- a/apps/files_trashbin/l10n/es_AR.php +++ b/apps/files_trashbin/l10n/es_AR.php @@ -2,17 +2,12 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "No fue posible borrar %s de manera permanente", "Couldn't restore %s" => "No se pudo restaurar %s", -"perform restore operation" => "Restaurar", "Error" => "Error", -"delete file permanently" => "Borrar archivo de manera permanente", -"Delete permanently" => "Borrar de manera permanente", -"Name" => "Nombre", -"Deleted" => "Borrado", -"_%n folder_::_%n folders_" => array("%n directorio","%n directorios"), -"_%n file_::_%n files_" => array("%n archivo","%n archivos"), "restored" => "recuperado", "Nothing in here. Your trash bin is empty!" => "No hay nada acá. ¡La papelera está vacía!", +"Name" => "Nombre", "Restore" => "Recuperar", +"Deleted" => "Borrado", "Delete" => "Borrar", "Deleted Files" => "Archivos eliminados" ); diff --git a/apps/files_trashbin/l10n/es_MX.php b/apps/files_trashbin/l10n/es_MX.php index 0acad00e8b5..db7a617729b 100644 --- a/apps/files_trashbin/l10n/es_MX.php +++ b/apps/files_trashbin/l10n/es_MX.php @@ -1,6 +1,14 @@ <?php $TRANSLATIONS = array( -"_%n folder_::_%n folders_" => array("",""), -"_%n file_::_%n files_" => array("","") +"Couldn't delete %s permanently" => "No se puede eliminar %s permanentemente", +"Couldn't restore %s" => "No se puede restaurar %s", +"Error" => "Error", +"restored" => "recuperado", +"Nothing in here. Your trash bin is empty!" => "No hay nada aquí. ¡Tu papelera esta vacía!", +"Name" => "Nombre", +"Restore" => "Recuperar", +"Deleted" => "Eliminado", +"Delete" => "Eliminar", +"Deleted Files" => "Archivos Eliminados" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_trashbin/l10n/et_EE.php b/apps/files_trashbin/l10n/et_EE.php index 43c182ea7b3..56eebc79f0b 100644 --- a/apps/files_trashbin/l10n/et_EE.php +++ b/apps/files_trashbin/l10n/et_EE.php @@ -2,17 +2,12 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "%s jäädavalt kustutamine ebaõnnestus", "Couldn't restore %s" => "%s ei saa taastada", -"perform restore operation" => "soorita taastamine", "Error" => "Viga", -"delete file permanently" => "kustuta fail jäädavalt", -"Delete permanently" => "Kustuta jäädavalt", -"Name" => "Nimi", -"Deleted" => "Kustutatud", -"_%n folder_::_%n folders_" => array("","%n kataloogi"), -"_%n file_::_%n files_" => array("%n fail","%n faili"), "restored" => "taastatud", "Nothing in here. Your trash bin is empty!" => "Siin pole midagi. Sinu prügikast on tühi!", +"Name" => "Nimi", "Restore" => "Taasta", +"Deleted" => "Kustutatud", "Delete" => "Kustuta", "Deleted Files" => "Kustutatud failid" ); diff --git a/apps/files_trashbin/l10n/eu.php b/apps/files_trashbin/l10n/eu.php index 240582a7ea6..04d92e01b36 100644 --- a/apps/files_trashbin/l10n/eu.php +++ b/apps/files_trashbin/l10n/eu.php @@ -2,17 +2,12 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Ezin izan da %s betirako ezabatu", "Couldn't restore %s" => "Ezin izan da %s berreskuratu", -"perform restore operation" => "berreskuratu", "Error" => "Errorea", -"delete file permanently" => "ezabatu fitxategia betirako", -"Delete permanently" => "Ezabatu betirako", -"Name" => "Izena", -"Deleted" => "Ezabatuta", -"_%n folder_::_%n folders_" => array("karpeta %n","%n karpeta"), -"_%n file_::_%n files_" => array("fitxategi %n","%n fitxategi"), "restored" => "Berrezarrita", "Nothing in here. Your trash bin is empty!" => "Ez dago ezer ez. Zure zakarrontzia hutsik dago!", +"Name" => "Izena", "Restore" => "Berrezarri", +"Deleted" => "Ezabatuta", "Delete" => "Ezabatu", "Deleted Files" => "Ezabatutako Fitxategiak" ); diff --git a/apps/files_trashbin/l10n/fa.php b/apps/files_trashbin/l10n/fa.php index 654f20a5f1c..8409987b897 100644 --- a/apps/files_trashbin/l10n/fa.php +++ b/apps/files_trashbin/l10n/fa.php @@ -2,16 +2,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "%s را نمی توان برای همیشه حذف کرد", "Couldn't restore %s" => "%s را نمی توان بازگرداند", -"perform restore operation" => "انجام عمل بازگرداندن", "Error" => "خطا", -"delete file permanently" => "حذف فایل برای همیشه", -"Delete permanently" => "حذف قطعی", -"Name" => "نام", -"Deleted" => "حذف شده", -"_%n folder_::_%n folders_" => array(""), -"_%n file_::_%n files_" => array(""), "Nothing in here. Your trash bin is empty!" => "هیچ چیزی اینجا نیست. سطل زباله ی شما خالی است.", +"Name" => "نام", "Restore" => "بازیابی", +"Deleted" => "حذف شده", "Delete" => "حذف", "Deleted Files" => "فایلهای حذف شده" ); diff --git a/apps/files_trashbin/l10n/fi_FI.php b/apps/files_trashbin/l10n/fi_FI.php index f03950981c0..b956c1c1e4c 100644 --- a/apps/files_trashbin/l10n/fi_FI.php +++ b/apps/files_trashbin/l10n/fi_FI.php @@ -2,17 +2,12 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Kohdetta %s ei voitu poistaa pysyvästi", "Couldn't restore %s" => "Kohteen %s palautus epäonnistui", -"perform restore operation" => "suorita palautustoiminto", "Error" => "Virhe", -"delete file permanently" => "poista tiedosto pysyvästi", -"Delete permanently" => "Poista pysyvästi", -"Name" => "Nimi", -"Deleted" => "Poistettu", -"_%n folder_::_%n folders_" => array("%n kansio","%n kansiota"), -"_%n file_::_%n files_" => array("%n tiedosto","%n tiedostoa"), "restored" => "palautettu", "Nothing in here. Your trash bin is empty!" => "Tyhjää täynnä! Roskakorissa ei ole mitään.", +"Name" => "Nimi", "Restore" => "Palauta", +"Deleted" => "Poistettu", "Delete" => "Poista", "Deleted Files" => "Poistetut tiedostot" ); diff --git a/apps/files_trashbin/l10n/fr.php b/apps/files_trashbin/l10n/fr.php index 45527805ce1..593310e2c32 100644 --- a/apps/files_trashbin/l10n/fr.php +++ b/apps/files_trashbin/l10n/fr.php @@ -2,17 +2,12 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Impossible d'effacer %s de façon permanente", "Couldn't restore %s" => "Impossible de restaurer %s", -"perform restore operation" => "effectuer l'opération de restauration", "Error" => "Erreur", -"delete file permanently" => "effacer définitivement le fichier", -"Delete permanently" => "Supprimer de façon définitive", -"Name" => "Nom", -"Deleted" => "Effacé", -"_%n folder_::_%n folders_" => array("","%n dossiers"), -"_%n file_::_%n files_" => array("","%n fichiers"), "restored" => "restauré", "Nothing in here. Your trash bin is empty!" => "Il n'y a rien ici. Votre corbeille est vide !", +"Name" => "Nom", "Restore" => "Restaurer", +"Deleted" => "Effacé", "Delete" => "Supprimer", "Deleted Files" => "Fichiers effacés" ); diff --git a/apps/files_trashbin/l10n/gl.php b/apps/files_trashbin/l10n/gl.php index 568c17607fe..ae7ef8b319b 100644 --- a/apps/files_trashbin/l10n/gl.php +++ b/apps/files_trashbin/l10n/gl.php @@ -2,17 +2,12 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Non foi posíbel eliminar %s permanente", "Couldn't restore %s" => "Non foi posíbel restaurar %s", -"perform restore operation" => "realizar a operación de restauración", "Error" => "Erro", -"delete file permanently" => "eliminar o ficheiro permanentemente", -"Delete permanently" => "Eliminar permanentemente", -"Name" => "Nome", -"Deleted" => "Eliminado", -"_%n folder_::_%n folders_" => array("%n cartafol","%n cartafoles"), -"_%n file_::_%n files_" => array("%n ficheiro","%n ficheiros"), "restored" => "restaurado", "Nothing in here. Your trash bin is empty!" => "Aquí non hai nada. O cesto do lixo está baleiro!", +"Name" => "Nome", "Restore" => "Restablecer", +"Deleted" => "Eliminado", "Delete" => "Eliminar", "Deleted Files" => "Ficheiros eliminados" ); diff --git a/apps/files_trashbin/l10n/he.php b/apps/files_trashbin/l10n/he.php index 6aa6264a315..d0bcb327d4a 100644 --- a/apps/files_trashbin/l10n/he.php +++ b/apps/files_trashbin/l10n/he.php @@ -2,16 +2,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "לא ניתן למחוק את %s לצמיתות", "Couldn't restore %s" => "לא ניתן לשחזר את %s", -"perform restore operation" => "ביצוע פעולת שחזור", "Error" => "שגיאה", -"delete file permanently" => "מחיקת קובץ לצמיתות", -"Delete permanently" => "מחיקה לצמיתות", -"Name" => "שם", -"Deleted" => "נמחק", -"_%n folder_::_%n folders_" => array("",""), -"_%n file_::_%n files_" => array("",""), "Nothing in here. Your trash bin is empty!" => "אין כאן שום דבר. סל המיחזור שלך ריק!", +"Name" => "שם", "Restore" => "שחזור", +"Deleted" => "נמחק", "Delete" => "מחיקה", "Deleted Files" => "קבצים שנמחקו" ); diff --git a/apps/files_trashbin/l10n/hi.php b/apps/files_trashbin/l10n/hi.php index 71711218b14..d4a26011b58 100644 --- a/apps/files_trashbin/l10n/hi.php +++ b/apps/files_trashbin/l10n/hi.php @@ -1,7 +1,5 @@ <?php $TRANSLATIONS = array( -"Error" => "त्रुटि", -"_%n folder_::_%n folders_" => array("",""), -"_%n file_::_%n files_" => array("","") +"Error" => "त्रुटि" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_trashbin/l10n/hr.php b/apps/files_trashbin/l10n/hr.php index d227b4979aa..8e8fd22f8ef 100644 --- a/apps/files_trashbin/l10n/hr.php +++ b/apps/files_trashbin/l10n/hr.php @@ -2,8 +2,6 @@ $TRANSLATIONS = array( "Error" => "Greška", "Name" => "Ime", -"_%n folder_::_%n folders_" => array("","",""), -"_%n file_::_%n files_" => array("","",""), "Delete" => "Obriši" ); $PLURAL_FORMS = "nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;"; diff --git a/apps/files_trashbin/l10n/hu_HU.php b/apps/files_trashbin/l10n/hu_HU.php index 766ddcbce4d..aa8b45a7d65 100644 --- a/apps/files_trashbin/l10n/hu_HU.php +++ b/apps/files_trashbin/l10n/hu_HU.php @@ -2,17 +2,12 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Nem sikerült %s végleges törlése", "Couldn't restore %s" => "Nem sikerült %s visszaállítása", -"perform restore operation" => "a visszaállítás végrehajtása", "Error" => "Hiba", -"delete file permanently" => "az állomány végleges törlése", -"Delete permanently" => "Végleges törlés", -"Name" => "Név", -"Deleted" => "Törölve", -"_%n folder_::_%n folders_" => array("","%n mappa"), -"_%n file_::_%n files_" => array("","%n állomány"), "restored" => "visszaállítva", "Nothing in here. Your trash bin is empty!" => "Itt nincs semmi. Az Ön szemetes mappája üres!", +"Name" => "Név", "Restore" => "Visszaállítás", +"Deleted" => "Törölve", "Delete" => "Törlés", "Deleted Files" => "Törölt fájlok" ); diff --git a/apps/files_trashbin/l10n/hy.php b/apps/files_trashbin/l10n/hy.php index 6ff58b56202..f933bec8feb 100644 --- a/apps/files_trashbin/l10n/hy.php +++ b/apps/files_trashbin/l10n/hy.php @@ -1,7 +1,5 @@ <?php $TRANSLATIONS = array( -"_%n folder_::_%n folders_" => array("",""), -"_%n file_::_%n files_" => array("",""), "Delete" => "Ջնջել" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_trashbin/l10n/ia.php b/apps/files_trashbin/l10n/ia.php index c583344a81e..7709ef030e3 100644 --- a/apps/files_trashbin/l10n/ia.php +++ b/apps/files_trashbin/l10n/ia.php @@ -2,8 +2,6 @@ $TRANSLATIONS = array( "Error" => "Error", "Name" => "Nomine", -"_%n folder_::_%n folders_" => array("",""), -"_%n file_::_%n files_" => array("",""), "Delete" => "Deler" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_trashbin/l10n/id.php b/apps/files_trashbin/l10n/id.php index 6aad1302f43..a55520fc117 100644 --- a/apps/files_trashbin/l10n/id.php +++ b/apps/files_trashbin/l10n/id.php @@ -2,16 +2,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Tidak dapat menghapus permanen %s", "Couldn't restore %s" => "Tidak dapat memulihkan %s", -"perform restore operation" => "jalankan operasi pemulihan", "Error" => "Galat", -"delete file permanently" => "hapus berkas secara permanen", -"Delete permanently" => "Hapus secara permanen", -"Name" => "Nama", -"Deleted" => "Dihapus", -"_%n folder_::_%n folders_" => array(""), -"_%n file_::_%n files_" => array(""), "Nothing in here. Your trash bin is empty!" => "Tempat sampah anda kosong!", +"Name" => "Nama", "Restore" => "Pulihkan", +"Deleted" => "Dihapus", "Delete" => "Hapus", "Deleted Files" => "Berkas yang Dihapus" ); diff --git a/apps/files_trashbin/l10n/is.php b/apps/files_trashbin/l10n/is.php index 55ae4336461..8ccf89739fc 100644 --- a/apps/files_trashbin/l10n/is.php +++ b/apps/files_trashbin/l10n/is.php @@ -2,8 +2,6 @@ $TRANSLATIONS = array( "Error" => "Villa", "Name" => "Nafn", -"_%n folder_::_%n folders_" => array("",""), -"_%n file_::_%n files_" => array("",""), "Delete" => "Eyða" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_trashbin/l10n/it.php b/apps/files_trashbin/l10n/it.php index e4b39c4a6d5..b631e0c9e4f 100644 --- a/apps/files_trashbin/l10n/it.php +++ b/apps/files_trashbin/l10n/it.php @@ -2,17 +2,12 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Impossibile eliminare %s definitivamente", "Couldn't restore %s" => "Impossibile ripristinare %s", -"perform restore operation" => "esegui operazione di ripristino", "Error" => "Errore", -"delete file permanently" => "elimina il file definitivamente", -"Delete permanently" => "Elimina definitivamente", -"Name" => "Nome", -"Deleted" => "Eliminati", -"_%n folder_::_%n folders_" => array("%n cartella","%n cartelle"), -"_%n file_::_%n files_" => array("%n file","%n file"), "restored" => "ripristinati", "Nothing in here. Your trash bin is empty!" => "Qui non c'è niente. Il tuo cestino è vuoto.", +"Name" => "Nome", "Restore" => "Ripristina", +"Deleted" => "Eliminati", "Delete" => "Elimina", "Deleted Files" => "File eliminati" ); diff --git a/apps/files_trashbin/l10n/ja_JP.php b/apps/files_trashbin/l10n/ja_JP.php index eb9748d57c0..8d896625b52 100644 --- a/apps/files_trashbin/l10n/ja_JP.php +++ b/apps/files_trashbin/l10n/ja_JP.php @@ -2,18 +2,13 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "%s を完全に削除出来ませんでした", "Couldn't restore %s" => "%s を復元出来ませんでした", -"perform restore operation" => "復元操作を実行する", "Error" => "エラー", -"delete file permanently" => "ファイルを完全に削除する", -"Delete permanently" => "完全に削除する", -"Name" => "名前", -"Deleted" => "削除済み", -"_%n folder_::_%n folders_" => array("%n個のフォルダ"), -"_%n file_::_%n files_" => array("%n個のファイル"), "restored" => "復元済", "Nothing in here. Your trash bin is empty!" => "ここには何もありません。ゴミ箱は空です!", +"Name" => "名前", "Restore" => "復元", +"Deleted" => "削除済み", "Delete" => "削除", -"Deleted Files" => "削除されたファイル" +"Deleted Files" => "ゴミ箱" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/files_trashbin/l10n/ka_GE.php b/apps/files_trashbin/l10n/ka_GE.php index 236d8951e9d..7440171deef 100644 --- a/apps/files_trashbin/l10n/ka_GE.php +++ b/apps/files_trashbin/l10n/ka_GE.php @@ -2,16 +2,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "ფაილი %s–ის სრულად წაშლა ვერ მოხერხდა", "Couldn't restore %s" => "%s–ის აღდგენა ვერ მოხერხდა", -"perform restore operation" => "მიმდინარეობს აღდგენის ოპერაცია", "Error" => "შეცდომა", -"delete file permanently" => "ფაილის სრულად წაშლა", -"Delete permanently" => "სრულად წაშლა", -"Name" => "სახელი", -"Deleted" => "წაშლილი", -"_%n folder_::_%n folders_" => array(""), -"_%n file_::_%n files_" => array(""), "Nothing in here. Your trash bin is empty!" => "აქ არაფერი არ არის. სანაგვე ყუთი ცარიელია!", +"Name" => "სახელი", "Restore" => "აღდგენა", +"Deleted" => "წაშლილი", "Delete" => "წაშლა", "Deleted Files" => "წაშლილი ფაილები" ); diff --git a/apps/files_trashbin/l10n/km.php b/apps/files_trashbin/l10n/km.php index 70f10d7c0bf..f7d9faa38c5 100644 --- a/apps/files_trashbin/l10n/km.php +++ b/apps/files_trashbin/l10n/km.php @@ -1,6 +1,5 @@ <?php $TRANSLATIONS = array( -"_%n folder_::_%n folders_" => array(""), -"_%n file_::_%n files_" => array("") +"Delete" => "លុប" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/files_trashbin/l10n/ko.php b/apps/files_trashbin/l10n/ko.php index 9ac5f9802c6..9c3cd2de15f 100644 --- a/apps/files_trashbin/l10n/ko.php +++ b/apps/files_trashbin/l10n/ko.php @@ -1,19 +1,14 @@ <?php $TRANSLATIONS = array( -"Couldn't delete %s permanently" => "%s를 영구적으로 삭제할수 없습니다", -"Couldn't restore %s" => "%s를 복원할수 없습니다", -"perform restore operation" => "복원 작업중", +"Couldn't delete %s permanently" => "%s을(를_ 영구적으로 삭제할 수 없습니다", +"Couldn't restore %s" => "%s을(를) 복원할 수 없습니다", "Error" => "오류", -"delete file permanently" => "영구적으로 파일 삭제하기", -"Delete permanently" => "영원히 삭제", -"Name" => "이름", -"Deleted" => "삭제됨", -"_%n folder_::_%n folders_" => array("폴더 %n개"), -"_%n file_::_%n files_" => array("파일 %n개 "), "restored" => "복원됨", -"Nothing in here. Your trash bin is empty!" => "현재 휴지통은 비어있습니다!", +"Nothing in here. Your trash bin is empty!" => "휴지통이 비어 있습니다!", +"Name" => "이름", "Restore" => "복원", +"Deleted" => "삭제됨", "Delete" => "삭제", -"Deleted Files" => "삭제된 파일들" +"Deleted Files" => "삭제된 파일" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/files_trashbin/l10n/ku_IQ.php b/apps/files_trashbin/l10n/ku_IQ.php index 3f110f06002..c1962a4075d 100644 --- a/apps/files_trashbin/l10n/ku_IQ.php +++ b/apps/files_trashbin/l10n/ku_IQ.php @@ -1,8 +1,6 @@ <?php $TRANSLATIONS = array( "Error" => "ههڵه", -"Name" => "ناو", -"_%n folder_::_%n folders_" => array("",""), -"_%n file_::_%n files_" => array("","") +"Name" => "ناو" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_trashbin/l10n/lb.php b/apps/files_trashbin/l10n/lb.php index cbfd515a8b3..b434ae72176 100644 --- a/apps/files_trashbin/l10n/lb.php +++ b/apps/files_trashbin/l10n/lb.php @@ -2,8 +2,6 @@ $TRANSLATIONS = array( "Error" => "Fehler", "Name" => "Numm", -"_%n folder_::_%n folders_" => array("",""), -"_%n file_::_%n files_" => array("",""), "Delete" => "Läschen" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_trashbin/l10n/lt_LT.php b/apps/files_trashbin/l10n/lt_LT.php index 0a51290f4d9..c4a8463fd0e 100644 --- a/apps/files_trashbin/l10n/lt_LT.php +++ b/apps/files_trashbin/l10n/lt_LT.php @@ -2,17 +2,12 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Nepavyko negrįžtamai ištrinti %s", "Couldn't restore %s" => "Nepavyko atkurti %s", -"perform restore operation" => "atkurti", "Error" => "Klaida", -"delete file permanently" => "failą ištrinti negrįžtamai", -"Delete permanently" => "Ištrinti negrįžtamai", -"Name" => "Pavadinimas", -"Deleted" => "Ištrinti", -"_%n folder_::_%n folders_" => array("","","%n aplankų"), -"_%n file_::_%n files_" => array("","","%n failų"), "restored" => "atstatyta", "Nothing in here. Your trash bin is empty!" => "Nieko nėra. Jūsų šiukšliadėžė tuščia!", +"Name" => "Pavadinimas", "Restore" => "Atstatyti", +"Deleted" => "Ištrinti", "Delete" => "Ištrinti", "Deleted Files" => "Ištrinti failai" ); diff --git a/apps/files_trashbin/l10n/lv.php b/apps/files_trashbin/l10n/lv.php index ca833b24208..5c04a0c97d1 100644 --- a/apps/files_trashbin/l10n/lv.php +++ b/apps/files_trashbin/l10n/lv.php @@ -2,17 +2,12 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Nevarēja pilnībā izdzēst %s", "Couldn't restore %s" => "Nevarēja atjaunot %s", -"perform restore operation" => "veikt atjaunošanu", "Error" => "Kļūda", -"delete file permanently" => "dzēst datni pavisam", -"Delete permanently" => "Dzēst pavisam", -"Name" => "Nosaukums", -"Deleted" => "Dzēsts", -"_%n folder_::_%n folders_" => array("Nekas, %n mapes","%n mape","%n mapes"), -"_%n file_::_%n files_" => array("Neviens! %n faaili","%n fails","%n faili"), "restored" => "atjaunots", "Nothing in here. Your trash bin is empty!" => "Šeit nekā nav. Jūsu miskaste ir tukša!", +"Name" => "Nosaukums", "Restore" => "Atjaunot", +"Deleted" => "Dzēsts", "Delete" => "Dzēst", "Deleted Files" => "Dzēstās datnes" ); diff --git a/apps/files_trashbin/l10n/mk.php b/apps/files_trashbin/l10n/mk.php index 965518dbc86..06a9dcfb241 100644 --- a/apps/files_trashbin/l10n/mk.php +++ b/apps/files_trashbin/l10n/mk.php @@ -1,9 +1,14 @@ <?php $TRANSLATIONS = array( +"Couldn't delete %s permanently" => "Не можеше трајно да се избрише %s", +"Couldn't restore %s" => "Не можеше да се поврати %s", "Error" => "Грешка", +"restored" => "повратени", +"Nothing in here. Your trash bin is empty!" => "Тука нема ништо. Вашата корпа за отпадоци е празна!", "Name" => "Име", -"_%n folder_::_%n folders_" => array("",""), -"_%n file_::_%n files_" => array("",""), -"Delete" => "Избриши" +"Restore" => "Поврати", +"Deleted" => "Избришан", +"Delete" => "Избриши", +"Deleted Files" => "Избришани датотеки" ); $PLURAL_FORMS = "nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;"; diff --git a/apps/files_trashbin/l10n/ms_MY.php b/apps/files_trashbin/l10n/ms_MY.php index 1b5ca07c70c..e7721313918 100644 --- a/apps/files_trashbin/l10n/ms_MY.php +++ b/apps/files_trashbin/l10n/ms_MY.php @@ -1,9 +1,14 @@ <?php $TRANSLATIONS = array( +"Couldn't delete %s permanently" => "Tidak dapat menghapuskan %s secara kekal", +"Couldn't restore %s" => "Tidak dapat memulihkan %s", "Error" => "Ralat", +"restored" => "dipulihkan", +"Nothing in here. Your trash bin is empty!" => "Tiada apa disini. Tong sampah anda kosong!", "Name" => "Nama", -"_%n folder_::_%n folders_" => array(""), -"_%n file_::_%n files_" => array(""), -"Delete" => "Padam" +"Restore" => "Pulihkan", +"Deleted" => "Dihapuskan", +"Delete" => "Padam", +"Deleted Files" => "Fail Dihapus" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/files_trashbin/l10n/nb_NO.php b/apps/files_trashbin/l10n/nb_NO.php index 8eb3bc1846f..eb917e3dde6 100644 --- a/apps/files_trashbin/l10n/nb_NO.php +++ b/apps/files_trashbin/l10n/nb_NO.php @@ -2,16 +2,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Kunne ikke slette %s fullstendig", "Couldn't restore %s" => "Kunne ikke gjenopprette %s", -"perform restore operation" => "utfør gjenopprettings operasjon", "Error" => "Feil", -"delete file permanently" => "slett filer permanent", -"Delete permanently" => "Slett permanent", -"Name" => "Navn", -"Deleted" => "Slettet", -"_%n folder_::_%n folders_" => array("","%n mapper"), -"_%n file_::_%n files_" => array("","%n filer"), "Nothing in here. Your trash bin is empty!" => "Ingenting her. Søppelkassen din er tom!", +"Name" => "Navn", "Restore" => "Gjenopprett", +"Deleted" => "Slettet", "Delete" => "Slett", "Deleted Files" => "Slettet filer" ); diff --git a/apps/files_trashbin/l10n/nl.php b/apps/files_trashbin/l10n/nl.php index b3ae57da563..37a8ca65409 100644 --- a/apps/files_trashbin/l10n/nl.php +++ b/apps/files_trashbin/l10n/nl.php @@ -2,17 +2,12 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Kon %s niet permanent verwijderen", "Couldn't restore %s" => "Kon %s niet herstellen", -"perform restore operation" => "uitvoeren restore operatie", "Error" => "Fout", -"delete file permanently" => "verwijder bestanden definitief", -"Delete permanently" => "Verwijder definitief", -"Name" => "Naam", -"Deleted" => "Verwijderd", -"_%n folder_::_%n folders_" => array("%n map","%n mappen"), -"_%n file_::_%n files_" => array("%n bestand","%n bestanden"), "restored" => "hersteld", "Nothing in here. Your trash bin is empty!" => "Niets te vinden. Uw prullenbak is leeg!", +"Name" => "Naam", "Restore" => "Herstellen", +"Deleted" => "Verwijderd", "Delete" => "Verwijder", "Deleted Files" => "Verwijderde bestanden" ); diff --git a/apps/files_trashbin/l10n/nn_NO.php b/apps/files_trashbin/l10n/nn_NO.php index 73fe48211c2..39e2d5cda91 100644 --- a/apps/files_trashbin/l10n/nn_NO.php +++ b/apps/files_trashbin/l10n/nn_NO.php @@ -2,17 +2,12 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Klarte ikkje sletta %s for godt", "Couldn't restore %s" => "Klarte ikkje gjenoppretta %s", -"perform restore operation" => "utfør gjenoppretting", "Error" => "Feil", -"delete file permanently" => "slett fila for godt", -"Delete permanently" => "Slett for godt", -"Name" => "Namn", -"Deleted" => "Sletta", -"_%n folder_::_%n folders_" => array("%n mappe","%n mapper"), -"_%n file_::_%n files_" => array("%n fil","%n filer"), "restored" => "gjenoppretta", "Nothing in here. Your trash bin is empty!" => "Ingenting her. Papirkorga di er tom!", +"Name" => "Namn", "Restore" => "Gjenopprett", +"Deleted" => "Sletta", "Delete" => "Slett", "Deleted Files" => "Sletta filer" ); diff --git a/apps/files_trashbin/l10n/oc.php b/apps/files_trashbin/l10n/oc.php index a62902c3b7e..b472683f08d 100644 --- a/apps/files_trashbin/l10n/oc.php +++ b/apps/files_trashbin/l10n/oc.php @@ -2,8 +2,6 @@ $TRANSLATIONS = array( "Error" => "Error", "Name" => "Nom", -"_%n folder_::_%n folders_" => array("",""), -"_%n file_::_%n files_" => array("",""), "Delete" => "Escafa" ); $PLURAL_FORMS = "nplurals=2; plural=(n > 1);"; diff --git a/apps/files_trashbin/l10n/pa.php b/apps/files_trashbin/l10n/pa.php index e53707fd707..825a49aaea4 100644 --- a/apps/files_trashbin/l10n/pa.php +++ b/apps/files_trashbin/l10n/pa.php @@ -1,8 +1,6 @@ <?php $TRANSLATIONS = array( "Error" => "ਗਲਤੀ", -"_%n folder_::_%n folders_" => array("",""), -"_%n file_::_%n files_" => array("",""), "Delete" => "ਹਟਾਓ" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_trashbin/l10n/pl.php b/apps/files_trashbin/l10n/pl.php index c838a6b956c..961b7727824 100644 --- a/apps/files_trashbin/l10n/pl.php +++ b/apps/files_trashbin/l10n/pl.php @@ -2,17 +2,12 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Nie można trwale usunąć %s", "Couldn't restore %s" => "Nie można przywrócić %s", -"perform restore operation" => "wykonywanie operacji przywracania", "Error" => "Błąd", -"delete file permanently" => "trwale usuń plik", -"Delete permanently" => "Trwale usuń", -"Name" => "Nazwa", -"Deleted" => "Usunięte", -"_%n folder_::_%n folders_" => array("","","%n katalogów"), -"_%n file_::_%n files_" => array("","","%n plików"), "restored" => "przywrócony", "Nothing in here. Your trash bin is empty!" => "Nic tu nie ma. Twój kosz jest pusty!", +"Name" => "Nazwa", "Restore" => "Przywróć", +"Deleted" => "Usunięte", "Delete" => "Usuń", "Deleted Files" => "Usunięte pliki" ); diff --git a/apps/files_trashbin/l10n/pt_BR.php b/apps/files_trashbin/l10n/pt_BR.php index e0e8c8faec6..c2100efe96e 100644 --- a/apps/files_trashbin/l10n/pt_BR.php +++ b/apps/files_trashbin/l10n/pt_BR.php @@ -2,17 +2,12 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Não foi possível excluir %s permanentemente", "Couldn't restore %s" => "Não foi possível restaurar %s", -"perform restore operation" => "realizar operação de restauração", "Error" => "Erro", -"delete file permanently" => "excluir arquivo permanentemente", -"Delete permanently" => "Excluir permanentemente", -"Name" => "Nome", -"Deleted" => "Excluído", -"_%n folder_::_%n folders_" => array("","%n pastas"), -"_%n file_::_%n files_" => array("%n arquivo","%n arquivos"), "restored" => "restaurado", "Nothing in here. Your trash bin is empty!" => "Nada aqui. Sua lixeira está vazia!", +"Name" => "Nome", "Restore" => "Restaurar", +"Deleted" => "Excluído", "Delete" => "Excluir", "Deleted Files" => "Arquivos Apagados" ); diff --git a/apps/files_trashbin/l10n/pt_PT.php b/apps/files_trashbin/l10n/pt_PT.php index 9dccc773cb1..89e84a84d28 100644 --- a/apps/files_trashbin/l10n/pt_PT.php +++ b/apps/files_trashbin/l10n/pt_PT.php @@ -2,17 +2,12 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Não foi possível eliminar %s de forma permanente", "Couldn't restore %s" => "Não foi possível restaurar %s", -"perform restore operation" => "executar a operação de restauro", "Error" => "Erro", -"delete file permanently" => "Eliminar permanentemente o(s) ficheiro(s)", -"Delete permanently" => "Eliminar permanentemente", -"Name" => "Nome", -"Deleted" => "Apagado", -"_%n folder_::_%n folders_" => array("%n pasta","%n pastas"), -"_%n file_::_%n files_" => array("%n ficheiro","%n ficheiros"), "restored" => "Restaurado", "Nothing in here. Your trash bin is empty!" => "Não hà ficheiros. O lixo está vazio!", +"Name" => "Nome", "Restore" => "Restaurar", +"Deleted" => "Apagado", "Delete" => "Eliminar", "Deleted Files" => "Ficheiros Apagados" ); diff --git a/apps/files_trashbin/l10n/ro.php b/apps/files_trashbin/l10n/ro.php index 12377bb0652..f285dcc164e 100644 --- a/apps/files_trashbin/l10n/ro.php +++ b/apps/files_trashbin/l10n/ro.php @@ -1,10 +1,7 @@ <?php $TRANSLATIONS = array( "Error" => "Eroare", -"Delete permanently" => "Stergere permanenta", "Name" => "Nume", -"_%n folder_::_%n folders_" => array("","","%n directoare"), -"_%n file_::_%n files_" => array("","","%n fișiere"), "Delete" => "Șterge" ); $PLURAL_FORMS = "nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));"; diff --git a/apps/files_trashbin/l10n/ru.php b/apps/files_trashbin/l10n/ru.php index 5f52263a118..06a4f864c67 100644 --- a/apps/files_trashbin/l10n/ru.php +++ b/apps/files_trashbin/l10n/ru.php @@ -2,17 +2,12 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "%s не может быть удалён навсегда", "Couldn't restore %s" => "%s не может быть восстановлен", -"perform restore operation" => "выполнить операцию восстановления", "Error" => "Ошибка", -"delete file permanently" => "удалить файл навсегда", -"Delete permanently" => "Удалено навсегда", -"Name" => "Имя", -"Deleted" => "Удалён", -"_%n folder_::_%n folders_" => array("","","%n папок"), -"_%n file_::_%n files_" => array("","","%n файлов"), "restored" => "восстановлен", "Nothing in here. Your trash bin is empty!" => "Здесь ничего нет. Ваша корзина пуста!", +"Name" => "Имя", "Restore" => "Восстановить", +"Deleted" => "Удалён", "Delete" => "Удалить", "Deleted Files" => "Удаленные файлы" ); diff --git a/apps/files_trashbin/l10n/si_LK.php b/apps/files_trashbin/l10n/si_LK.php index 6dad84437cf..87e928989e4 100644 --- a/apps/files_trashbin/l10n/si_LK.php +++ b/apps/files_trashbin/l10n/si_LK.php @@ -2,8 +2,6 @@ $TRANSLATIONS = array( "Error" => "දෝෂයක්", "Name" => "නම", -"_%n folder_::_%n folders_" => array("",""), -"_%n file_::_%n files_" => array("",""), "Delete" => "මකා දමන්න" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_trashbin/l10n/sk.php b/apps/files_trashbin/l10n/sk.php index 94aaf9b3a94..3129cf5c411 100644 --- a/apps/files_trashbin/l10n/sk.php +++ b/apps/files_trashbin/l10n/sk.php @@ -1,6 +1,5 @@ <?php $TRANSLATIONS = array( -"_%n folder_::_%n folders_" => array("","",""), -"_%n file_::_%n files_" => array("","","") +"Delete" => "Odstrániť" ); $PLURAL_FORMS = "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"; diff --git a/apps/files_trashbin/l10n/sk_SK.php b/apps/files_trashbin/l10n/sk_SK.php index 50fb58a44e2..b23383c1214 100644 --- a/apps/files_trashbin/l10n/sk_SK.php +++ b/apps/files_trashbin/l10n/sk_SK.php @@ -2,17 +2,12 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Nemožno zmazať %s navždy", "Couldn't restore %s" => "Nemožno obnoviť %s", -"perform restore operation" => "vykonať obnovu", "Error" => "Chyba", -"delete file permanently" => "trvalo zmazať súbor", -"Delete permanently" => "Zmazať trvalo", -"Name" => "Názov", -"Deleted" => "Zmazané", -"_%n folder_::_%n folders_" => array("%n priečinok","%n priečinky","%n priečinkov"), -"_%n file_::_%n files_" => array("%n súbor","%n súbory","%n súborov"), "restored" => "obnovené", "Nothing in here. Your trash bin is empty!" => "Žiadny obsah. Kôš je prázdny!", +"Name" => "Názov", "Restore" => "Obnoviť", +"Deleted" => "Zmazané", "Delete" => "Zmazať", "Deleted Files" => "Zmazané súbory" ); diff --git a/apps/files_trashbin/l10n/sl.php b/apps/files_trashbin/l10n/sl.php index eb2d42a18ff..9f164ae709c 100644 --- a/apps/files_trashbin/l10n/sl.php +++ b/apps/files_trashbin/l10n/sl.php @@ -1,17 +1,13 @@ <?php $TRANSLATIONS = array( -"Couldn't delete %s permanently" => "Datoteke %s ni mogoče dokončno izbrisati.", +"Couldn't delete %s permanently" => "Datoteke %s ni mogoče trajno izbrisati.", "Couldn't restore %s" => "Ni mogoče obnoviti %s", -"perform restore operation" => "izvedi opravilo obnavljanja", "Error" => "Napaka", -"delete file permanently" => "dokončno izbriši datoteko", -"Delete permanently" => "Izbriši dokončno", -"Name" => "Ime", -"Deleted" => "Izbrisano", -"_%n folder_::_%n folders_" => array("","","",""), -"_%n file_::_%n files_" => array("","","",""), +"restored" => "obnovljeno", "Nothing in here. Your trash bin is empty!" => "Mapa smeti je prazna.", +"Name" => "Ime", "Restore" => "Obnovi", +"Deleted" => "Izbrisano", "Delete" => "Izbriši", "Deleted Files" => "Izbrisane datoteke" ); diff --git a/apps/files_trashbin/l10n/sq.php b/apps/files_trashbin/l10n/sq.php index 50ca7d901b5..63957080f37 100644 --- a/apps/files_trashbin/l10n/sq.php +++ b/apps/files_trashbin/l10n/sq.php @@ -2,17 +2,12 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Nuk munda ta eliminoj përfundimisht %s", "Couldn't restore %s" => "Nuk munda ta rivendos %s", -"perform restore operation" => "ekzekuto operacionin e rivendosjes", "Error" => "Veprim i gabuar", -"delete file permanently" => "eliminoje përfundimisht skedarin", -"Delete permanently" => "Elimino përfundimisht", -"Name" => "Emri", -"Deleted" => "Eliminuar", -"_%n folder_::_%n folders_" => array("%n dosje","%n dosje"), -"_%n file_::_%n files_" => array("%n skedar","%n skedarë"), "restored" => "rivendosur", "Nothing in here. Your trash bin is empty!" => "Këtu nuk ka asgjë. Koshi juaj është bosh!", +"Name" => "Emri", "Restore" => "Rivendos", +"Deleted" => "Eliminuar", "Delete" => "Elimino", "Deleted Files" => "Skedarë të eliminuar" ); diff --git a/apps/files_trashbin/l10n/sr.php b/apps/files_trashbin/l10n/sr.php index 7311e759f98..c893dba118b 100644 --- a/apps/files_trashbin/l10n/sr.php +++ b/apps/files_trashbin/l10n/sr.php @@ -1,14 +1,10 @@ <?php $TRANSLATIONS = array( -"perform restore operation" => "врати у претходно стање", "Error" => "Грешка", -"Delete permanently" => "Обриши за стално", -"Name" => "Име", -"Deleted" => "Обрисано", -"_%n folder_::_%n folders_" => array("","",""), -"_%n file_::_%n files_" => array("","",""), "Nothing in here. Your trash bin is empty!" => "Овде нема ништа. Корпа за отпатке је празна.", +"Name" => "Име", "Restore" => "Врати", +"Deleted" => "Обрисано", "Delete" => "Обриши" ); $PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"; diff --git a/apps/files_trashbin/l10n/sr@latin.php b/apps/files_trashbin/l10n/sr@latin.php index fa30afcf4bf..9f18ac8be7d 100644 --- a/apps/files_trashbin/l10n/sr@latin.php +++ b/apps/files_trashbin/l10n/sr@latin.php @@ -2,8 +2,6 @@ $TRANSLATIONS = array( "Error" => "Greška", "Name" => "Ime", -"_%n folder_::_%n folders_" => array("","",""), -"_%n file_::_%n files_" => array("","",""), "Delete" => "Obriši" ); $PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"; diff --git a/apps/files_trashbin/l10n/sv.php b/apps/files_trashbin/l10n/sv.php index 47a52f25736..21d4d15e9cc 100644 --- a/apps/files_trashbin/l10n/sv.php +++ b/apps/files_trashbin/l10n/sv.php @@ -2,17 +2,12 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Kunde inte radera %s permanent", "Couldn't restore %s" => "Kunde inte återställa %s", -"perform restore operation" => "utför återställning", "Error" => "Fel", -"delete file permanently" => "radera filen permanent", -"Delete permanently" => "Radera permanent", -"Name" => "Namn", -"Deleted" => "Raderad", -"_%n folder_::_%n folders_" => array("%n mapp","%n mappar"), -"_%n file_::_%n files_" => array("%n fil","%n filer"), "restored" => "återställd", "Nothing in here. Your trash bin is empty!" => "Ingenting här. Din papperskorg är tom!", +"Name" => "Namn", "Restore" => "Återskapa", +"Deleted" => "Raderad", "Delete" => "Radera", "Deleted Files" => "Raderade filer" ); diff --git a/apps/files_trashbin/l10n/ta_LK.php b/apps/files_trashbin/l10n/ta_LK.php index ed93b459c7d..79349919b52 100644 --- a/apps/files_trashbin/l10n/ta_LK.php +++ b/apps/files_trashbin/l10n/ta_LK.php @@ -2,8 +2,6 @@ $TRANSLATIONS = array( "Error" => "வழு", "Name" => "பெயர்", -"_%n folder_::_%n folders_" => array("",""), -"_%n file_::_%n files_" => array("",""), "Delete" => "நீக்குக" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_trashbin/l10n/te.php b/apps/files_trashbin/l10n/te.php index 0d803a8e648..01262b78232 100644 --- a/apps/files_trashbin/l10n/te.php +++ b/apps/files_trashbin/l10n/te.php @@ -1,10 +1,7 @@ <?php $TRANSLATIONS = array( "Error" => "పొరపాటు", -"Delete permanently" => "శాశ్వతంగా తొలగించు", "Name" => "పేరు", -"_%n folder_::_%n folders_" => array("",""), -"_%n file_::_%n files_" => array("",""), "Delete" => "తొలగించు" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_trashbin/l10n/th_TH.php b/apps/files_trashbin/l10n/th_TH.php index 31caa11aac3..65fd081a952 100644 --- a/apps/files_trashbin/l10n/th_TH.php +++ b/apps/files_trashbin/l10n/th_TH.php @@ -1,13 +1,10 @@ <?php $TRANSLATIONS = array( -"perform restore operation" => "ดำเนินการคืนค่า", "Error" => "ข้อผิดพลาด", -"Name" => "ชื่อ", -"Deleted" => "ลบแล้ว", -"_%n folder_::_%n folders_" => array(""), -"_%n file_::_%n files_" => array(""), "Nothing in here. Your trash bin is empty!" => "ไม่มีอะไรอยู่ในนี้ ถังขยะของคุณยังว่างอยู่", +"Name" => "ชื่อ", "Restore" => "คืนค่า", +"Deleted" => "ลบแล้ว", "Delete" => "ลบ", "Deleted Files" => "ไฟล์ที่ลบทิ้ง" ); diff --git a/apps/files_trashbin/l10n/tr.php b/apps/files_trashbin/l10n/tr.php index f25b179bc1e..00a3b4d32a5 100644 --- a/apps/files_trashbin/l10n/tr.php +++ b/apps/files_trashbin/l10n/tr.php @@ -1,18 +1,13 @@ <?php $TRANSLATIONS = array( -"Couldn't delete %s permanently" => "%s Kalıcı olarak silinemedi", -"Couldn't restore %s" => "%s Geri yüklenemedi", -"perform restore operation" => "Geri yükleme işlemini gerçekleştir", +"Couldn't delete %s permanently" => "%s alıcı olarak silinemedi", +"Couldn't restore %s" => "%s eri yüklenemedi", "Error" => "Hata", -"delete file permanently" => "Dosyayı kalıcı olarak sil", -"Delete permanently" => "Kalıcı olarak sil", -"Name" => "İsim", -"Deleted" => "Silindi", -"_%n folder_::_%n folders_" => array("","%n dizin"), -"_%n file_::_%n files_" => array("","%n dosya"), "restored" => "geri yüklendi", -"Nothing in here. Your trash bin is empty!" => "Burası boş. Çöp kutun tamamen boş.", +"Nothing in here. Your trash bin is empty!" => "Burada hiçbir şey yok. Çöp kutunuz tamamen boş!", +"Name" => "İsim", "Restore" => "Geri yükle", +"Deleted" => "Silindi", "Delete" => "Sil", "Deleted Files" => "Silinen Dosyalar" ); diff --git a/apps/files_trashbin/l10n/ug.php b/apps/files_trashbin/l10n/ug.php index ad983aee18b..54c040c88a7 100644 --- a/apps/files_trashbin/l10n/ug.php +++ b/apps/files_trashbin/l10n/ug.php @@ -1,12 +1,9 @@ <?php $TRANSLATIONS = array( "Error" => "خاتالىق", -"Delete permanently" => "مەڭگۈلۈك ئۆچۈر", +"Nothing in here. Your trash bin is empty!" => "بۇ جايدا ھېچنېمە يوق. Your trash bin is empty!", "Name" => "ئاتى", "Deleted" => "ئۆچۈرۈلدى", -"_%n folder_::_%n folders_" => array(""), -"_%n file_::_%n files_" => array(""), -"Nothing in here. Your trash bin is empty!" => "بۇ جايدا ھېچنېمە يوق. Your trash bin is empty!", "Delete" => "ئۆچۈر" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/files_trashbin/l10n/uk.php b/apps/files_trashbin/l10n/uk.php index aa4b6595032..c54d45aaa82 100644 --- a/apps/files_trashbin/l10n/uk.php +++ b/apps/files_trashbin/l10n/uk.php @@ -2,17 +2,12 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Неможливо видалити %s назавжди", "Couldn't restore %s" => "Неможливо відновити %s", -"perform restore operation" => "виконати операцію відновлення", "Error" => "Помилка", -"delete file permanently" => "видалити файл назавжди", -"Delete permanently" => "Видалити назавжди", -"Name" => "Ім'я", -"Deleted" => "Видалено", -"_%n folder_::_%n folders_" => array("","",""), -"_%n file_::_%n files_" => array("","",""), "restored" => "відновлено", "Nothing in here. Your trash bin is empty!" => "Нічого немає. Ваший кошик для сміття пустий!", +"Name" => "Ім'я", "Restore" => "Відновити", +"Deleted" => "Видалено", "Delete" => "Видалити", "Deleted Files" => "Видалено Файлів" ); diff --git a/apps/files_trashbin/l10n/ur_PK.php b/apps/files_trashbin/l10n/ur_PK.php index f6c6a3da3c8..49c82f53872 100644 --- a/apps/files_trashbin/l10n/ur_PK.php +++ b/apps/files_trashbin/l10n/ur_PK.php @@ -1,7 +1,5 @@ <?php $TRANSLATIONS = array( -"Error" => "ایرر", -"_%n folder_::_%n folders_" => array("",""), -"_%n file_::_%n files_" => array("","") +"Error" => "ایرر" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_trashbin/l10n/vi.php b/apps/files_trashbin/l10n/vi.php index 072d799fa68..c5e899392bf 100644 --- a/apps/files_trashbin/l10n/vi.php +++ b/apps/files_trashbin/l10n/vi.php @@ -2,16 +2,11 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "Không thể óa %s vĩnh viễn", "Couldn't restore %s" => "Không thể khôi phục %s", -"perform restore operation" => "thực hiện phục hồi", "Error" => "Lỗi", -"delete file permanently" => "xóa file vĩnh viễn", -"Delete permanently" => "Xóa vĩnh vễn", -"Name" => "Tên", -"Deleted" => "Đã xóa", -"_%n folder_::_%n folders_" => array(""), -"_%n file_::_%n files_" => array(""), "Nothing in here. Your trash bin is empty!" => "Không có gì ở đây. Thùng rác của bạn rỗng!", +"Name" => "Tên", "Restore" => "Khôi phục", +"Deleted" => "Đã xóa", "Delete" => "Xóa", "Deleted Files" => "File đã xóa" ); diff --git a/apps/files_trashbin/l10n/zh_CN.php b/apps/files_trashbin/l10n/zh_CN.php index dc2d5b4c00e..24d9002adcb 100644 --- a/apps/files_trashbin/l10n/zh_CN.php +++ b/apps/files_trashbin/l10n/zh_CN.php @@ -2,17 +2,12 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "无法彻底删除文件%s", "Couldn't restore %s" => "无法恢复%s", -"perform restore operation" => "执行恢复操作", "Error" => "错误", -"delete file permanently" => "彻底删除文件", -"Delete permanently" => "永久删除", -"Name" => "名称", -"Deleted" => "已删除", -"_%n folder_::_%n folders_" => array("%n 文件夹"), -"_%n file_::_%n files_" => array("%n个文件"), "restored" => "已恢复", "Nothing in here. Your trash bin is empty!" => "这里没有东西. 你的回收站是空的!", +"Name" => "名称", "Restore" => "恢复", +"Deleted" => "已删除", "Delete" => "删除", "Deleted Files" => "已删除文件" ); diff --git a/apps/files_trashbin/l10n/zh_HK.php b/apps/files_trashbin/l10n/zh_HK.php index 3f0d663baeb..877912e9c42 100644 --- a/apps/files_trashbin/l10n/zh_HK.php +++ b/apps/files_trashbin/l10n/zh_HK.php @@ -2,8 +2,6 @@ $TRANSLATIONS = array( "Error" => "錯誤", "Name" => "名稱", -"_%n folder_::_%n folders_" => array(""), -"_%n file_::_%n files_" => array(""), "Delete" => "刪除" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/files_trashbin/l10n/zh_TW.php b/apps/files_trashbin/l10n/zh_TW.php index bfc2fc659de..1f05a2687b6 100644 --- a/apps/files_trashbin/l10n/zh_TW.php +++ b/apps/files_trashbin/l10n/zh_TW.php @@ -2,17 +2,12 @@ $TRANSLATIONS = array( "Couldn't delete %s permanently" => "無法永久刪除 %s", "Couldn't restore %s" => "無法還原 %s", -"perform restore operation" => "進行還原動作", "Error" => "錯誤", -"delete file permanently" => "永久刪除檔案", -"Delete permanently" => "永久刪除", -"Name" => "名稱", -"Deleted" => "已刪除", -"_%n folder_::_%n folders_" => array("%n 個資料夾"), -"_%n file_::_%n files_" => array("%n 個檔案"), "restored" => "已還原", "Nothing in here. Your trash bin is empty!" => "您的回收桶是空的!", +"Name" => "名稱", "Restore" => "還原", +"Deleted" => "已刪除", "Delete" => "刪除", "Deleted Files" => "已刪除的檔案" ); diff --git a/apps/files_trashbin/lib/helper.php b/apps/files_trashbin/lib/helper.php index 4f442ee9304..c454b35a5f2 100644 --- a/apps/files_trashbin/lib/helper.php +++ b/apps/files_trashbin/lib/helper.php @@ -44,8 +44,10 @@ class Helper } $files = array(); + $id = 0; foreach ($result as $r) { $i = array(); + $i['id'] = $id++; $i['name'] = $r['id']; $i['date'] = \OCP\Util::formatDate($r['timestamp']); $i['timestamp'] = $r['timestamp']; diff --git a/apps/files_trashbin/lib/trashbin.php b/apps/files_trashbin/lib/trashbin.php index c79afdc0c2e..769fd8d8990 100644 --- a/apps/files_trashbin/lib/trashbin.php +++ b/apps/files_trashbin/lib/trashbin.php @@ -41,13 +41,7 @@ class Trashbin { return array($uid, $filename); } - /** - * move file to the trash bin - * - * @param $file_path path to the deleted file/directory relative to the files root directory - */ - public static function move2trash($file_path) { - $user = \OCP\User::getUser(); + private static function setUpTrash($user) { $view = new \OC\Files\View('/' . $user); if (!$view->is_dir('files_trashbin')) { $view->mkdir('files_trashbin'); @@ -64,6 +58,48 @@ class Trashbin { if (!$view->is_dir('files_trashbin/share-keys')) { $view->mkdir('files_trashbin/share-keys'); } + } + + + private static function copyFilesToOwner($sourcePath, $owner, $ownerPath, $timestamp, $type, $mime) { + self::setUpTrash($owner); + + $ownerFilename = basename($ownerPath); + $ownerLocation = dirname($ownerPath); + + $sourceFilename = basename($sourcePath); + + $view = new \OC\Files\View('/'); + + $source = \OCP\User::getUser().'/files_trashbin/files/' . $sourceFilename . '.d' . $timestamp; + $target = $owner.'/files_trashbin/files/' . $ownerFilename . '.d' . $timestamp; + self::copy_recursive($source, $target, $view); + + + if ($view->file_exists($target)) { + $query = \OC_DB::prepare("INSERT INTO `*PREFIX*files_trash` (`id`,`timestamp`,`location`,`type`,`mime`,`user`) VALUES (?,?,?,?,?,?)"); + $result = $query->execute(array($ownerFilename, $timestamp, $ownerLocation, $type, $mime, $owner)); + if (!$result) { // if file couldn't be added to the database than also don't store it in the trash bin. + $view->deleteAll($owner.'/files_trashbin/files/' . $ownerFilename . '.d' . $timestamp); + \OC_Log::write('files_trashbin', 'trash bin database couldn\'t be updated for the files owner', \OC_log::ERROR); + return; + } + } + } + + + /** + * move file to the trash bin + * + * @param $file_path path to the deleted file/directory relative to the files root directory + */ + public static function move2trash($file_path) { + $user = \OCP\User::getUser(); + $size = 0; + list($owner, $ownerPath) = self::getUidAndFilename($file_path); + self::setUpTrash($user); + + $view = new \OC\Files\View('/' . $user); $path_parts = pathinfo($file_path); $filename = $path_parts['basename']; @@ -77,19 +113,20 @@ class Trashbin { $type = 'file'; } - $trashbinSize = self::getTrashbinSize($user); - if ($trashbinSize === false || $trashbinSize < 0) { - $trashbinSize = self::calculateSize(new \OC\Files\View('/' . $user . '/files_trashbin')); + $userTrashSize = self::getTrashbinSize($user); + if ($userTrashSize === false || $userTrashSize < 0) { + $userTrashSize = self::calculateSize(new \OC\Files\View('/' . $user . '/files_trashbin')); } // disable proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; - $sizeOfAddedFiles = self::copy_recursive($file_path, 'files_trashbin/files/' . $filename . '.d' . $timestamp, $view); + $trashPath = '/files_trashbin/files/' . $filename . '.d' . $timestamp; + $sizeOfAddedFiles = self::copy_recursive('/files/'.$file_path, $trashPath, $view); \OC_FileProxy::$enabled = $proxyStatus; if ($view->file_exists('files_trashbin/files/' . $filename . '.d' . $timestamp)) { - $trashbinSize += $sizeOfAddedFiles; + $size = $sizeOfAddedFiles; $query = \OC_DB::prepare("INSERT INTO `*PREFIX*files_trash` (`id`,`timestamp`,`location`,`type`,`mime`,`user`) VALUES (?,?,?,?,?,?)"); $result = $query->execute(array($filename, $timestamp, $location, $type, $mime, $user)); if (!$result) { // if file couldn't be added to the database than also don't store it in the trash bin. @@ -100,15 +137,31 @@ class Trashbin { \OCP\Util::emitHook('\OCA\Files_Trashbin\Trashbin', 'post_moveToTrash', array('filePath' => \OC\Files\Filesystem::normalizePath($file_path), 'trashPath' => \OC\Files\Filesystem::normalizePath($filename . '.d' . $timestamp))); - $trashbinSize += self::retainVersions($file_path, $filename, $timestamp); - $trashbinSize += self::retainEncryptionKeys($file_path, $filename, $timestamp); + $size += self::retainVersions($file_path, $filename, $timestamp); + $size += self::retainEncryptionKeys($file_path, $filename, $timestamp); + + // if owner !== user we need to also add a copy to the owners trash + if ($user !== $owner) { + self::copyFilesToOwner($file_path, $owner, $ownerPath, $timestamp, $type, $mime); + } } else { \OC_Log::write('files_trashbin', 'Couldn\'t move ' . $file_path . ' to the trash bin', \OC_log::ERROR); } - $trashbinSize -= self::expire($trashbinSize); + $userTrashSize += $size; + $userTrashSize -= self::expire($userTrashSize, $user); + self::setTrashbinSize($user, $userTrashSize); - self::setTrashbinSize($user, $trashbinSize); + // if owner !== user we also need to update the owners trash size + if($owner !== $user) { + $ownerTrashSize = self::getTrashbinSize($owner); + if ($ownerTrashSize === false || $ownerTrashSize < 0) { + $ownerTrashSize = self::calculateSize(new \OC\Files\View('/' . $owner . '/files_trashbin')); + } + $ownerTrashSize += $size; + $ownerTrashSize -= self::expire($ownerTrashSize, $owner); + self::setTrashbinSize($owner, $ownerTrashSize); + } } /** @@ -135,10 +188,16 @@ class Trashbin { if ($rootView->is_dir($owner . '/files_versions/' . $ownerPath)) { $size += self::calculateSize(new \OC\Files\View('/' . $owner . '/files_versions/' . $ownerPath)); + if ($owner !== $user) { + self::copy_recursive($owner . '/files_versions/' . $ownerPath, $owner . '/files_trashbin/versions/' . basename($ownerPath) . '.d' . $timestamp, $rootView); + } $rootView->rename($owner . '/files_versions/' . $ownerPath, $user . '/files_trashbin/versions/' . $filename . '.d' . $timestamp); } else if ($versions = \OCA\Files_Versions\Storage::getVersions($owner, $ownerPath)) { foreach ($versions as $v) { $size += $rootView->filesize($owner . '/files_versions' . $v['path'] . '.v' . $v['version']); + if ($owner !== $user) { + $rootView->copy($owner . '/files_versions' . $v['path'] . '.v' . $v['version'], $owner . '/files_trashbin/versions/' . $v['name'] . '.v' . $v['version'] . '.d' . $timestamp); + } $rootView->rename($owner . '/files_versions' . $v['path'] . '.v' . $v['version'], $user . '/files_trashbin/versions/' . $filename . '.v' . $v['version'] . '.d' . $timestamp); } } @@ -187,9 +246,15 @@ class Trashbin { // move keyfiles if ($rootView->is_dir($keyfile)) { $size += self::calculateSize(new \OC\Files\View($keyfile)); + if ($owner !== $user) { + self::copy_recursive($keyfile, $owner . '/files_trashbin/keyfiles/' . basename($ownerPath) . '.d' . $timestamp, $rootView); + } $rootView->rename($keyfile, $user . '/files_trashbin/keyfiles/' . $filename . '.d' . $timestamp); } else { $size += $rootView->filesize($keyfile . '.key'); + if ($owner !== $user) { + $rootView->copy($keyfile . '.key', $owner . '/files_trashbin/keyfiles/' . basename($ownerPath) . '.key.d' . $timestamp); + } $rootView->rename($keyfile . '.key', $user . '/files_trashbin/keyfiles/' . $filename . '.key.d' . $timestamp); } } @@ -199,6 +264,9 @@ class Trashbin { if ($rootView->is_dir($sharekeys)) { $size += self::calculateSize(new \OC\Files\View($sharekeys)); + if ($owner !== $user) { + self::copy_recursive($sharekeys, $owner . '/files_trashbin/share-keys/' . basename($ownerPath) . '.d' . $timestamp, $rootView); + } $rootView->rename($sharekeys, $user . '/files_trashbin/share-keys/' . $filename . '.d' . $timestamp); } else { // get local path to share-keys @@ -211,22 +279,23 @@ class Trashbin { // get source file parts $pathinfo = pathinfo($src); - // we only want to keep the owners key so we can access the private key - $ownerShareKey = $filename . '.' . $user . '.shareKey'; + // we only want to keep the users key so we can access the private key + $userShareKey = $filename . '.' . $user . '.shareKey'; // if we found the share-key for the owner, we need to move it to files_trashbin - if ($pathinfo['basename'] == $ownerShareKey) { + if ($pathinfo['basename'] == $userShareKey) { // calculate size $size += $rootView->filesize($sharekeys . '.' . $user . '.shareKey'); // move file - $rootView->rename($sharekeys . '.' . $user . '.shareKey', $user . '/files_trashbin/share-keys/' . $ownerShareKey . '.d' . $timestamp); + $rootView->rename($sharekeys . '.' . $user . '.shareKey', $user . '/files_trashbin/share-keys/' . $userShareKey . '.d' . $timestamp); + } elseif ($owner !== $user) { + $ownerShareKey = basename($ownerPath) . '.' . $owner . '.shareKey'; + if ($pathinfo['basename'] == $ownerShareKey) { + $rootView->rename($sharekeys . '.' . $owner . '.shareKey', $owner . '/files_trashbin/share-keys/' . $ownerShareKey . '.d' . $timestamp); + } } else { - - // calculate size - $size += filesize($src); - // don't keep other share-keys unlink($src); } @@ -496,6 +565,21 @@ class Trashbin { } /** + * @brief delete all files from the trash + */ + public static function deleteAll() { + $user = \OCP\User::getUser(); + $view = new \OC\Files\View('/' . $user); + $view->deleteAll('files_trashbin'); + self::setTrashbinSize($user, 0); + $query = \OC_DB::prepare('DELETE FROM `*PREFIX*files_trash` WHERE `user`=?'); + $query->execute(array($user)); + + return true; + } + + + /** * @brief delete file from trash bin permanently * * @param $filename path to the file @@ -530,6 +614,7 @@ class Trashbin { $size += $view->filesize('/files_trashbin/files/' . $file); } $view->unlink('/files_trashbin/files/' . $file); + \OC_Hook::emit('\OCP\Trashbin', 'delete', array('path' => '/files_trashbin/files/' . $file)); $trashbinSize -= $size; self::setTrashbinSize($user, $trashbinSize); @@ -678,7 +763,7 @@ class Trashbin { $freeSpace = self::calculateFreeSpace($size); if ($freeSpace < 0) { - $newSize = $size - self::expire($size); + $newSize = $size - self::expire($size, $user); if ($newSize !== $size) { self::setTrashbinSize($user, $newSize); } @@ -687,13 +772,19 @@ class Trashbin { /** * clean up the trash bin - * @param current size of the trash bin - * @return size of expired files + * @param int $trashbinSize current size of the trash bin + * @param string $user + * @return int size of expired files */ - private static function expire($trashbinSize) { + private static function expire($trashbinSize, $user) { + + // let the admin disable auto expire + $autoExpire = \OC_Config::getValue('trashbin_auto_expire', true); + if ($autoExpire === false) { + return 0; + } $user = \OCP\User::getUser(); - $view = new \OC\Files\View('/' . $user); $availableSpace = self::calculateFreeSpace($trashbinSize); $size = 0; @@ -741,23 +832,23 @@ class Trashbin { */ private static function copy_recursive($source, $destination, $view) { $size = 0; - if ($view->is_dir('files' . $source)) { + if ($view->is_dir($source)) { $view->mkdir($destination); - $view->touch($destination, $view->filemtime('files' . $source)); - foreach (\OC_Files::getDirectoryContent($source) as $i) { + $view->touch($destination, $view->filemtime($source)); + foreach ($view->getDirectoryContent($source) as $i) { $pathDir = $source . '/' . $i['name']; - if ($view->is_dir('files' . $pathDir)) { + if ($view->is_dir($pathDir)) { $size += self::copy_recursive($pathDir, $destination . '/' . $i['name'], $view); } else { - $size += $view->filesize('files' . $pathDir); - $view->copy('files' . $pathDir, $destination . '/' . $i['name']); - $view->touch($destination . '/' . $i['name'], $view->filemtime('files' . $pathDir)); + $size += $view->filesize($pathDir); + $view->copy($pathDir, $destination . '/' . $i['name']); + $view->touch($destination . '/' . $i['name'], $view->filemtime($pathDir)); } } } else { - $size += $view->filesize('files' . $source); - $view->copy('files' . $source, $destination); - $view->touch($destination, $view->filemtime('files' . $source)); + $size += $view->filesize($source); + $view->copy($source, $destination); + $view->touch($destination, $view->filemtime($source)); } return $size; } diff --git a/apps/files_trashbin/templates/index.php b/apps/files_trashbin/templates/index.php index 82ba0608834..f9264d4352c 100644 --- a/apps/files_trashbin/templates/index.php +++ b/apps/files_trashbin/templates/index.php @@ -1,13 +1,10 @@ -<!--[if IE 8]><style>input[type="checkbox"]{padding:0;}table td{position:static !important;}</style><![endif]--> <div id="controls"> <?php print_unescaped($_['breadcrumb']); ?> <div id="file_action_panel"></div> </div> <div id='notification'></div> -<?php if (isset($_['files']) && count($_['files']) === 0 && $_['dirlisting'] === false && !$_['ajaxLoad']):?> - <div id="emptycontent"><?php p($l->t('Nothing in here. Your trash bin is empty!'))?></div> -<?php endif; ?> +<div id="emptycontent" <?php if (!(isset($_['files']) && count($_['files']) === 0 && $_['dirlisting'] === false && !$_['ajaxLoad'])):?>class="hidden"<?php endif; ?>><?php p($l->t('Nothing in here. Your trash bin is empty!'))?></div> <input type="hidden" name="ajaxLoad" id="ajaxLoad" value="<?php p($_['ajaxLoad']); ?>" /> <input type="hidden" id="disableSharing" data-status="<?php p($_['disableSharing']); ?>"></input> @@ -17,7 +14,9 @@ <thead> <tr> <th id='headerName'> + <div id="headerName-container"> <input type="checkbox" id="select_all" /> + <label for="select_all"></label> <span class='name'><?php p($l->t( 'Name' )); ?></span> <span class='selectedActions'> <a href="" class="undelete"> @@ -26,6 +25,7 @@ <?php p($l->t('Restore'))?> </a> </span> + </div> </th> <th id="headerDate"> <span id="modified"><?php p($l->t( 'Deleted' )); ?></span> diff --git a/apps/files_trashbin/templates/part.breadcrumb.php b/apps/files_trashbin/templates/part.breadcrumb.php index 4acc298adbe..fdf78c190d0 100644 --- a/apps/files_trashbin/templates/part.breadcrumb.php +++ b/apps/files_trashbin/templates/part.breadcrumb.php @@ -3,11 +3,11 @@ <img src="<?php print_unescaped(OCP\image_path('core', 'places/home.svg'));?>" class="svg" /> </a> </div> -<?php if(count($_["breadcrumb"])):?> - <div class="crumb svg" - data-dir='/'> +<div class="crumb svg" + data-dir='/'> <a href="<?php p($_['baseURL']); ?>"><?php p($l->t("Deleted Files")); ?></a> - </div> +</div> +<?php if(count($_["breadcrumb"])):?> <?php endif;?> <?php for($i=0; $i<count($_["breadcrumb"]); $i++): $crumb = $_["breadcrumb"][$i]; diff --git a/apps/files_trashbin/templates/part.list.php b/apps/files_trashbin/templates/part.list.php index 78709d986ae..c32d9fd54da 100644 --- a/apps/files_trashbin/templates/part.list.php +++ b/apps/files_trashbin/templates/part.list.php @@ -35,18 +35,21 @@ <?php endif; ?> <?php endif; ?> > - <?php if(!isset($_['readonly']) || !$_['readonly']): ?><input type="checkbox" /><?php endif; ?> + <?php if(!isset($_['readonly']) || !$_['readonly']): ?> + <input id="select-<?php p($file['id']); ?>" type="checkbox" /> + <label for="select-<?php p($file['id']); ?>"></label> + <?php endif; ?> <?php if($file['type'] === 'dir'): ?> <?php if( $_['dirlisting'] ): ?> - <a class="name" href="<?php p($_['baseURL'].'/'.$name); ?>" title=""> + <a class="name dir" href="<?php p($_['baseURL'].'/'.$name); ?>" title=""> <?php else: ?> - <a class="name" href="<?php p($_['baseURL'].'/'.$name.'.d'.$file['timestamp']); ?>" title=""> + <a class="name dir" href="<?php p($_['baseURL'].'/'.$name.'.d'.$file['timestamp']); ?>" title=""> <?php endif; ?> <?php else: ?> <?php if( $_['dirlisting'] ): ?> - <a class="name" href="<?php p($_['downloadURL'].'/'.$name); ?>" title=""> + <a class="name file" href="<?php p($_['downloadURL'].'/'.$name); ?>" title=""> <?php else: ?> - <a class="name" href="<?php p($_['downloadURL'].'/'.$name.'.d'.$file['timestamp']);?>" title=""> + <a class="name file" href="<?php p($_['downloadURL'].'/'.$name.'.d'.$file['timestamp']);?>" title=""> <?php endif; ?> <?php endif; ?> <span class="nametext"> diff --git a/apps/files_versions/ajax/preview.php b/apps/files_versions/ajax/preview.php index c24134df534..31525028ef3 100644 --- a/apps/files_versions/ajax/preview.php +++ b/apps/files_versions/ajax/preview.php @@ -12,26 +12,34 @@ if(!\OC_App::isEnabled('files_versions')){ } $file = array_key_exists('file', $_GET) ? (string) urldecode($_GET['file']) : ''; +$user = array_key_exists('user', $_GET) ? $_GET['user'] : ''; $maxX = array_key_exists('x', $_GET) ? (int) $_GET['x'] : 44; $maxY = array_key_exists('y', $_GET) ? (int) $_GET['y'] : 44; $version = array_key_exists('version', $_GET) ? $_GET['version'] : ''; $scalingUp = array_key_exists('scalingup', $_GET) ? (bool) $_GET['scalingup'] : true; +if($user === '') { + \OC_Response::setStatus(400); //400 Bad Request + \OC_Log::write('versions-preview', 'No user parameter was passed', \OC_Log::DEBUG); + exit; +} + if($file === '' && $version === '') { \OC_Response::setStatus(400); //400 Bad Request - \OC_Log::write('core-preview', 'No file parameter was passed', \OC_Log::DEBUG); + \OC_Log::write('versions-preview', 'No file parameter was passed', \OC_Log::DEBUG); exit; } if($maxX === 0 || $maxY === 0) { \OC_Response::setStatus(400); //400 Bad Request - \OC_Log::write('core-preview', 'x and/or y set to 0', \OC_Log::DEBUG); + \OC_Log::write('versions-preview', 'x and/or y set to 0', \OC_Log::DEBUG); exit; } try{ - $preview = new \OC\Preview(\OC_User::getUser(), 'files_versions'); - $preview->setFile($file.'.v'.$version); + $preview = new \OC\Preview($user, 'files_versions', $file.'.v'.$version); + $mimetype = \OC_Helper::getFileNameMimeType($file); + $preview->setMimetype($mimetype); $preview->setMaxX($maxX); $preview->setMaxY($maxY); $preview->setScalingUp($scalingUp); diff --git a/apps/files_versions/appinfo/app.php b/apps/files_versions/appinfo/app.php index 5b1e464ba6c..8f2071dd7b6 100644 --- a/apps/files_versions/appinfo/app.php +++ b/apps/files_versions/appinfo/app.php @@ -12,6 +12,7 @@ OCP\Util::addStyle('files_versions', 'versions'); OCP\Util::connectHook('OC_Filesystem', 'write', "OCA\Files_Versions\Hooks", "write_hook"); // Listen to delete and rename signals OCP\Util::connectHook('OC_Filesystem', 'post_delete', "OCA\Files_Versions\Hooks", "remove_hook"); +OCP\Util::connectHook('OC_Filesystem', 'delete', "OCA\Files_Versions\Hooks", "pre_remove_hook"); OCP\Util::connectHook('OC_Filesystem', 'rename', "OCA\Files_Versions\Hooks", "rename_hook"); //Listen to delete user signal OCP\Util::connectHook('OC_User', 'pre_deleteUser', "OCA\Files_Versions\Hooks", "deleteUser_hook"); diff --git a/apps/files_versions/download.php b/apps/files_versions/download.php index 040a662e61b..2fe56d2e638 100644 --- a/apps/files_versions/download.php +++ b/apps/files_versions/download.php @@ -36,12 +36,7 @@ $view = new OC\Files\View('/'); $ftype = $view->getMimeType('/'.$uid.'/files/'.$filename); header('Content-Type:'.$ftype); -if ( preg_match( "/MSIE/", $_SERVER["HTTP_USER_AGENT"] ) ) { - header( 'Content-Disposition: attachment; filename="' . rawurlencode( basename($filename) ) . '"' ); -} else { - header( 'Content-Disposition: attachment; filename*=UTF-8\'\'' . rawurlencode( basename($filename) ) - . '; filename="' . rawurlencode( basename($filename) ) . '"' ); -} +OCP\Response::setContentDispositionHeader(basename($filename), 'attachment'); OCP\Response::disableCaching(); header('Content-Length: '.$view->filesize($versionName)); diff --git a/apps/files_versions/js/versions.js b/apps/files_versions/js/versions.js index 3f56a3eb698..4adf14745de 100644 --- a/apps/files_versions/js/versions.js +++ b/apps/files_versions/js/versions.js @@ -1,5 +1,12 @@ $(document).ready(function(){ + if ($('#isPublic').val()){ + // no versions actions in public mode + // beware of https://github.com/owncloud/core/issues/4545 + // as enabling this might hang Chrome + return; + } + if (typeof FileActions !== 'undefined') { // Add versions button to 'files/index.php' FileActions.register( @@ -14,7 +21,7 @@ $(document).ready(function(){ // Action to perform when clicked if (scanFiles.scanning){return;}//workaround to prevent additional http request block scanning feedback - var file = $('#dir').val()+'/'+filename; + var file = $('#dir').val().replace(/(?!<=\/)$|\/$/, '/' + filename); var createDropDown = true; // Check if drop down is already visible for a different file if (($('#dropdown').length > 0) ) { @@ -70,6 +77,7 @@ function goToVersionPage(url){ function createVersionsDropdown(filename, files) { var start = 0; + var fileEl; var html = '<div id="dropdown" class="drop drop-versions" data-file="'+escapeHTML(files)+'">'; html += '<div id="private">'; @@ -79,8 +87,9 @@ function createVersionsDropdown(filename, files) { html += '<input type="button" value="'+ t('files_versions', 'More versions...') + '" name="show-more-versions" id="show-more-versions" style="display: none;" />'; if (filename) { - $('tr').filterAttr('data-file',filename).addClass('mouseOver'); - $(html).appendTo($('tr').filterAttr('data-file',filename).find('td.filename')); + fileEl = FileList.findFileEl(filename); + fileEl.addClass('mouseOver'); + $(html).appendTo(fileEl.find('td.filename')); } else { $(html).appendTo($('thead .share')); } @@ -131,7 +140,7 @@ function createVersionsDropdown(filename, files) { var preview = '<img class="preview" src="'+revision.preview+'"/>'; - var download ='<a href="' + path + "?file=" + files + '&revision=' + revision.version + '">'; + var download ='<a href="' + path + "?file=" + encodeURIComponent(files) + '&revision=' + revision.version + '">'; download+='<img'; download+=' src="' + OC.imagePath('core', 'actions/download') + '"'; download+=' name="downloadVersion" />'; @@ -139,8 +148,7 @@ function createVersionsDropdown(filename, files) { download+='</a>'; var revert='<span class="revertVersion"'; - revert+=' id="' + revision.version + '"'; - revert+=' value="' + files + '">'; + revert+=' id="' + revision.version + '">'; revert+='<img'; revert+=' src="' + OC.imagePath('core', 'actions/history') + '"'; revert+=' name="revertVersion"'; @@ -149,14 +157,13 @@ function createVersionsDropdown(filename, files) { var version=$('<li/>'); version.attr('value', revision.version); version.html(preview + download + revert); + // add file here for proper name escaping + version.find('span.revertVersion').attr('value', files); version.appendTo('#found_versions'); } - $('tr').filterAttr('data-file',filename).addClass('mouseOver'); $('#dropdown').show('blind'); - - } $(this).click( diff --git a/apps/files_versions/l10n/de.php b/apps/files_versions/l10n/de.php index c8b45eee500..2b5bf3e9347 100644 --- a/apps/files_versions/l10n/de.php +++ b/apps/files_versions/l10n/de.php @@ -2,8 +2,8 @@ $TRANSLATIONS = array( "Could not revert: %s" => "Konnte %s nicht zurücksetzen", "Versions" => "Versionen", -"Failed to revert {file} to revision {timestamp}." => "Konnte {file} der Revision {timestamp} nicht rückgänging machen.", -"More versions..." => "Mehrere Versionen...", +"Failed to revert {file} to revision {timestamp}." => "Konnte {file} der Revision {timestamp} nicht rückgängig machen.", +"More versions..." => "Weitere Versionen...", "No other versions available" => "Keine anderen Versionen verfügbar", "Restore" => "Wiederherstellen" ); diff --git a/apps/files_versions/l10n/de_DE.php b/apps/files_versions/l10n/de_DE.php index c8b45eee500..781774dcdd9 100644 --- a/apps/files_versions/l10n/de_DE.php +++ b/apps/files_versions/l10n/de_DE.php @@ -2,7 +2,7 @@ $TRANSLATIONS = array( "Could not revert: %s" => "Konnte %s nicht zurücksetzen", "Versions" => "Versionen", -"Failed to revert {file} to revision {timestamp}." => "Konnte {file} der Revision {timestamp} nicht rückgänging machen.", +"Failed to revert {file} to revision {timestamp}." => "Konnte {file} der Revision {timestamp} nicht rückgängig machen.", "More versions..." => "Mehrere Versionen...", "No other versions available" => "Keine anderen Versionen verfügbar", "Restore" => "Wiederherstellen" diff --git a/apps/files_versions/l10n/el.php b/apps/files_versions/l10n/el.php index af608e7c042..5337f3b5a48 100644 --- a/apps/files_versions/l10n/el.php +++ b/apps/files_versions/l10n/el.php @@ -1,6 +1,6 @@ <?php $TRANSLATIONS = array( -"Could not revert: %s" => "Αδυναμία επαναφοράς του: %s", +"Could not revert: %s" => "Αδυναμία επαναφοράς: %s", "Versions" => "Εκδόσεις", "Failed to revert {file} to revision {timestamp}." => "Αποτυχία επαναφοράς του {file} στην αναθεώρηση {timestamp}.", "More versions..." => "Περισσότερες εκδόσεις...", diff --git a/apps/files_versions/l10n/eo.php b/apps/files_versions/l10n/eo.php index c023d5fbc37..cfd8b1845cb 100644 --- a/apps/files_versions/l10n/eo.php +++ b/apps/files_versions/l10n/eo.php @@ -2,6 +2,9 @@ $TRANSLATIONS = array( "Could not revert: %s" => "Ne eblas malfari: %s", "Versions" => "Versioj", +"Failed to revert {file} to revision {timestamp}." => "Malsukcesis returnigo de {file} al la revizio {timestamp}.", +"More versions..." => "Pli da versioj...", +"No other versions available" => "Ne disponeblas aliaj versioj", "Restore" => "Restaŭri" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_versions/l10n/es_MX.php b/apps/files_versions/l10n/es_MX.php new file mode 100644 index 00000000000..b7acc376978 --- /dev/null +++ b/apps/files_versions/l10n/es_MX.php @@ -0,0 +1,10 @@ +<?php +$TRANSLATIONS = array( +"Could not revert: %s" => "No se puede revertir: %s", +"Versions" => "Revisiones", +"Failed to revert {file} to revision {timestamp}." => "No se ha podido revertir {archivo} a revisión {timestamp}.", +"More versions..." => "Más versiones...", +"No other versions available" => "No hay otras versiones disponibles", +"Restore" => "Recuperar" +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_versions/l10n/id.php b/apps/files_versions/l10n/id.php index ee7061805ba..14920cc52fd 100644 --- a/apps/files_versions/l10n/id.php +++ b/apps/files_versions/l10n/id.php @@ -2,6 +2,9 @@ $TRANSLATIONS = array( "Could not revert: %s" => "Tidak dapat mengembalikan: %s", "Versions" => "Versi", +"Failed to revert {file} to revision {timestamp}." => "Gagal mengembalikan {file} ke revisi {timestamp}.", +"More versions..." => "Versi lebih...", +"No other versions available" => "Tidak ada versi lain yang tersedia", "Restore" => "Pulihkan" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/files_versions/l10n/ko.php b/apps/files_versions/l10n/ko.php index ba951c4107a..bd56c0489bf 100644 --- a/apps/files_versions/l10n/ko.php +++ b/apps/files_versions/l10n/ko.php @@ -2,9 +2,9 @@ $TRANSLATIONS = array( "Could not revert: %s" => "되돌릴 수 없습니다: %s", "Versions" => "버전", -"Failed to revert {file} to revision {timestamp}." => "{timestamp} 판의 {file}로 돌리는데 실패했습니다.", -"More versions..." => "더 많은 버전들...", -"No other versions available" => "다른 버전을 사용할수 없습니다", +"Failed to revert {file} to revision {timestamp}." => "{file}을(를) 리비전 {timestamp}으(로) 되돌리는 데 실패하였습니다.", +"More versions..." => "더 많은 버전...", +"No other versions available" => "다른 버전을 사용할 수 없습니다", "Restore" => "복원" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/files_versions/l10n/mk.php b/apps/files_versions/l10n/mk.php index 01a98808cff..d5c883b894f 100644 --- a/apps/files_versions/l10n/mk.php +++ b/apps/files_versions/l10n/mk.php @@ -1,5 +1,10 @@ <?php $TRANSLATIONS = array( -"Versions" => "Версии" +"Could not revert: %s" => "Не можев да го вратам: %s", +"Versions" => "Версии", +"Failed to revert {file} to revision {timestamp}." => "Не успеав да го вратам {file} на ревизијата {timestamp}.", +"More versions..." => "Повеќе верзии...", +"No other versions available" => "Не постојат други верзии", +"Restore" => "Врати" ); $PLURAL_FORMS = "nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;"; diff --git a/apps/files_versions/l10n/ms_MY.php b/apps/files_versions/l10n/ms_MY.php new file mode 100644 index 00000000000..513dff49b24 --- /dev/null +++ b/apps/files_versions/l10n/ms_MY.php @@ -0,0 +1,10 @@ +<?php +$TRANSLATIONS = array( +"Could not revert: %s" => "Tidak dapat kembalikan: %s", +"Versions" => "Versi", +"Failed to revert {file} to revision {timestamp}." => "Gagal kembalikan {file} ke semakan {timestamp}.", +"More versions..." => "Lagi versi...", +"No other versions available" => "Tiada lagi versi lain", +"Restore" => "Pulihkan" +); +$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/files_versions/l10n/sl.php b/apps/files_versions/l10n/sl.php index 809ab34c262..08b2f03e4c1 100644 --- a/apps/files_versions/l10n/sl.php +++ b/apps/files_versions/l10n/sl.php @@ -2,6 +2,9 @@ $TRANSLATIONS = array( "Could not revert: %s" => "Ni mogoče povrniti: %s", "Versions" => "Različice", +"Failed to revert {file} to revision {timestamp}." => "Povrnitev datoteke {file} na objavo {timestamp} je spodletelo.", +"More versions..." => "Več različic", +"No other versions available" => "Ni drugih različic", "Restore" => "Obnovi" ); $PLURAL_FORMS = "nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);"; diff --git a/apps/files_versions/l10n/tr.php b/apps/files_versions/l10n/tr.php index f2bc1e6c0aa..998c61e9270 100644 --- a/apps/files_versions/l10n/tr.php +++ b/apps/files_versions/l10n/tr.php @@ -2,6 +2,9 @@ $TRANSLATIONS = array( "Could not revert: %s" => "Geri alınamıyor: %s", "Versions" => "Sürümler", +"Failed to revert {file} to revision {timestamp}." => "{file} dosyası {timestamp} gözden geçirmesine geri alınamadı.", +"More versions..." => "Daha fazla sürüm...", +"No other versions available" => "Başka sürüm mevcut değil", "Restore" => "Geri yükle" ); $PLURAL_FORMS = "nplurals=2; plural=(n > 1);"; diff --git a/apps/files_versions/l10n/uk.php b/apps/files_versions/l10n/uk.php index d75160f2864..2f87a9e703b 100644 --- a/apps/files_versions/l10n/uk.php +++ b/apps/files_versions/l10n/uk.php @@ -2,6 +2,9 @@ $TRANSLATIONS = array( "Could not revert: %s" => "Не вдалося відновити: %s", "Versions" => "Версії", +"Failed to revert {file} to revision {timestamp}." => "Не вдалося повернути {file} до ревізії {timestamp}.", +"More versions..." => "Більше версій ...", +"No other versions available" => "Інші версії недоступні", "Restore" => "Відновити" ); $PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"; diff --git a/apps/files_versions/lib/hooks.php b/apps/files_versions/lib/hooks.php index 81ee3c8b3c6..5d3882cc3e3 100644 --- a/apps/files_versions/lib/hooks.php +++ b/apps/files_versions/lib/hooks.php @@ -46,6 +46,17 @@ class Hooks { } /** + * @brief mark file as "deleted" so that we can clean up the versions if the file is gone + * @param array $params + */ + public static function pre_remove_hook($params) { + $path = $params[\OC\Files\Filesystem::signal_param_path]; + if($path<>'') { + Storage::markDeletedFile($path); + } + } + + /** * @brief rename/move versions of renamed/moved files * @param array with oldpath and newpath * @@ -53,7 +64,7 @@ class Hooks { * of the stored versions along the actual file */ public static function rename_hook($params) { - + if (\OCP\App::isEnabled('files_versions')) { $oldpath = $params['oldpath']; $newpath = $params['newpath']; @@ -71,7 +82,7 @@ class Hooks { * to remove the used space for versions stored in the database */ public static function deleteUser_hook($params) { - + if (\OCP\App::isEnabled('files_versions')) { $uid = $params['uid']; Storage::deleteUser($uid); diff --git a/apps/files_versions/lib/versions.php b/apps/files_versions/lib/versions.php index fc8d0365c71..7e6cc818efb 100644 --- a/apps/files_versions/lib/versions.php +++ b/apps/files_versions/lib/versions.php @@ -19,6 +19,10 @@ class Storage { const DEFAULTENABLED=true; const DEFAULTMAXSIZE=50; // unit: percentage; 50% of available disk space/quota + const VERSIONS_ROOT = 'files_versions/'; + + // files for which we can remove the versions after the delete operation was successful + private static $deletedFiles = array(); private static $max_versions_per_interval = array( //first 10sec, one version every 2sec @@ -94,7 +98,6 @@ class Storage { $files_view = new \OC\Files\View('/'.$uid .'/files'); $users_view = new \OC\Files\View('/'.$uid); - $versions_view = new \OC\Files\View('/'.$uid.'/files_versions'); // check if filename is a directory if($files_view->is_dir($filename)) { @@ -128,7 +131,10 @@ class Storage { \OC_FileProxy::$enabled = false; // store a new version of a file - $users_view->copy('files'.$filename, 'files_versions'.$filename.'.v'.$users_view->filemtime('files'.$filename)); + $mtime = $users_view->filemtime('files'.$filename); + $users_view->copy('files'.$filename, 'files_versions'.$filename.'.v'. $mtime); + // call getFileInfo to enforce a file cache entry for the new version + $users_view->getFileInfo('files_versions'.$filename.'.v'.$mtime); // reset proxy state \OC_FileProxy::$enabled = $proxyStatus; @@ -141,24 +147,45 @@ class Storage { /** + * @brief mark file as deleted so that we can remove the versions if the file is gone + * @param string $path + */ + public static function markDeletedFile($path) { + list($uid, $filename) = self::getUidAndFilename($path); + self::$deletedFiles[$path] = array( + 'uid' => $uid, + 'filename' => $filename); + } + + /** * Delete versions of a file */ - public static function delete($filename) { - list($uid, $filename) = self::getUidAndFilename($filename); - $versions_fileview = new \OC\Files\View('/'.$uid .'/files_versions'); + public static function delete($path) { - $abs_path = $versions_fileview->getLocalFile($filename.'.v'); - if( ($versions = self::getVersions($uid, $filename)) ) { - $versionsSize = self::getVersionsSize($uid); - if ( $versionsSize === false || $versionsSize < 0 ) { - $versionsSize = self::calculateSize($uid); - } - foreach ($versions as $v) { - unlink($abs_path . $v['version']); - $versionsSize -= $v['size']; + $deletedFile = self::$deletedFiles[$path]; + $uid = $deletedFile['uid']; + $filename = $deletedFile['filename']; + + if (!\OC\Files\Filesystem::file_exists($path)) { + + $versions_fileview = new \OC\Files\View('/' . $uid . '/files_versions'); + + $abs_path = $versions_fileview->getLocalFile($filename . '.v'); + $versions = self::getVersions($uid, $filename); + if (!empty($versions)) { + $versionsSize = self::getVersionsSize($uid); + if ($versionsSize === false || $versionsSize < 0) { + $versionsSize = self::calculateSize($uid); + } + foreach ($versions as $v) { + unlink($abs_path . $v['version']); + \OC_Hook::emit('\OCP\Versions', 'delete', array('path' => $abs_path . $v['version'])); + $versionsSize -= $v['size']; + } + self::setVersionsSize($uid, $versionsSize); } - self::setVersionsSize($uid, $versionsSize); } + unset(self::$deletedFiles[$path]); } /** @@ -238,60 +265,39 @@ class Storage { * @param $filename file to find versions of, relative to the user files dir * @returns array */ - public static function getVersions($uid, $filename ) { - if( \OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true' ) { - $versions_fileview = new \OC\Files\View('/' . $uid . '/files_versions'); - $versionsName = $versions_fileview->getLocalFile($filename).'.v'; - $escapedVersionName = preg_replace('/(\*|\?|\[)/', '[$1]', $versionsName); - - $versions = array(); - // fetch for old versions - $matches = glob($escapedVersionName.'*'); - - if ( !$matches ) { - return $versions; - } - - sort( $matches ); - - $files_view = new \OC\Files\View('/'.$uid.'/files'); - $local_file = $files_view->getLocalFile($filename); - $local_file_md5 = \md5_file( $local_file ); - - foreach( $matches as $ma ) { - $parts = explode( '.v', $ma ); - $version = ( end( $parts ) ); - $key = $version.'#'.$filename; - $versions[$key]['cur'] = 0; - $versions[$key]['version'] = $version; - $versions[$key]['humanReadableTimestamp'] = self::getHumanReadableTimestamp($version); - $versions[$key]['path'] = $filename; - $versions[$key]['preview'] = \OCP\Util::linkToRoute('core_ajax_versions_preview', array('file' => $filename, 'version' => $version)); - $versions[$key]['size'] = $versions_fileview->filesize($filename.'.v'.$version); - - // if file with modified date exists, flag it in array as currently enabled version - ( \md5_file( $ma ) == $local_file_md5 ? $versions[$key]['fileMatch'] = 1 : $versions[$key]['fileMatch'] = 0 ); - - } - - // newest versions first - $versions = array_reverse( $versions ); - - foreach( $versions as $key => $value ) { - // flag the first matched file in array (which will have latest modification date) as current version - if ( $value['fileMatch'] ) { - $value['cur'] = 1; - break; + public static function getVersions($uid, $filename) { + $versions = array(); + // fetch for old versions + $view = new \OC\Files\View('/' . $uid . '/' . self::VERSIONS_ROOT); + + $pathinfo = pathinfo($filename); + + $files = $view->getDirectoryContent($pathinfo['dirname']); + + $versionedFile = $pathinfo['basename']; + + foreach ($files as $file) { + if ($file['type'] === 'file') { + $pos = strrpos($file['path'], '.v'); + $currentFile = substr($file['name'], 0, strrpos($file['name'], '.v')); + if ($currentFile === $versionedFile) { + $version = substr($file['path'], $pos + 2); + $key = $version . '#' . $filename; + $versions[$key]['cur'] = 0; + $versions[$key]['version'] = $version; + $versions[$key]['humanReadableTimestamp'] = self::getHumanReadableTimestamp($version); + $versions[$key]['preview'] = \OCP\Util::linkToRoute('core_ajax_versions_preview', array('file' => $filename, 'version' => $version, 'user' => $uid)); + $versions[$key]['path'] = $filename; + $versions[$key]['name'] = $versionedFile; + $versions[$key]['size'] = $file['size']; } } - - return( $versions ); - - } else { - // if versioning isn't enabled then return an empty array - return( array() ); } + // sort with newest version first + krsort($versions); + + return $versions; } /** @@ -338,22 +344,21 @@ class Storage { * @return size of vesions */ private static function calculateSize($uid) { - if( \OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true' ) { - $versions_fileview = new \OC\Files\View('/'.$uid.'/files_versions'); - $versionsRoot = $versions_fileview->getLocalFolder(''); - - $iterator = new \RecursiveIteratorIterator( - new \RecursiveDirectoryIterator($versionsRoot), - \RecursiveIteratorIterator::CHILD_FIRST - ); + if (\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED) == 'true') { + $view = new \OC\Files\View('/' . $uid . '/files_versions'); $size = 0; - foreach ($iterator as $path) { - if ( preg_match('/^.+\.v(\d+)$/', $path, $match) ) { - $relpath = substr($path, strlen($versionsRoot)-1); - $size += $versions_fileview->filesize($relpath); + $dirContent = $view->getDirectoryContent('/'); + + while (!empty($dirContent)) { + $path = reset($dirContent); + if ($path['type'] === 'dir') { + $dirContent = array_merge($dirContent, $view->getDirectoryContent(substr($path['path'], strlen('files_versions')))); + } else { + $size += $view->filesize(substr($path['path'], strlen('files_versions'))); } + unset($dirContent[key($dirContent)]); } return $size; @@ -366,48 +371,45 @@ class Storage { * @return array with contains two arrays 'all' which contains all versions sorted by age and 'by_file' which contains all versions sorted by filename */ private static function getAllVersions($uid) { - if( \OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true' ) { - $versions_fileview = new \OC\Files\View('/'.$uid.'/files_versions'); - $versionsRoot = $versions_fileview->getLocalFolder(''); - - $iterator = new \RecursiveIteratorIterator( - new \RecursiveDirectoryIterator($versionsRoot), - \RecursiveIteratorIterator::CHILD_FIRST - ); + $view = new \OC\Files\View('/' . $uid . '/'); + $dirs = array(self::VERSIONS_ROOT); - $versions = array(); + while (!empty($dirs)) { + $dir = array_pop($dirs); + $files = $view->getDirectoryContent($dir); - foreach ($iterator as $path) { - if ( preg_match('/^.+\.v(\d+)$/', $path, $match) ) { - $relpath = substr($path, strlen($versionsRoot)-1); - $versions[$match[1].'#'.$relpath] = array('path' => $relpath, 'timestamp' => $match[1]); + foreach ($files as $file) { + if ($file['type'] === 'dir') { + array_push($dirs, $file['path']); + } else { + $versionsBegin = strrpos($file['path'], '.v'); + $relPathStart = strlen(self::VERSIONS_ROOT); + $version = substr($file['path'], $versionsBegin + 2); + $relpath = substr($file['path'], $relPathStart, $versionsBegin - $relPathStart); + $key = $version . '#' . $relpath; + $versions[$key] = array('path' => $relpath, 'timestamp' => $version); } } + } - ksort($versions); - - $i = 0; - - $result = array(); + ksort($versions); - foreach( $versions as $key => $value ) { - $i++; - $size = $versions_fileview->filesize($value['path']); - $filename = substr($value['path'], 0, -strlen($value['timestamp'])-2); + $result = array(); - $result['all'][$key]['version'] = $value['timestamp']; - $result['all'][$key]['path'] = $filename; - $result['all'][$key]['size'] = $size; + foreach ($versions as $key => $value) { + $size = $view->filesize($value['path']); + $filename = $value['path']; - $filename = substr($value['path'], 0, -strlen($value['timestamp'])-2); - $result['by_file'][$filename][$key]['version'] = $value['timestamp']; - $result['by_file'][$filename][$key]['path'] = $filename; - $result['by_file'][$filename][$key]['size'] = $size; + $result['all'][$key]['version'] = $value['timestamp']; + $result['all'][$key]['path'] = $filename; + $result['all'][$key]['size'] = $size; - } - - return $result; + $result['by_file'][$filename][$key]['version'] = $value['timestamp']; + $result['by_file'][$filename][$key]['path'] = $filename; + $result['by_file'][$filename][$key]['size'] = $size; } + + return $result; } /** @@ -489,6 +491,7 @@ class Storage { while ($availableSpace < 0 && $i < $numOfVersions) { $version = current($allVersions); $versionsFileview->unlink($version['path'].'.v'.$version['version']); + \OC_Hook::emit('\OCP\Versions', 'delete', array('path' => $version['path'].'.v'.$version['version'])); $versionsSize -= $version['size']; $availableSpace += $version['size']; next($allVersions); @@ -539,6 +542,7 @@ class Storage { if ($version['version'] > $nextVersion) { //distance between two version too small, delete version $versionsFileview->unlink($version['path'] . '.v' . $version['version']); + \OC_Hook::emit('\OCP\Versions', 'delete', array('path' => $version['path'] . '.v' . $version['version'])); $size += $version['size']; unset($allVersions[$key]); // update array with all versions } else { diff --git a/apps/user_ldap/ajax/setConfiguration.php b/apps/user_ldap/ajax/setConfiguration.php index 94de8835fbc..84acecee5da 100644 --- a/apps/user_ldap/ajax/setConfiguration.php +++ b/apps/user_ldap/ajax/setConfiguration.php @@ -27,6 +27,18 @@ OCP\JSON::checkAppEnabled('user_ldap'); OCP\JSON::callCheck(); $prefix = $_POST['ldap_serverconfig_chooser']; + +// Checkboxes are not submitted, when they are unchecked. Set them manually. +// only legacy checkboxes (Advanced and Expert tab) need to be handled here, +// the Wizard-like tabs handle it on their own +$chkboxes = array('ldap_configuration_active', 'ldap_override_main_server', + 'ldap_nocase', 'ldap_turn_off_cert_check'); +foreach($chkboxes as $boxid) { + if(!isset($_POST[$boxid])) { + $_POST[$boxid] = 0; + } +} + $ldapWrapper = new OCA\user_ldap\lib\LDAP(); $connection = new \OCA\user_ldap\lib\Connection($ldapWrapper, $prefix); $connection->setConfiguration($_POST); diff --git a/apps/user_ldap/ajax/testConfiguration.php b/apps/user_ldap/ajax/testConfiguration.php index 0b8e4ccfe20..a6375209611 100644 --- a/apps/user_ldap/ajax/testConfiguration.php +++ b/apps/user_ldap/ajax/testConfiguration.php @@ -30,6 +30,8 @@ $l=OC_L10N::get('user_ldap'); $ldapWrapper = new OCA\user_ldap\lib\LDAP(); $connection = new \OCA\user_ldap\lib\Connection($ldapWrapper, '', null); +//needs to be true, otherwise it will also fail with an irritating message +$_POST['ldap_configuration_active'] = 1; if($connection->setConfiguration($_POST)) { //Configuration is okay if($connection->bind()) { @@ -41,5 +43,5 @@ if($connection->setConfiguration($_POST)) { } } else { OCP\JSON::error(array('message' - => $l->t('The configuration is invalid. Please look in the ownCloud log for further details.'))); + => $l->t('The configuration is invalid. Please have a look at the logs for further details.'))); } diff --git a/apps/user_ldap/ajax/wizard.php b/apps/user_ldap/ajax/wizard.php new file mode 100644 index 00000000000..ad75a384369 --- /dev/null +++ b/apps/user_ldap/ajax/wizard.php @@ -0,0 +1,102 @@ +<?php + +/** + * ownCloud - user_ldap + * + * @author Arthur Schiwon + * @copyright 2013 Arthur Schiwon blizzz@owncloud.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library 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 along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +// Check user and app status +OCP\JSON::checkAdminUser(); +OCP\JSON::checkAppEnabled('user_ldap'); +OCP\JSON::callCheck(); + +$l=OC_L10N::get('user_ldap'); + +if(!isset($_POST['action'])) { + \OCP\JSON::error(array('message' => $l->t('No action specified'))); +} +$action = $_POST['action']; + + +if(!isset($_POST['ldap_serverconfig_chooser'])) { + \OCP\JSON::error(array('message' => $l->t('No configuration specified'))); +} +$prefix = $_POST['ldap_serverconfig_chooser']; + +$ldapWrapper = new OCA\user_ldap\lib\LDAP(); +$configuration = new \OCA\user_ldap\lib\Configuration($prefix); +$wizard = new \OCA\user_ldap\lib\Wizard($configuration, $ldapWrapper); + +switch($action) { + case 'guessPortAndTLS': + case 'guessBaseDN': + case 'determineGroupMemberAssoc': + case 'determineUserObjectClasses': + case 'determineGroupObjectClasses': + case 'determineGroupsForUsers': + case 'determineGroupsForGroups': + case 'determineAttributes': + case 'getUserListFilter': + case 'getLoginFilterMode': + case 'getUserLoginFilter': + case 'getUserFilterMode': + case 'getGroupFilter': + case 'getGroupFilterMode': + case 'countUsers': + case 'countGroups': + try { + $result = $wizard->$action(); + if($result !== false) { + OCP\JSON::success($result->getResultArray()); + exit; + } + } catch (\Exception $e) { + \OCP\JSON::error(array('message' => $e->getMessage())); + exit; + } + \OCP\JSON::error(); + exit; + break; + + case 'save': + $key = isset($_POST['cfgkey']) ? $_POST['cfgkey'] : false; + $val = isset($_POST['cfgval']) ? $_POST['cfgval'] : null; + if($key === false || is_null($val)) { + \OCP\JSON::error(array('message' => $l->t('No data specified'))); + exit; + } + $cfg = array($key => $val); + $setParameters = array(); + $configuration->setConfiguration($cfg, $setParameters); + if(!in_array($key, $setParameters)) { + \OCP\JSON::error(array('message' => $l->t($key. + ' Could not set configuration %s', $setParameters[0]))); + exit; + } + $configuration->saveConfiguration(); + //clear the cache on save + $connection = new \OCA\user_ldap\lib\Connection($ldapWrapper, $prefix); + $connection->clearCache(); + OCP\JSON::success(); + break; + default: + //TODO: return 4xx error + break; +} + diff --git a/apps/user_ldap/appinfo/app.php b/apps/user_ldap/appinfo/app.php index 9d6327181af..c2cd295523e 100644 --- a/apps/user_ldap/appinfo/app.php +++ b/apps/user_ldap/appinfo/app.php @@ -30,7 +30,7 @@ if(count($configPrefixes) === 1) { $ldapAccess = new OCA\user_ldap\lib\Access($connector, $ldapWrapper); $userBackend = new OCA\user_ldap\USER_LDAP($ldapAccess); $groupBackend = new OCA\user_ldap\GROUP_LDAP($ldapAccess); -} else { +} else if(count($configPrefixes) > 1) { $userBackend = new OCA\user_ldap\User_Proxy($configPrefixes, $ldapWrapper); $groupBackend = new OCA\user_ldap\Group_Proxy($configPrefixes, $ldapWrapper); } diff --git a/apps/user_ldap/appinfo/update.php b/apps/user_ldap/appinfo/update.php index 179451dad69..41770cf97b1 100644 --- a/apps/user_ldap/appinfo/update.php +++ b/apps/user_ldap/appinfo/update.php @@ -1,20 +1,5 @@ <?php -//from version 0.1 to 0.2 - -//ATTENTION -//Upgrade from ownCloud 3 (LDAP backend 0.1) to ownCloud 4.5 (LDAP backend 0.3) is not supported!! -//You must do upgrade to ownCloud 4.0 first! -//The upgrade stuff in the section from 0.1 to 0.2 is just to minimize the bad effects. - -//settings -$pw = OCP\Config::getAppValue('user_ldap', 'ldap_password'); -if(!is_null($pw)) { - $pwEnc = base64_encode($pw); - OCP\Config::setAppValue('user_ldap', 'ldap_agent_password', $pwEnc); - OC_Appconfig::deleteKey('user_ldap', 'ldap_password'); -} - //detect if we can switch on naming guidelines. We won't do it on conflicts. //it's a bit spaghetti, but hey. $state = OCP\Config::getSystemValue('ldapIgnoreNamingRules', 'unset'); @@ -22,75 +7,21 @@ if($state === 'unset') { OCP\Config::setSystemValue('ldapIgnoreNamingRules', false); } -//from version 0.2 to 0.3 (0.2.0.x dev version) -$objects = array('user', 'group'); - -$connector = new \OCA\user_ldap\lib\Connection(); -$userBE = new \OCA\user_ldap\USER_LDAP(); -$userBE->setConnector($connector); -$groupBE = new \OCA\user_ldap\GROUP_LDAP(); -$groupBE->setConnector($connector); - -foreach($objects as $object) { - $fetchDNSql = ' - SELECT `ldap_dn`, `owncloud_name`, `directory_uuid` - FROM `*PREFIX*ldap_'.$object.'_mapping`'; - $updateSql = ' - UPDATE `*PREFIX*ldap_'.$object.'_mapping` - SET `ldap_DN` = ?, `directory_uuid` = ? - WHERE `ldap_dn` = ?'; - - $query = OCP\DB::prepare($fetchDNSql); - $res = $query->execute(); - $DNs = $res->fetchAll(); - $updateQuery = OCP\DB::prepare($updateSql); - foreach($DNs as $dn) { - $newDN = escapeDN(mb_strtolower($dn['ldap_dn'], 'UTF-8')); - if(!empty($dn['directory_uuid'])) { - $uuid = $dn['directory_uuid']; - } elseif($object === 'user') { - $uuid = $userBE->getUUID($newDN); - //fix home folder to avoid new ones depending on the configuration - $userBE->getHome($dn['owncloud_name']); - } else { - $uuid = $groupBE->getUUID($newDN); - } - try { - $updateQuery->execute(array($newDN, $uuid, $dn['ldap_dn'])); - } catch(Exception $e) { - \OCP\Util::writeLog('user_ldap', - 'Could not update '.$object.' '.$dn['ldap_dn'].' in the mappings table. ', - \OCP\Util::WARN); - } - - } -} - -function escapeDN($dn) { - $aDN = ldap_explode_dn($dn, false); - unset($aDN['count']); - foreach($aDN as $key => $part) { - $value = substr($part, strpos($part, '=')+1); - $escapedValue = strtr($value, Array(','=>'\2c', '='=>'\3d', '+'=>'\2b', - '<'=>'\3c', '>'=>'\3e', ';'=>'\3b', '\\'=>'\5c', - '"'=>'\22', '#'=>'\23')); - $part = str_replace($part, $value, $escapedValue); - } - $dn = implode(',', $aDN); - - return $dn; -} - - -// SUPPORTED UPGRADE FROM Version 0.3 (ownCloud 4.5) to 0.4 (ownCloud 5) - -if(!isset($connector)) { - $connector = new \OCA\user_ldap\lib\Connection(); +$configPrefixes = OCA\user_ldap\lib\Helper::getServerConfigurationPrefixes(true); +$ldap = new OCA\user_ldap\lib\LDAP(); +foreach($configPrefixes as $config) { + $connection = new OCA\user_ldap\lib\Connection($ldap, $config); + $value = \OCP\Config::getAppValue('user_ldap', + $config.'ldap_uuid_attribute', 'auto'); + \OCP\Config::setAppValue('user_ldap', + $config.'ldap_uuid_user_attribute', $value); + \OCP\Config::setAppValue('user_ldap', + $config.'ldap_uuid_group_attribute', $value); + + $value = \OCP\Config::getAppValue('user_ldap', + $config.'ldap_expert_uuid_attr', 'auto'); + \OCP\Config::setAppValue('user_ldap', + $config.'ldap_expert_uuid_user_attr', $value); + \OCP\Config::setAppValue('user_ldap', + $config.'ldap_expert_uuid_group_attr', $value); } -//it is required, that connections do have ldap_configuration_active setting stored in the database -$connector->getConfiguration(); -$connector->saveConfiguration(); - -// we don't save it anymore, was a well-meant bad idea. Clean up database. -$query = OC_DB::prepare('DELETE FROM `*PREFIX*preferences` WHERE `appid` = ? AND `configkey` = ?'); -$query->execute(array('user_ldap' , 'homedir')); diff --git a/apps/user_ldap/appinfo/version b/apps/user_ldap/appinfo/version index 60a2d3e96c8..44bb5d1f743 100644 --- a/apps/user_ldap/appinfo/version +++ b/apps/user_ldap/appinfo/version @@ -1 +1 @@ -0.4.0
\ No newline at end of file +0.4.1
\ No newline at end of file diff --git a/apps/user_ldap/css/settings.css b/apps/user_ldap/css/settings.css index 55ca503adf5..44d74926b37 100644 --- a/apps/user_ldap/css/settings.css +++ b/apps/user_ldap/css/settings.css @@ -1,3 +1,86 @@ +.table { + display: table; + width: 60%; +} + +.tablerow { + display: table-row; + white-space: nowrap; +} + +.tablerow input, .tablerow textarea { + width: 100% !important; +} + +.tablerow textarea { + height: 15px; +} + +.invisible { + visibility: hidden; +} + +.ldapSettingsTabs { + float: right !important; +} + +.ldapWizardControls { + width: 60%; + text-align: right; +} + +.ldapWizardInfo { + width: 100% !important; + height: 50px; + background-color: lightyellow; + border-radius: 0.5em; + padding: 0.6em 0.5em 0.4em !important; + margin-bottom: 0.3em; +} + +#ldapWizard1 .hostPortCombinator { + width: 60%; + display: table; +} + +#ldapWizard1 .hostPortCombinator div span { + width: 7%; + display: table-cell; + text-align: right; +} + +#ldapWizard1 .host { + width: 96.5% !important; +} + +.tableCellInput { + margin-left: -40%; + width: 100%; +} + +.tableCellLabel { + text-align: right; + padding-right: 25%; +} + +.ldapIndent { + margin-left: 50px; +} + +.ldapwarning { + margin-left: 1.4em; + color: #FF3B3B; +} + +.wizSpinner { + height: 15px; + margin: 0.3em; +} + +.ldapSettingControls { + margin-top: 3ex; +} + #ldap fieldset p label { width: 20%; max-width: 200px; @@ -8,20 +91,43 @@ padding-right: 5px; } +#ldap fieldset input[type=submit] { + width: auto; +} + #ldap fieldset input, #ldap fieldset textarea { - width: 60%; - display: inline-block; + width: 60%; } #ldap fieldset p input[type=checkbox] { vertical-align: bottom; } -.ldapIndent { - margin-left: 50px; +select[multiple=multiple] + button { + height: 28px; + padding-top: 6px !important; + min-width: 40%; + max-width: 40%; } .ldapwarning { margin-left: 22px; color: #FF3B3B; } +.ldap_config_state_indicator_sign { + display: inline-block; + height: 16px; + width: 16px; + vertical-align: text-bottom; +} +.ldap_config_state_indicator_sign.success { + background: #37ce02; + border-radius: 8px; +} +.ldap_config_state_indicator_sign.error { + background: #ce3702; +} + +.ldap_grey { + color: #777; +} diff --git a/apps/user_ldap/group_proxy.php b/apps/user_ldap/group_proxy.php index acc563c9532..4404bd7fe3a 100644 --- a/apps/user_ldap/group_proxy.php +++ b/apps/user_ldap/group_proxy.php @@ -67,16 +67,17 @@ class Group_Proxy extends lib\Proxy implements \OCP\GroupInterface { * @param $gid string, the gid connected to the request * @param $method string, the method of the group backend that shall be called * @param $parameters an array of parameters to be passed + * @param $passOnWhen the result matches this variable * @return mixed, the result of the method or false */ - protected function callOnLastSeenOn($gid, $method, $parameters) { + protected function callOnLastSeenOn($gid, $method, $parameters, $passOnWhen) { $cacheKey = $this->getGroupCacheKey($gid);; $prefix = $this->getFromCache($cacheKey); //in case the uid has been found in the past, try this stored connection first if(!is_null($prefix)) { if(isset($this->backends[$prefix])) { $result = call_user_func_array(array($this->backends[$prefix], $method), $parameters); - if(!$result) { + if($result === $passOnWhen) { //not found here, reset cache to null if group vanished //because sometimes methods return false with a reason $groupExists = call_user_func_array( diff --git a/apps/user_ldap/js/settings.js b/apps/user_ldap/js/settings.js index 20d6f76dcd6..acf88ef58a4 100644 --- a/apps/user_ldap/js/settings.js +++ b/apps/user_ldap/js/settings.js @@ -30,6 +30,7 @@ var LdapConfiguration = { // assign the value $('#'+configkey).val(configvalue); }); + LdapWizard.init(); } } ); @@ -91,6 +92,7 @@ var LdapConfiguration = { $('#ldap_serverconfig_chooser option:selected').removeAttr('selected'); var html = '<option value="'+result.configPrefix+'" selected="selected">'+$('#ldap_serverconfig_chooser option').length+'. Server</option>'; $('#ldap_serverconfig_chooser option:last').before(html); + LdapWizard.init(); } else { OC.dialogs.alert( result.message, @@ -101,10 +103,24 @@ var LdapConfiguration = { ); }, + testConfiguration: function(onSuccess, onError) { + $.post( + OC.filePath('user_ldap','ajax','testConfiguration.php'), + $('#ldap').serialize(), + function (result) { + if (result.status === 'success') { + onSuccess(result); + } else { + onError(result); + } + } + ); + }, + clearMappings: function(mappingSubject) { $.post( OC.filePath('user_ldap','ajax','clearMappings.php'), - 'ldap_clear_mapping='+mappingSubject, + 'ldap_clear_mapping='+encodeURIComponent(mappingSubject), function(result) { if(result.status == 'success') { OC.dialogs.info( @@ -122,30 +138,779 @@ var LdapConfiguration = { } }; +var LdapWizard = { + checkPortInfoShown: false, + saveBlacklist: {}, + userFilterGroupSelectState: 'enable', + spinner: '<img class="wizSpinner" src="'+ OC.imagePath('core', 'loading.gif') +'">', + filterModeAssisted: 0, + filterModeRaw: 1, + + ajax: function(param, fnOnSuccess, fnOnError) { + $.post( + OC.filePath('user_ldap','ajax','wizard.php'), + param, + function(result) { + if(result.status == 'success') { + fnOnSuccess(result); + } else { + fnOnError(result); + } + } + ); + }, + + applyChanges: function (result) { + for (id in result.changes) { + LdapWizard.blacklistAdd(id); + if(id.indexOf('count') > 0) { + $('#'+id).text(result.changes[id]); + } else { + $('#'+id).val(result.changes[id]); + } + } + LdapWizard.functionalityCheck(); + + if($('#ldapSettings').tabs('option', 'active') == 0) { + LdapWizard.basicStatusCheck(); + } + }, + + basicStatusCheck: function() { + //criterias to continue from the first tab + // - host, port, user filter, agent dn, password, base dn + host = $('#ldap_host').val(); + port = $('#ldap_port').val(); + agent = $('#ldap_dn').val(); + pwd = $('#ldap_agent_password').val(); + base = $('#ldap_base').val(); + + if((host && port && base) && ((!agent && !pwd) || (agent && pwd))) { + $('.ldap_action_continue').removeAttr('disabled'); + $('#ldapSettings').tabs('option', 'disabled', []); + } else { + $('.ldap_action_continue').attr('disabled', 'disabled'); + $('#ldapSettings').tabs('option', 'disabled', [1, 2, 3, 4, 5]); + } + }, + + + blacklistAdd: function(id) { + obj = $('#'+id); + if(!(obj[0].hasOwnProperty('multiple') && obj[0]['multiple'] == true)) { + //no need to blacklist multiselect + LdapWizard.saveBlacklist[id] = true; + return true; + } + return false; + }, + + blacklistRemove: function(id) { + if(LdapWizard.saveBlacklist.hasOwnProperty(id)) { + delete LdapWizard.saveBlacklist[id]; + return true; + } + return false; + }, + + checkBaseDN: function() { + host = $('#ldap_host').val(); + port = $('#ldap_port').val(); + user = $('#ldap_dn').val(); + pass = $('#ldap_agent_password').val(); + + //FIXME: determine base dn with anonymous access + if(host && port && user && pass) { + param = 'action=guessBaseDN'+ + '&ldap_serverconfig_chooser='+ + encodeURIComponent($('#ldap_serverconfig_chooser').val()); + + LdapWizard.showSpinner('#ldap_base'); + $('#ldap_base').prop('disabled', 'disabled'); + LdapWizard.ajax(param, + function(result) { + LdapWizard.applyChanges(result); + LdapWizard.hideSpinner('#ldap_base'); + if($('#ldap_base').val()) { + LdapWizard.hideInfoBox(); + } + $('#ldap_base').prop('disabled', false); + }, + function (result) { + LdapWizard.hideSpinner('#ldap_base'); + LdapWizard.showInfoBox('Please specify a Base DN'); + LdapWizard.showInfoBox('Could not determine Base DN'); + } + ); + } + }, + + checkPort: function() { + host = $('#ldap_host').val(); + port = $('#ldap_port').val(); + + if(host && !port) { + param = 'action=guessPortAndTLS'+ + '&ldap_serverconfig_chooser='+ + encodeURIComponent($('#ldap_serverconfig_chooser').val()); + + LdapWizard.showSpinner('#ldap_port'); + $('#ldap_port').prop('disabled', 'disabled'); + LdapWizard.ajax(param, + function(result) { + LdapWizard.applyChanges(result); + LdapWizard.hideSpinner('#ldap_port'); + if($('#ldap_port').val()) { + LdapWizard.checkBaseDN(); + $('#ldap_port').prop('disabled', false); + LdapWizard.hideInfoBox(); + } + }, + function (result) { + LdapWizard.hideSpinner('#ldap_port'); + $('#ldap_port').prop('disabled', false); + LdapWizard.showInfoBox('Please specify the port'); + } + ); + } + }, + + composeFilter: function(type) { + subject = type.charAt(0).toUpperCase() + type.substr(1); + if(!$('#raw'+subject+'FilterContainer').hasClass('invisible')) { + //Raw filter editing, i.e. user defined filter, don't compose + return; + } + + if(type == 'user') { + action = 'getUserListFilter'; + } else if(type == 'login') { + action = 'getUserLoginFilter'; + } else if(type == 'group') { + action = 'getGroupFilter'; + } + + param = 'action='+action+ + '&ldap_serverconfig_chooser='+ + encodeURIComponent($('#ldap_serverconfig_chooser').val()); + + LdapWizard.ajax(param, + function(result) { + LdapWizard.applyChanges(result); + if(type == 'user') { + LdapWizard.countUsers(); + } else if(type == 'group') { + LdapWizard.countGroups(); + LdapWizard.detectGroupMemberAssoc(); + } + }, + function (result) { + // error handling + } + ); + }, + + controlBack: function() { + curTabIndex = $('#ldapSettings').tabs('option', 'active'); + if(curTabIndex == 0) { + return; + } + $('#ldapSettings').tabs('option', 'active', curTabIndex - 1); + LdapWizard.controlUpdate(curTabIndex - 1); + }, + + controlContinue: function() { + curTabIndex = $('#ldapSettings').tabs('option', 'active'); + if(curTabIndex == 3) { + return; + } + $('#ldapSettings').tabs('option', 'active', 1 + curTabIndex); + LdapWizard.controlUpdate(curTabIndex + 1); + }, + + controlUpdate: function(nextTabIndex) { + if(nextTabIndex == 0) { + $('.ldap_action_back').addClass('invisible'); + $('.ldap_action_continue').removeClass('invisible'); + } else + if(nextTabIndex == 1) { + $('.ldap_action_back').removeClass('invisible'); + $('.ldap_action_continue').removeClass('invisible'); + } else + if(nextTabIndex == 2) { + $('.ldap_action_continue').removeClass('invisible'); + $('.ldap_action_back').removeClass('invisible'); + } else + if(nextTabIndex == 3) { + //now last tab + $('.ldap_action_back').removeClass('invisible'); + $('.ldap_action_continue').addClass('invisible'); + } + }, + + _countThings: function(method) { + param = 'action='+method+ + '&ldap_serverconfig_chooser='+ + encodeURIComponent($('#ldap_serverconfig_chooser').val()); + + LdapWizard.ajax(param, + function(result) { + LdapWizard.applyChanges(result); + }, + function (result) { + // error handling + } + ); + }, + + countGroups: function() { + LdapWizard._countThings('countGroups'); + }, + + countUsers: function() { + LdapWizard._countThings('countUsers'); + }, + + detectGroupMemberAssoc: function() { + param = 'action=determineGroupMemberAssoc'+ + '&ldap_serverconfig_chooser='+ + encodeURIComponent($('#ldap_serverconfig_chooser').val()); + + LdapWizard.ajax(param, + function(result) { + //pure background story + }, + function (result) { + // error handling + } + ); + }, + + findAttributes: function() { + param = 'action=determineAttributes'+ + '&ldap_serverconfig_chooser='+ + encodeURIComponent($('#ldap_serverconfig_chooser').val()); + + LdapWizard.showSpinner('#ldap_loginfilter_attributes'); + LdapWizard.ajax(param, + function(result) { + $('#ldap_loginfilter_attributes').find('option').remove(); + for (i in result.options['ldap_loginfilter_attributes']) { + //FIXME: move HTML into template + attr = result.options['ldap_loginfilter_attributes'][i]; + $('#ldap_loginfilter_attributes').append( + "<option value='"+attr+"'>"+attr+"</option>"); + } + LdapWizard.hideSpinner('#ldap_loginfilter_attributes'); + LdapWizard.applyChanges(result); + $('#ldap_loginfilter_attributes').multiselect('refresh'); + if($('#rawLoginFilterContainer').hasClass('invisible')) { + $('#ldap_loginfilter_attributes').multiselect('enable'); + } + LdapWizard.postInitLoginFilter(); + }, + function (result) { + //deactivate if no attributes found + $('#ldap_loginfilter_attributes').multiselect( + {noneSelectedText : 'No attributes found'}); + $('#ldap_loginfilter_attributes').multiselect('disable'); + LdapWizard.hideSpinner('#ldap_loginfilter_attributes'); + } + ); + }, + + findAvailableGroups: function(multisel, type) { + if(type != 'Users' && type != 'Groups') { + return false; + } + param = 'action=determineGroupsFor'+encodeURIComponent(type)+ + '&ldap_serverconfig_chooser='+ + encodeURIComponent($('#ldap_serverconfig_chooser').val()); + + LdapWizard.showSpinner('#'+multisel); + LdapWizard.ajax(param, + function(result) { + $('#'+multisel).find('option').remove(); + for (i in result.options[multisel]) { + //FIXME: move HTML into template + objc = result.options[multisel][i]; + $('#'+multisel).append("<option value='"+objc+"'>"+objc+"</option>"); + } + LdapWizard.hideSpinner('#'+multisel); + LdapWizard.applyChanges(result); + $('#'+multisel).multiselect('refresh'); + part = type.slice(0, -1); + if($('#raw' + part + 'FilterContainer').hasClass('invisible')) { + //enable only when raw filter editing is not turned on + $('#'+multisel).multiselect('enable'); + } + if(type === 'Users') { + //required for initial save + filter = $('#ldap_userlist_filter').val(); + if(!filter) { + LdapWizard.saveMultiSelect(multisel, + $('#'+multisel).multiselect("getChecked")); + } + LdapWizard.userFilterAvailableGroupsHasRun = true; + LdapWizard.postInitUserFilter(); + } + }, + function (result) { + LdapWizard.hideSpinner('#'+multisel); + $('#'+multisel).multiselect('disable'); + if(type == 'Users') { + LdapWizard.userFilterAvailableGroupsHasRun = true; + LdapWizard.postInitUserFilter(); + } + } + ); + }, + + findObjectClasses: function(multisel, type) { + if(type != 'User' && type != 'Group') { + return false; + } + param = 'action=determine'+encodeURIComponent(type)+'ObjectClasses'+ + '&ldap_serverconfig_chooser='+ + encodeURIComponent($('#ldap_serverconfig_chooser').val()); + + LdapWizard.showSpinner('#'+multisel); + LdapWizard.ajax(param, + function(result) { + $('#'+multisel).find('option').remove(); + for (i in result.options[multisel]) { + //FIXME: move HTML into template + objc = result.options[multisel][i]; + $('#'+multisel).append("<option value='"+objc+"'>"+objc+"</option>"); + } + LdapWizard.hideSpinner('#'+multisel); + LdapWizard.applyChanges(result); + $('#'+multisel).multiselect('refresh'); + if(type === 'User') { + //required for initial save + filter = $('#ldap_userlist_filter').val(); + if(!filter) { + LdapWizard.saveMultiSelect(multisel, + $('#'+multisel).multiselect("getChecked")); + } + LdapWizard.userFilterObjectClassesHasRun = true; + LdapWizard.postInitUserFilter(); + } + }, + function (result) { + LdapWizard.hideSpinner('#'+multisel); + if(type == 'User') { + LdapWizard.userFilterObjectClassesHasRun = true; + LdapWizard.postInitUserFilter(); + } + //TODO: error handling + } + ); + }, + + functionalityCheck: function() { + //criterias to enable the connection: + // - host, port, basedn, user filter, login filter + host = $('#ldap_host').val(); + port = $('#ldap_port').val(); + base = $('#ldap_base').val(); + userfilter = $('#ldap_userlist_filter').val(); + loginfilter = $('#ldap_login_filter').val(); + + //FIXME: activates a manually deactivated configuration. + if(host && port && base && userfilter && loginfilter) { + LdapWizard.updateStatusIndicator(true); + if($('#ldap_configuration_active').is(':checked')) { + return; + } + if(!LdapWizard.isConfigurationActiveControlLocked) { + //avoids a manually deactivated connection will be activated + //upon opening the admin page + $('#ldap_configuration_active').prop('checked', true); + LdapWizard.save($('#ldap_configuration_active')[0]); + } + } else { + if($('#ldap_configuration_active').is(':checked')) { + $('#ldap_configuration_active').prop('checked', false); + LdapWizard.save($('#ldap_configuration_active')[0]); + } + LdapWizard.updateStatusIndicator(false); + } + }, + + hideInfoBox: function() { + if(LdapWizard.checkInfoShown) { + $('#ldapWizard1 .ldapWizardInfo').addClass('invisible'); + LdapWizard.checkInfoShown = false; + } + }, + + hideSpinner: function(id) { + $(id+' + .wizSpinner').remove(); + $(id + " + button").css('display', 'inline'); + }, + + isConfigurationActiveControlLocked: true, + + init: function() { + LdapWizard.basicStatusCheck(); + LdapWizard.functionalityCheck(); + LdapWizard.isConfigurationActiveControlLocked = false; + }, + + initGroupFilter: function() { + LdapWizard.regardFilterMode('Group'); + LdapWizard.findObjectClasses('ldap_groupfilter_objectclass', 'Group'); + LdapWizard.findAvailableGroups('ldap_groupfilter_groups', 'Groups'); + LdapWizard.countGroups(); + }, + + /** init login filter tab section **/ + + initLoginFilter: function() { + LdapWizard.regardFilterMode('Login'); + LdapWizard.findAttributes(); + }, + + postInitLoginFilter: function() { + if($('#rawLoginFilterContainer').hasClass('invisible')) { + LdapWizard.composeFilter('login'); + } + }, + + /** end of init user filter tab section **/ + + initMultiSelect: function(object, id, caption) { + object.multiselect({ + header: false, + selectedList: 9, + noneSelectedText: caption, + click: function(event, ui) { + LdapWizard.saveMultiSelect(id, + $('#'+id).multiselect("getChecked")); + } + }); + }, + + /** init user filter tab section **/ + + userFilterObjectClassesHasRun: false, + userFilterAvailableGroupsHasRun: false, + + initUserFilter: function() { + LdapWizard.userFilterObjectClassesHasRun = false; + LdapWizard.userFilterAvailableGroupsHasRun = false; + LdapWizard.regardFilterMode('User'); + LdapWizard.findObjectClasses('ldap_userfilter_objectclass', 'User'); + LdapWizard.findAvailableGroups('ldap_userfilter_groups', 'Users'); + }, + + postInitUserFilter: function() { + if(LdapWizard.userFilterObjectClassesHasRun + && LdapWizard.userFilterAvailableGroupsHasRun) { + LdapWizard.composeFilter('user'); + LdapWizard.countUsers(); + } + }, + + /** end of init user filter tab section **/ + + onTabChange: function(event, ui) { + newTabIndex = 0; + if(ui.newTab[0].id === '#ldapWizard2') { + LdapWizard.initUserFilter(); + newTabIndex = 1; + } else if(ui.newTab[0].id === '#ldapWizard3') { + LdapWizard.initLoginFilter(); + newTabIndex = 2; + } else if(ui.newTab[0].id === '#ldapWizard4') { + LdapWizard.initGroupFilter(); + newTabIndex = 3; + } + + curTabIndex = $('#ldapSettings').tabs('option', 'active'); + if(curTabIndex >= 0 && curTabIndex <= 3) { + LdapWizard.controlUpdate(newTabIndex); + } + }, + + processChanges: function(triggerObj) { + LdapWizard.hideInfoBox(); + + if(triggerObj.id == 'ldap_host' + || triggerObj.id == 'ldap_port' + || triggerObj.id == 'ldap_dn' + || triggerObj.id == 'ldap_agent_password') { + LdapWizard.checkPort(); + if($('#ldap_port').val()) { + //if Port is already set, check BaseDN + LdapWizard.checkBaseDN(); + } + } + + if(triggerObj.id == 'ldap_userlist_filter') { + LdapWizard.countUsers(); + } else if(triggerObj.id == 'ldap_group_filter') { + LdapWizard.countGroups(); + LdapWizard.detectGroupMemberAssoc(); + } + + if(triggerObj.id == 'ldap_loginfilter_username' + || triggerObj.id == 'ldap_loginfilter_email') { + LdapWizard.composeFilter('login'); + } + + if($('#ldapSettings').tabs('option', 'active') == 0) { + LdapWizard.basicStatusCheck(); + LdapWizard.functionalityCheck(); + } + }, + + regardFilterMode: function(subject) { + param = 'action=get'+encodeURIComponent(subject)+'FilterMode'+ + '&ldap_serverconfig_chooser='+ + encodeURIComponent($('#ldap_serverconfig_chooser').val()); + + LdapWizard.ajax(param, + function(result) { + property = 'ldap' + subject + 'FilterMode'; + mode = result.changes[property]; + if(mode == LdapWizard.filterModeRaw + && $('#raw'+subject+'FilterContainer').hasClass('invisible')) { + LdapWizard['toggleRaw'+subject+'Filter'](); + } else if(mode == LdapWizard.filterModeAssisted + && !$('#raw'+subject+'FilterContainer').hasClass('invisible')) { + LdapWizard['toggleRaw'+subject+'Filter'](); + } + }, + function (result) { + //on error case get back to default i.e. Assisted + if(!$('#raw'+subject+'FilterContainer').hasClass('invisible')) { + LdapWizard['toggleRaw'+subject+'Filter'](); + } + } + ); + }, + + save: function(inputObj) { + if(LdapWizard.blacklistRemove(inputObj.id)) { + return; + } + if($(inputObj).is('input[type=checkbox]') + && !$(inputObj).is(':checked')) { + val = 0; + } else { + val = $(inputObj).val(); + } + LdapWizard._save(inputObj, val); + }, + + saveMultiSelect: function(originalObj, resultObj) { + values = ''; + for(i = 0; i < resultObj.length; i++) { + values = values + "\n" + resultObj[i].value; + } + LdapWizard._save($('#'+originalObj)[0], $.trim(values)); + if(originalObj == 'ldap_userfilter_objectclass' + || originalObj == 'ldap_userfilter_groups') { + LdapWizard.composeFilter('user'); + //when user filter is changed afterwards, login filter needs to + //be adjusted, too + LdapWizard.composeFilter('login'); + } else if(originalObj == 'ldap_loginfilter_attributes') { + LdapWizard.composeFilter('login'); + } else if(originalObj == 'ldap_groupfilter_objectclass' + || originalObj == 'ldap_groupfilter_groups') { + LdapWizard.composeFilter('group'); + } + }, + + _save: function(object, value) { + param = 'cfgkey='+encodeURIComponent(object.id)+ + '&cfgval='+encodeURIComponent(value)+ + '&action=save'+ + '&ldap_serverconfig_chooser='+$('#ldap_serverconfig_chooser').val(); + + $.post( + OC.filePath('user_ldap','ajax','wizard.php'), + param, + function(result) { + if(result.status == 'success') { + LdapWizard.processChanges(object); + } else { +// alert('Oooooooooooh :('); + } + } + ); + }, + + showInfoBox: function(text) { + $('#ldapWizard1 .ldapWizardInfo').text(t('user_ldap', text)); + $('#ldapWizard1 .ldapWizardInfo').removeClass('invisible'); + LdapWizard.checkInfoShown = true; + }, + + showSpinner: function(id) { + if($(id + ' + .wizSpinner').length == 0) { + $(LdapWizard.spinner).insertAfter($(id)); + $(id + " + img + button").css('display', 'none'); + } + }, + + toggleRawFilter: function(container, moc, mg, stateVar, modeKey) { + //moc = multiselect objectclass + //mg = mutliselect groups + if($(container).hasClass('invisible')) { + $(container).removeClass('invisible'); + $(moc).multiselect('disable'); + if($(mg).multiselect().attr('disabled') == 'disabled') { + LdapWizard[stateVar] = 'disable'; + } else { + LdapWizard[stateVar] = 'enable'; + } + $(mg).multiselect('disable'); + LdapWizard._save({ id: modeKey }, LdapWizard.filterModeRaw); + } else { + $(container).addClass('invisible'); + $(mg).multiselect(LdapWizard[stateVar]); + $(moc).multiselect('enable'); + LdapWizard._save({ id: modeKey }, LdapWizard.filterModeAssisted); + if(moc.indexOf('user') >= 0) { + LdapWizard.blacklistRemove('ldap_userlist_filter'); + LdapWizard.composeFilter('user'); + } else { + LdapWizard.blacklistRemove('ldap_group_filter'); + LdapWizard.composeFilter('group'); + } + } + }, + + toggleRawGroupFilter: function() { + LdapWizard.blacklistRemove('ldap_group_filter'); + LdapWizard.toggleRawFilter('#rawGroupFilterContainer', + '#ldap_groupfilter_objectclass', + '#ldap_groupfilter_groups', + 'groupFilterGroupSelectState', + 'ldapGroupFilterMode' + ); + }, + + toggleRawLoginFilter: function() { + LdapWizard.blacklistRemove('ldap_login_filter'); + container = '#rawLoginFilterContainer'; + if($(container).hasClass('invisible')) { + $(container).removeClass('invisible'); + action = 'disable'; + property = 'disabled'; + mode = LdapWizard.filterModeRaw; + } else { + $(container).addClass('invisible'); + action = 'enable'; + property = false; + mode = LdapWizard.filterModeAssisted; + } + $('#ldap_loginfilter_attributes').multiselect(action); + $('#ldap_loginfilter_email').prop('disabled', property); + $('#ldap_loginfilter_username').prop('disabled', property); + LdapWizard._save({ id: 'ldapLoginFilterMode' }, mode); + if(action == 'enable') { + LdapWizard.composeFilter('login'); + } + }, + + toggleRawUserFilter: function() { + LdapWizard.blacklistRemove('ldap_userlist_filter'); + LdapWizard.toggleRawFilter('#rawUserFilterContainer', + '#ldap_userfilter_objectclass', + '#ldap_userfilter_groups', + 'userFilterGroupSelectState', + 'ldapUserFilterMode' + ); + }, + + updateStatusIndicator: function(isComplete) { + if(isComplete) { + LdapConfiguration.testConfiguration( + //onSuccess + function(result) { + $('.ldap_config_state_indicator').text(t('user_ldap', + 'Configuration OK' + )); + $('.ldap_config_state_indicator').addClass('ldap_grey'); + $('.ldap_config_state_indicator_sign').removeClass('error'); + $('.ldap_config_state_indicator_sign').addClass('success'); + }, + //onError + function(result) { + $('.ldap_config_state_indicator').text(t('user_ldap', + 'Configuration incorrect' + )); + $('.ldap_config_state_indicator').removeClass('ldap_grey'); + $('.ldap_config_state_indicator_sign').addClass('error'); + $('.ldap_config_state_indicator_sign').removeClass('success'); + } + ); + } else { + $('.ldap_config_state_indicator').text(t('user_ldap', + 'Configuration incomplete' + )); + $('.ldap_config_state_indicator').removeClass('ldap_grey'); + $('.ldap_config_state_indicator_sign').removeClass('error'); + $('.ldap_config_state_indicator_sign').removeClass('success'); + } + } +}; + $(document).ready(function() { $('#ldapAdvancedAccordion').accordion({ heightStyle: 'content', animate: 'easeInOutCirc'}); - $('#ldapSettings').tabs(); - $('#ldap_submit').button(); - $('#ldap_action_test_connection').button(); + $('#ldapSettings').tabs({ beforeActivate: LdapWizard.onTabChange }); + $('.ldap_submit').button(); + $('.ldap_action_test_connection').button(); $('#ldap_action_delete_configuration').button(); + LdapWizard.initMultiSelect($('#ldap_userfilter_groups'), + 'ldap_userfilter_groups', + t('user_ldap', 'Select groups')); + LdapWizard.initMultiSelect($('#ldap_userfilter_objectclass'), + 'ldap_userfilter_objectclass', + t('user_ldap', 'Select object classes')); + LdapWizard.initMultiSelect($('#ldap_loginfilter_attributes'), + 'ldap_loginfilter_attributes', + t('user_ldap', 'Select attributes')); + LdapWizard.initMultiSelect($('#ldap_groupfilter_groups'), + 'ldap_groupfilter_groups', + t('user_ldap', 'Select groups')); + LdapWizard.initMultiSelect($('#ldap_groupfilter_objectclass'), + 'ldap_groupfilter_objectclass', + t('user_ldap', 'Select object classes')); + $('.lwautosave').change(function() { LdapWizard.save(this); }); + $('#toggleRawUserFilter').click(LdapWizard.toggleRawUserFilter); + $('#toggleRawGroupFilter').click(LdapWizard.toggleRawGroupFilter); + $('#toggleRawLoginFilter').click(LdapWizard.toggleRawLoginFilter); LdapConfiguration.refreshConfig(); - $('#ldap_action_test_connection').click(function(event){ + $('.ldap_action_continue').click(function(event) { event.preventDefault(); - $.post( - OC.filePath('user_ldap','ajax','testConfiguration.php'), - $('#ldap').serialize(), - function (result) { - if (result.status === 'success') { - OC.dialogs.alert( - result.message, - t('user_ldap', 'Connection test succeeded') - ); - } else { - OC.dialogs.alert( - result.message, - t('user_ldap', 'Connection test failed') - ); - } + LdapWizard.controlContinue(); + }); + $('.ldap_action_back').click(function(event) { + event.preventDefault(); + LdapWizard.controlBack(); + }); + $('.ldap_action_test_connection').click(function(event){ + event.preventDefault(); + LdapConfiguration.testConfiguration( + //onSuccess + function(result) { + OC.dialogs.alert( + result.message, + t('user_ldap', 'Connection test succeeded') + ); + }, + //onError + function(result) { + OC.dialogs.alert( + result.message, + t('user_ldap', 'Connection test failed') + ); } ); }); @@ -163,18 +928,18 @@ $(document).ready(function() { ); }); - $('#ldap_submit').click(function(event) { + $('.ldap_submit').click(function(event) { event.preventDefault(); $.post( OC.filePath('user_ldap','ajax','setConfiguration.php'), $('#ldap').serialize(), function (result) { - bgcolor = $('#ldap_submit').css('background'); + bgcolor = $('.ldap_submit').css('background'); if (result.status === 'success') { //the dealing with colors is a but ugly, but the jQuery version in use has issues with rgba colors - $('#ldap_submit').css('background', '#fff'); - $('#ldap_submit').effect('highlight', {'color':'#A8FA87'}, 5000, function() { - $('#ldap_submit').css('background', bgcolor); + $('.ldap_submit').css('background', '#fff'); + $('.ldap_submit').effect('highlight', {'color':'#A8FA87'}, 5000, function() { + $('.ldap_submit').css('background', bgcolor); }); //update the Label in the config chooser caption = $('#ldap_serverconfig_chooser option:selected:first').text(); @@ -184,9 +949,9 @@ $(document).ready(function() { $('#ldap_serverconfig_chooser option:selected:first').text(caption); } else { - $('#ldap_submit').css('background', '#fff'); - $('#ldap_submit').effect('highlight', {'color':'#E97'}, 5000, function() { - $('#ldap_submit').css('background', bgcolor); + $('.ldap_submit').css('background', '#fff'); + $('.ldap_submit').effect('highlight', {'color':'#E97'}, 5000, function() { + $('.ldap_submit').css('background', bgcolor); }); } } diff --git a/apps/user_ldap/l10n/ach.php b/apps/user_ldap/l10n/ach.php new file mode 100644 index 00000000000..2371ee70593 --- /dev/null +++ b/apps/user_ldap/l10n/ach.php @@ -0,0 +1,6 @@ +<?php +$TRANSLATIONS = array( +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("","") +); +$PLURAL_FORMS = "nplurals=2; plural=(n > 1);"; diff --git a/apps/user_ldap/l10n/ady.php b/apps/user_ldap/l10n/ady.php new file mode 100644 index 00000000000..3a1e002311c --- /dev/null +++ b/apps/user_ldap/l10n/ady.php @@ -0,0 +1,6 @@ +<?php +$TRANSLATIONS = array( +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("","") +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/af.php b/apps/user_ldap/l10n/af.php new file mode 100644 index 00000000000..3a1e002311c --- /dev/null +++ b/apps/user_ldap/l10n/af.php @@ -0,0 +1,6 @@ +<?php +$TRANSLATIONS = array( +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("","") +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/af_ZA.php b/apps/user_ldap/l10n/af_ZA.php index 32feab61b49..130e471e0e4 100644 --- a/apps/user_ldap/l10n/af_ZA.php +++ b/apps/user_ldap/l10n/af_ZA.php @@ -1,6 +1,8 @@ <?php $TRANSLATIONS = array( -"Password" => "Wagwoord", -"Help" => "Hulp" +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("",""), +"Help" => "Hulp", +"Password" => "Wagwoord" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/ak.php b/apps/user_ldap/l10n/ak.php new file mode 100644 index 00000000000..dd5f66761d6 --- /dev/null +++ b/apps/user_ldap/l10n/ak.php @@ -0,0 +1,6 @@ +<?php +$TRANSLATIONS = array( +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("","") +); +$PLURAL_FORMS = "nplurals=2; plural=n > 1;"; diff --git a/apps/user_ldap/l10n/ar.php b/apps/user_ldap/l10n/ar.php index 3dd88eb2655..2b0cbbd75a5 100644 --- a/apps/user_ldap/l10n/ar.php +++ b/apps/user_ldap/l10n/ar.php @@ -2,7 +2,13 @@ $TRANSLATIONS = array( "Deletion failed" => "فشل الحذف", "Error" => "خطأ", +"Select groups" => "إختر مجموعة", +"_%s group found_::_%s groups found_" => array("","","","","",""), +"_%s user found_::_%s users found_" => array("","","","","",""), +"Save" => "حفظ", +"Help" => "المساعدة", +"Host" => "المضيف", "Password" => "كلمة المرور", -"Help" => "المساعدة" +"Back" => "رجوع" ); $PLURAL_FORMS = "nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;"; diff --git a/apps/user_ldap/l10n/az.php b/apps/user_ldap/l10n/az.php new file mode 100644 index 00000000000..bba52d53a1a --- /dev/null +++ b/apps/user_ldap/l10n/az.php @@ -0,0 +1,6 @@ +<?php +$TRANSLATIONS = array( +"_%s group found_::_%s groups found_" => array(""), +"_%s user found_::_%s users found_" => array("") +); +$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/user_ldap/l10n/be.php b/apps/user_ldap/l10n/be.php new file mode 100644 index 00000000000..089b92efe7b --- /dev/null +++ b/apps/user_ldap/l10n/be.php @@ -0,0 +1,7 @@ +<?php +$TRANSLATIONS = array( +"Error" => "Памылка", +"_%s group found_::_%s groups found_" => array("","","",""), +"_%s user found_::_%s users found_" => array("","","","") +); +$PLURAL_FORMS = "nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"; diff --git a/apps/user_ldap/l10n/bg_BG.php b/apps/user_ldap/l10n/bg_BG.php index b750884e9de..588f6d448b4 100644 --- a/apps/user_ldap/l10n/bg_BG.php +++ b/apps/user_ldap/l10n/bg_BG.php @@ -1,7 +1,10 @@ <?php $TRANSLATIONS = array( "Error" => "Грешка", -"Password" => "Парола", -"Help" => "Помощ" +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("",""), +"Save" => "Запис", +"Help" => "Помощ", +"Password" => "Парола" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/bn_BD.php b/apps/user_ldap/l10n/bn_BD.php index 407d5f509ec..0b43a27df94 100644 --- a/apps/user_ldap/l10n/bn_BD.php +++ b/apps/user_ldap/l10n/bn_BD.php @@ -1,19 +1,18 @@ <?php $TRANSLATIONS = array( "Error" => "সমস্যা", +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("",""), +"Save" => "সংরক্ষণ", +"Help" => "সহায়িকা", "Host" => "হোস্ট", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "SSL আবশ্যক না হলে আপনি এই প্রটোকলটি মুছে ফেলতে পারেন । এরপর শুরু করুন এটা দিয়ে ldaps://", -"Base DN" => "ভিত্তি DN", -"You can specify Base DN for users and groups in the Advanced tab" => "সুচারু ট্যঅবে গিয়ে আপনি ব্যবহারকারি এবং গোষ্ঠীসমূহের জন্য ভিত্তি DN নির্ধারণ করতে পারেন।", +"Port" => "পোর্ট", "User DN" => "ব্যবহারকারি DN", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. পরিচয় গোপন রেখে অধিগমনের জন্য DN এবং কূটশব্দটি ফাঁকা রাখুন।", "Password" => "কূটশব্দ", "For anonymous access, leave DN and Password empty." => "অজ্ঞাতকুলশীল অধিগমনের জন্য DN এবং কূটশব্দটি ফাঁকা রাখুন।", -"User Login Filter" => "ব্যবহারকারির প্রবেশ ছাঁকনী", -"User List Filter" => "ব্যবহারকারী তালিকা ছাঁকনী", -"Group Filter" => "গোষ্ঠী ছাঁকনী", -"Port" => "পোর্ট", -"Use TLS" => "TLS ব্যবহার কর", +"You can specify Base DN for users and groups in the Advanced tab" => "সুচারু ট্যঅবে গিয়ে আপনি ব্যবহারকারি এবং গোষ্ঠীসমূহের জন্য ভিত্তি DN নির্ধারণ করতে পারেন।", "Case insensitve LDAP server (Windows)" => "বর্ণ অসংবেদী LDAP সার্ভার (উইন্ডোজ)", "Turn off SSL certificate validation." => "SSL সনদপত্র যাচাইকরণ বন্ধ রাক।", "in seconds. A change empties the cache." => "সেকেন্ডে। কোন পরিবর্তন ক্যাসে খালি করবে।", @@ -23,7 +22,6 @@ $TRANSLATIONS = array( "Base Group Tree" => "ভিত্তি গোষ্ঠী বৃক্ষাকারে", "Group-Member association" => "গোষ্ঠী-সদস্য সংস্থাপন", "in bytes" => "বাইটে", -"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "ব্যবহারকারী নামের জন্য ফাঁকা রাখুন (পূর্বনির্ধারিত)। অন্যথায়, LDAP/AD বৈশিষ্ট্য নির্ধারণ করুন।", -"Help" => "সহায়িকা" +"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "ব্যবহারকারী নামের জন্য ফাঁকা রাখুন (পূর্বনির্ধারিত)। অন্যথায়, LDAP/AD বৈশিষ্ট্য নির্ধারণ করুন।" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/bs.php b/apps/user_ldap/l10n/bs.php new file mode 100644 index 00000000000..7a64be44e0d --- /dev/null +++ b/apps/user_ldap/l10n/bs.php @@ -0,0 +1,7 @@ +<?php +$TRANSLATIONS = array( +"_%s group found_::_%s groups found_" => array("","",""), +"_%s user found_::_%s users found_" => array("","",""), +"Save" => "Spasi" +); +$PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"; diff --git a/apps/user_ldap/l10n/ca.php b/apps/user_ldap/l10n/ca.php index 455ad62d84c..2ebaa7d7a5a 100644 --- a/apps/user_ldap/l10n/ca.php +++ b/apps/user_ldap/l10n/ca.php @@ -4,7 +4,11 @@ $TRANSLATIONS = array( "Failed to delete the server configuration" => "Ha fallat en eliminar la configuració del servidor", "The configuration is valid and the connection could be established!" => "La configuració és vàlida i s'ha pogut establir la comunicació!", "The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "La configuració és vàlida, però ha fallat el Bind. Comproveu les credencials i l'arranjament del servidor.", -"The configuration is invalid. Please look in the ownCloud log for further details." => "La configuració no és vàlida. Per més detalls mireu al registre d'ownCloud.", +"The configuration is invalid. Please have a look at the logs for further details." => "La configuració no és vàlida. Per més detalls mireu al registre del sistema.", +"No action specified" => "No heu especificat cap acció", +"No configuration specified" => "No heu especificat cap configuració", +"No data specified" => "No heu especificat cap dada", +" Could not set configuration %s" => "No s'ha pogut establir la configuració %s", "Deletion failed" => "Eliminació fallida", "Take over settings from recent server configuration?" => "Voleu prendre l'arranjament de la configuració actual del servidor?", "Keep settings?" => "Voleu mantenir la configuració?", @@ -12,40 +16,60 @@ $TRANSLATIONS = array( "mappings cleared" => "s'han eliminat els mapatges", "Success" => "Èxit", "Error" => "Error", +"Configuration OK" => "Configuració correcte", +"Configuration incorrect" => "Configuració incorrecte", +"Configuration incomplete" => "Configuració incompleta", +"Select groups" => "Selecciona els grups", +"Select object classes" => "Seleccioneu les classes dels objectes", +"Select attributes" => "Seleccioneu els atributs", "Connection test succeeded" => "La prova de connexió ha reeixit", "Connection test failed" => "La prova de connexió ha fallat", "Do you really want to delete the current Server Configuration?" => "Voleu eliminar la configuració actual del servidor?", "Confirm Deletion" => "Confirma l'eliminació", -"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Avís:</b> Les aplicacions user_ldap i user_webdavauth són incompatibles. Podeu experimentar comportaments inesperats. Demaneu a l'administrador del sistema que en desactivi una.", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Avís:</b> El mòdul PHP LDAP no està instal·lat, el dorsal no funcionarà. Demaneu a l'administrador del sistema que l'instal·li.", -"Server configuration" => "Configuració del servidor", +"_%s group found_::_%s groups found_" => array("S'ha trobat %s grup","S'han trobat %s grups"), +"_%s user found_::_%s users found_" => array("S'ha trobat %s usuari","S'han trobat %s usuaris"), +"Invalid Host" => "Ordinador central no vàlid", +"Could not find the desired feature" => "La característica desitjada no s'ha trobat", +"Save" => "Desa", +"Test Configuration" => "Comprovació de la configuració", +"Help" => "Ajuda", +"Limit the access to %s to groups meeting this criteria:" => "Limita l'accés a %s grups que compleixin amb el criteri:", +"only those object classes:" => "només aquestes classes d'objecte:", +"only from those groups:" => "només d'aquests grups", +"Edit raw filter instead" => "Edita filtre raw", +"Raw LDAP filter" => "Filtre raw LDAP", +"The filter specifies which LDAP groups shall have access to the %s instance." => "El filtre especifica quins grups LDAP haurien de tenir accés a la instància %s.", +"groups found" => "grups trobats", +"What attribute shall be used as login name:" => "Quin atribut s'hauria d'utilitzar com a nom per a l'acreditació:", +"LDAP Username:" => "Nom d'usuari LDAP:", +"LDAP Email Address:" => "Adreça de correu electrònic LDAP:", +"Other Attributes:" => "Altres atributs:", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Defineix el filtre a aplicar quan s'intenta iniciar la sessió. %%uid reemplaça el nom d'usuari en l'acció d'inici de sessió. Per exemple: \"uid=%%uid\"", "Add Server Configuration" => "Afegeix la configuració del servidor", "Host" => "Equip remot", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Podeu ometre el protocol, excepte si requeriu SSL. Llavors comenceu amb ldaps://", -"Base DN" => "DN Base", -"One Base DN per line" => "Una DN Base per línia", -"You can specify Base DN for users and groups in the Advanced tab" => "Podeu especificar DN Base per usuaris i grups a la pestanya Avançat", +"Port" => "Port", "User DN" => "DN Usuari", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "La DN de l'usuari client amb la que s'haurà de fer, per exemple uid=agent,dc=exemple,dc=com. Per un accés anònim, deixeu la DN i la contrasenya en blanc.", "Password" => "Contrasenya", "For anonymous access, leave DN and Password empty." => "Per un accés anònim, deixeu la DN i la contrasenya en blanc.", -"User Login Filter" => "Filtre d'inici de sessió d'usuari", -"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Defineix el filtre a aplicar quan s'intenta iniciar la sessió. %%uid reemplaça el nom d'usuari en l'acció d'inici de sessió. Per exemple: \"uid=%%uid\"", -"User List Filter" => "Llista de filtres d'usuari", -"Defines the filter to apply, when retrieving users (no placeholders). Example: \"objectClass=person\"" => "Defineix el filtre a aplicar quan es mostren usuaris (no textos variables). Per exemple: \"objectClass=person\"", -"Group Filter" => "Filtre de grup", -"Defines the filter to apply, when retrieving groups (no placeholders). Example: \"objectClass=posixGroup\"" => "Defineix el filtre a aplicar quan es mostren grups (no textos variables). Per exemple: \"objectClass=posixGroup\"", +"One Base DN per line" => "Una DN Base per línia", +"You can specify Base DN for users and groups in the Advanced tab" => "Podeu especificar DN Base per usuaris i grups a la pestanya Avançat", +"Limit the access to %s to users meeting this criteria:" => "Limita l'accés a %s usuaris que compleixin amb el criteri:", +"The filter specifies which LDAP users shall have access to the %s instance." => "El filtre especifica quins usuaris LDAP haurien de tenir accés a la instància %s", +"users found" => "usuaris trobats", +"Back" => "Enrera", +"Continue" => "Continua", +"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Avís:</b> Les aplicacions user_ldap i user_webdavauth són incompatibles. Podeu experimentar comportaments inesperats. Demaneu a l'administrador del sistema que en desactivi una.", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Avís:</b> El mòdul PHP LDAP no està instal·lat, el dorsal no funcionarà. Demaneu a l'administrador del sistema que l'instal·li.", "Connection Settings" => "Arranjaments de connexió", "Configuration Active" => "Configuració activa", "When unchecked, this configuration will be skipped." => "Si està desmarcat, aquesta configuració s'ometrà.", -"Port" => "Port", "Backup (Replica) Host" => "Màquina de còpia de serguretat (rèplica)", "Give an optional backup host. It must be a replica of the main LDAP/AD server." => "Afegiu una màquina de còpia de seguretat opcional. Ha de ser una rèplica del servidor LDAP/AD principal.", "Backup (Replica) Port" => "Port de la còpia de seguretat (rèplica)", "Disable Main Server" => "Desactiva el servidor principal", "Only connect to the replica server." => "Connecta només al servidor rèplica.", -"Use TLS" => "Usa TLS", -"Do not use it additionally for LDAPS connections, it will fail." => "No ho useu adicionalment per a conexions LDAPS, fallarà.", "Case insensitve LDAP server (Windows)" => "Servidor LDAP sense distinció entre majúscules i minúscules (Windows)", "Turn off SSL certificate validation." => "Desactiva la validació de certificat SSL.", "Not recommended, use it for testing only! If connection only works with this option, import the LDAP server's SSL certificate in your %s server." => "No es recomana, useu-ho només com a prova! Importeu el certificat SSL del servidor LDAP al servidor %s només si la connexió funciona amb aquesta opció.", @@ -76,12 +100,11 @@ $TRANSLATIONS = array( "Internal Username Attribute:" => "Atribut nom d'usuari intern:", "Override UUID detection" => "Sobrescriu la detecció UUID", "By default, the UUID attribute is automatically detected. The UUID attribute is used to doubtlessly identify LDAP users and groups. Also, the internal username will be created based on the UUID, if not specified otherwise above. You can override the setting and pass an attribute of your choice. You must make sure that the attribute of your choice can be fetched for both users and groups and it is unique. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users and groups." => "Per defecte, owncloud autodetecta l'atribut UUID. L'atribut UUID s'utilitza per identificar usuaris i grups de forma indubtable. També el nom d'usuari intern es crearà en base a la UUIS, si no heu especificat res diferent a dalt. Podeu sobreescriure l'arranjament i passar l'atribut que desitgeu. Heu d'assegurar-vos que l'atribut que escolliu pot ser recollit tant pels usuaris com pels grups i que és únic. Deixeu-ho en blanc si preferiu el comportament per defecte. els canvis s'aplicaran als usuaris i grups LDAP mapats de nou (afegits).", -"UUID Attribute:" => "Atribut UUID:", +"UUID Attribute for Users:" => "Atribut UUID per Usuaris:", +"UUID Attribute for Groups:" => "Atribut UUID per Grups:", "Username-LDAP User Mapping" => "Mapatge d'usuari Nom d'usuari-LDAP", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have a internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." => "Els noms d'usuari s'usen per desar i assignar (meta)dades. Per tal d'identificar amb precisió i reconèixer els usuaris, cada usuari LDAP tindrà un nom d'usuari intern. Això requereix mapatge del nom d'usuari a l'usuari LDAP. El nom d'usuari creat es mapa a la UUID de l'usuari LDAP. A més, la DN es posa a la memòria de cau per reduir la interacció LDAP, però no s'usa per identificació. En cas que la DN canvïi, els canvis es trobaran. El nom d'usuari intern s'usa a tot arreu. Si esborreu els mapatges quedaran sobrants a tot arreu. Esborrar els mapatges no és sensible a la configuració, afecta a totes les configuracions LDAP! No esborreu mai els mapatges en un entorn de producció, només en un estadi de prova o experimental.", "Clear Username-LDAP User Mapping" => "Elimina el mapatge d'usuari Nom d'usuari-LDAP", -"Clear Groupname-LDAP Group Mapping" => "Elimina el mapatge de grup Nom de grup-LDAP", -"Test Configuration" => "Comprovació de la configuració", -"Help" => "Ajuda" +"Clear Groupname-LDAP Group Mapping" => "Elimina el mapatge de grup Nom de grup-LDAP" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/cs_CZ.php b/apps/user_ldap/l10n/cs_CZ.php index 9109a8c710a..6bcf364ab33 100644 --- a/apps/user_ldap/l10n/cs_CZ.php +++ b/apps/user_ldap/l10n/cs_CZ.php @@ -4,7 +4,11 @@ $TRANSLATIONS = array( "Failed to delete the server configuration" => "Selhalo smazání nastavení serveru", "The configuration is valid and the connection could be established!" => "Nastavení je v pořádku a spojení bylo navázáno.", "The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "Konfigurace je v pořádku, ale spojení selhalo. Zkontrolujte, prosím, nastavení serveru a přihlašovací údaje.", -"The configuration is invalid. Please look in the ownCloud log for further details." => "Nastavení je neplatné. Zkontrolujte, prosím, záznamy ownCloud pro další podrobnosti.", +"The configuration is invalid. Please have a look at the logs for further details." => "Konfigurace je neplatná. Pro bližší informace se podívejte do logu.", +"No action specified" => "Neurčena žádná akce", +"No configuration specified" => "Neurčena žádná konfigurace", +"No data specified" => "Neurčena žádná data", +" Could not set configuration %s" => "Nelze nastavit konfiguraci %s", "Deletion failed" => "Mazání selhalo", "Take over settings from recent server configuration?" => "Převzít nastavení z nedávné konfigurace serveru?", "Keep settings?" => "Ponechat nastavení?", @@ -12,40 +16,60 @@ $TRANSLATIONS = array( "mappings cleared" => "mapování zrušeno", "Success" => "Úspěch", "Error" => "Chyba", +"Configuration OK" => "Konfigurace v pořádku", +"Configuration incorrect" => "Nesprávná konfigurace", +"Configuration incomplete" => "Nekompletní konfigurace", +"Select groups" => "Vyberte skupiny", +"Select object classes" => "Vyberte objektové třídy", +"Select attributes" => "Vyberte atributy", "Connection test succeeded" => "Test spojení byl úspěšný", "Connection test failed" => "Test spojení selhal", "Do you really want to delete the current Server Configuration?" => "Opravdu si přejete smazat současné nastavení serveru?", "Confirm Deletion" => "Potvrdit smazání", -"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Varování:</b> Aplikace user_ldap a user_webdavauth jsou vzájemně nekompatibilní. Můžete zaznamenat neočekávané chování. Požádejte prosím vašeho systémového administrátora o zakázání jednoho z nich.", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Varování:</b> není nainstalován LDAP modul pro PHP, podpůrná vrstva nebude fungovat. Požádejte, prosím, správce systému, aby jej nainstaloval.", -"Server configuration" => "Nastavení serveru", +"_%s group found_::_%s groups found_" => array("nalezena %s skupina","nalezeny %s skupiny","nalezeno %s skupin"), +"_%s user found_::_%s users found_" => array("nalezen %s uživatel","nalezeni %s uživatelé","nalezeno %s uživatelů"), +"Invalid Host" => "Neplatný hostitel", +"Could not find the desired feature" => "Nelze nalézt požadovanou vlastnost", +"Save" => "Uložit", +"Test Configuration" => "Vyzkoušet nastavení", +"Help" => "Nápověda", +"Limit the access to %s to groups meeting this criteria:" => "Omezit přístup k %s skupinám uživatelů splňujícím tyto podmínky:", +"only those object classes:" => "pouze tyto objektové třídy:", +"only from those groups:" => "pouze z těchto skupin:", +"Edit raw filter instead" => "Edituj filtr přímo", +"Raw LDAP filter" => "Původní filtr LDAP", +"The filter specifies which LDAP groups shall have access to the %s instance." => "Filtr určuje, kteří uživatelé LDAP mají mít přístup k instanci %s.", +"groups found" => "nalezené skupiny", +"What attribute shall be used as login name:" => "Který atribut má být použit jako přihlašovací jméno:", +"LDAP Username:" => "LDAP uživatelské jméno:", +"LDAP Email Address:" => "LDAP e-mailová adresa:", +"Other Attributes:" => "Další atributy:", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Určuje použitý filtr při pokusu o přihlášení. %%uid nahrazuje uživatelské jméno v činnosti přihlášení. Příklad: \"uid=%%uid\"", "Add Server Configuration" => "Přidat nastavení serveru", "Host" => "Počítač", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Můžete vynechat protokol, vyjma pokud požadujete SSL. Tehdy začněte s ldaps://", -"Base DN" => "Základní DN", -"One Base DN per line" => "Jedna základní DN na řádku", -"You can specify Base DN for users and groups in the Advanced tab" => "V rozšířeném nastavení můžete určit základní DN pro uživatele a skupiny", +"Port" => "Port", "User DN" => "Uživatelské DN", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "DN klientského uživatele, ke kterému tvoříte vazbu, např. uid=agent,dc=example,dc=com. Pro anonymní přístup ponechte DN a heslo prázdné.", "Password" => "Heslo", "For anonymous access, leave DN and Password empty." => "Pro anonymní přístup ponechte údaje DN and heslo prázdné.", -"User Login Filter" => "Filtr přihlášení uživatelů", -"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Určuje použitý filtr při pokusu o přihlášení. %%uid nahrazuje uživatelské jméno v činnosti přihlášení. Příklad: \"uid=%%uid\"", -"User List Filter" => "Filtr seznamu uživatelů", -"Defines the filter to apply, when retrieving users (no placeholders). Example: \"objectClass=person\"" => "Určuje použitý filtr při získávání uživatelů (bez zástupných znaků). Příklad: \"objectClass=person\"", -"Group Filter" => "Filtr skupin", -"Defines the filter to apply, when retrieving groups (no placeholders). Example: \"objectClass=posixGroup\"" => "Určuje použitý filtr při získávání skupin (bez zástupných znaků). Příklad: \"objectClass=posixGroup\"", +"One Base DN per line" => "Jedna základní DN na řádku", +"You can specify Base DN for users and groups in the Advanced tab" => "V rozšířeném nastavení můžete určit základní DN pro uživatele a skupiny", +"Limit the access to %s to users meeting this criteria:" => "Omezit přístup k %s uživatelům splňujícím tyto podmínky:", +"The filter specifies which LDAP users shall have access to the %s instance." => "Filtr určuje, kteří uživatelé LDAP mají mít přístup k instanci %s.", +"users found" => "nalezení uživatelé", +"Back" => "Zpět", +"Continue" => "Pokračovat", +"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Varování:</b> Aplikace user_ldap a user_webdavauth jsou vzájemně nekompatibilní. Můžete zaznamenat neočekávané chování. Požádejte prosím vašeho systémového administrátora o zakázání jednoho z nich.", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Varování:</b> není nainstalován LDAP modul pro PHP, podpůrná vrstva nebude fungovat. Požádejte, prosím, správce systému, aby jej nainstaloval.", "Connection Settings" => "Nastavení spojení", "Configuration Active" => "Nastavení aktivní", "When unchecked, this configuration will be skipped." => "Pokud není zaškrtnuto, bude toto nastavení přeskočeno.", -"Port" => "Port", "Backup (Replica) Host" => "Záložní (kopie) hostitel", "Give an optional backup host. It must be a replica of the main LDAP/AD server." => "Zadejte volitelného záložního hostitele. Musí to být kopie hlavního serveru LDAP/AD.", "Backup (Replica) Port" => "Záložní (kopie) port", "Disable Main Server" => "Zakázat hlavní server", "Only connect to the replica server." => "Připojit jen k záložnímu serveru.", -"Use TLS" => "Použít TLS", -"Do not use it additionally for LDAPS connections, it will fail." => "Nepoužívejte v kombinaci s LDAPS spojením, nebude to fungovat.", "Case insensitve LDAP server (Windows)" => "LDAP server nerozlišující velikost znaků (Windows)", "Turn off SSL certificate validation." => "Vypnout ověřování SSL certifikátu.", "Not recommended, use it for testing only! If connection only works with this option, import the LDAP server's SSL certificate in your %s server." => "Nedoporučuje se, určeno pouze k testovacímu použití. Pokud spojení funguje jen s touto volbou, importujte SSL certifikát vašeho LDAP serveru na server %s.", @@ -76,12 +100,11 @@ $TRANSLATIONS = array( "Internal Username Attribute:" => "Atribut interního uživatelského jména:", "Override UUID detection" => "Nastavit ručně UUID atribut", "By default, the UUID attribute is automatically detected. The UUID attribute is used to doubtlessly identify LDAP users and groups. Also, the internal username will be created based on the UUID, if not specified otherwise above. You can override the setting and pass an attribute of your choice. You must make sure that the attribute of your choice can be fetched for both users and groups and it is unique. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users and groups." => "Ve výchozím nastavení je UUID atribut nalezen automaticky. UUID atribut je používán pro nezpochybnitelnou identifikaci uživatelů a skupin z LDAP. Navíc je na základě UUID tvořeno také interní uživatelské jméno, pokud není nastaveno jinak. Můžete výchozí nastavení přepsat a použít atribut, který sami zvolíte. Musíte se ale ujistit, že atribut, který vyberete, bude uveden jak u uživatelů, tak i u skupin a je unikátní. Ponechte prázdné pro výchozí chování. Změna bude mít vliv jen na nově namapované (přidané) uživatele a skupiny z LDAP.", -"UUID Attribute:" => "Atribut UUID:", +"UUID Attribute for Users:" => "UUID atribut pro uživatele:", +"UUID Attribute for Groups:" => "UUID atribut pro skupiny:", "Username-LDAP User Mapping" => "Mapování uživatelských jmen z LDAPu", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have a internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." => "Uživatelská jména jsou používány pro uchovávání a přiřazování (meta)dat. Pro správnou identifikaci a rozpoznání uživatelů bude mít každý uživatel z LDAP interní uživatelské jméno. To vyžaduje mapování uživatelských jmen na uživatele LDAP. Vytvořené uživatelské jméno je mapováno na UUID uživatele v LDAP. Navíc je cachována DN pro zmenšení interakce s LDAP, ale není používána pro identifikaci. Pokud se DN změní, bude to správně rozpoznáno. Interní uživatelské jméno se používá celé. Vyčištění mapování zanechá zbytky všude. Vyčištění navíc není specifické konfiguraci, bude mít vliv na všechny LDAP konfigurace! Nikdy nečistěte mapování v produkčním prostředí, jen v testovací nebo experimentální fázi.", "Clear Username-LDAP User Mapping" => "Zrušit mapování uživatelských jmen LDAPu", -"Clear Groupname-LDAP Group Mapping" => "Zrušit mapování názvů skupin LDAPu", -"Test Configuration" => "Vyzkoušet nastavení", -"Help" => "Nápověda" +"Clear Groupname-LDAP Group Mapping" => "Zrušit mapování názvů skupin LDAPu" ); $PLURAL_FORMS = "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"; diff --git a/apps/user_ldap/l10n/cy_GB.php b/apps/user_ldap/l10n/cy_GB.php index 71a38fad25d..65a78432c75 100644 --- a/apps/user_ldap/l10n/cy_GB.php +++ b/apps/user_ldap/l10n/cy_GB.php @@ -2,7 +2,10 @@ $TRANSLATIONS = array( "Deletion failed" => "Methwyd dileu", "Error" => "Gwall", -"Password" => "Cyfrinair", -"Help" => "Cymorth" +"_%s group found_::_%s groups found_" => array("","","",""), +"_%s user found_::_%s users found_" => array("","","",""), +"Save" => "Cadw", +"Help" => "Cymorth", +"Password" => "Cyfrinair" ); $PLURAL_FORMS = "nplurals=4; plural=(n==1) ? 0 : (n==2) ? 1 : (n != 8 && n != 11) ? 2 : 3;"; diff --git a/apps/user_ldap/l10n/da.php b/apps/user_ldap/l10n/da.php index e33efe3de09..e375598c9bd 100644 --- a/apps/user_ldap/l10n/da.php +++ b/apps/user_ldap/l10n/da.php @@ -2,39 +2,39 @@ $TRANSLATIONS = array( "Failed to delete the server configuration" => "Kunne ikke slette server konfigurationen", "The configuration is valid and the connection could be established!" => "Konfigurationen er korrekt og forbindelsen kunne etableres!", -"The configuration is invalid. Please look in the ownCloud log for further details." => "Konfigurationen er ugyldig. Se venligst ownCloud loggen for yderligere detaljer.", "Deletion failed" => "Fejl ved sletning", "Take over settings from recent server configuration?" => "Overtag indstillinger fra nylig server konfiguration? ", "Keep settings?" => "Behold indstillinger?", "Cannot add server configuration" => "Kan ikke tilføje serverkonfiguration", "Success" => "Succes", "Error" => "Fejl", +"Select groups" => "Vælg grupper", "Connection test succeeded" => "Forbindelsestest lykkedes", "Connection test failed" => "Forbindelsestest mislykkedes", "Do you really want to delete the current Server Configuration?" => "Ønsker du virkelig at slette den nuværende Server Konfiguration?", "Confirm Deletion" => "Bekræft Sletning", -"Server configuration" => "Server konfiguration", +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("",""), +"Save" => "Gem", +"Test Configuration" => "Test Konfiguration", +"Help" => "Hjælp", "Add Server Configuration" => "Tilføj Server Konfiguration", "Host" => "Host", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Du kan udelade protokollen, medmindre du skal bruge SSL. Start i så fald med ldaps://", -"Base DN" => "Base DN", -"You can specify Base DN for users and groups in the Advanced tab" => "You can specify Base DN for users and groups in the Advanced tab", +"Port" => "Port", "User DN" => "Bruger DN", "Password" => "Kodeord", "For anonymous access, leave DN and Password empty." => "For anonym adgang, skal du lade DN og Adgangskode tomme.", -"User Login Filter" => "Bruger Login Filter", -"User List Filter" => "Brugerliste Filter", -"Group Filter" => "Gruppe Filter", +"You can specify Base DN for users and groups in the Advanced tab" => "You can specify Base DN for users and groups in the Advanced tab", +"Back" => "Tilbage", +"Continue" => "Videre", "Connection Settings" => "Forbindelsesindstillinger ", "Configuration Active" => "Konfiguration Aktiv", -"Port" => "Port", "Backup (Replica) Host" => "Backup (Replika) Vært", "Give an optional backup host. It must be a replica of the main LDAP/AD server." => "Opgiv en ikke obligatorisk backup server. Denne skal være en replikation af hoved-LDAP/AD serveren.", "Backup (Replica) Port" => "Backup (Replika) Port", "Disable Main Server" => "Deaktiver Hovedserver", "Only connect to the replica server." => "Forbind kun til replika serveren.", -"Use TLS" => "Brug TLS", -"Do not use it additionally for LDAPS connections, it will fail." => "Benyt ikke flere LDAPS forbindelser, det vil mislykkeds. ", "Case insensitve LDAP server (Windows)" => "Ikke versalfølsom LDAP server (Windows)", "Turn off SSL certificate validation." => "Deaktiver SSL certifikat validering", "Cache Time-To-Live" => "Cache Time-To-Live", @@ -45,8 +45,6 @@ $TRANSLATIONS = array( "Quota Field" => "Kvote Felt", "in bytes" => "i bytes", "Email Field" => "Email Felt", -"Internal Username" => "Internt Brugernavn", -"Test Configuration" => "Test Konfiguration", -"Help" => "Hjælp" +"Internal Username" => "Internt Brugernavn" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/de.php b/apps/user_ldap/l10n/de.php index cb13275fafa..0c80ecfa850 100644 --- a/apps/user_ldap/l10n/de.php +++ b/apps/user_ldap/l10n/de.php @@ -4,7 +4,11 @@ $TRANSLATIONS = array( "Failed to delete the server configuration" => "Löschen der Serverkonfiguration fehlgeschlagen", "The configuration is valid and the connection could be established!" => "Die Konfiguration ist gültig und die Verbindung konnte hergestellt werden!", "The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "Die Konfiguration ist gültig aber die Verbindung ist fehlgeschlagen. Bitte überprüfe die Servereinstellungen und Anmeldeinformationen.", -"The configuration is invalid. Please look in the ownCloud log for further details." => "Die Konfiguration ist ungültig, sieh für weitere Details bitte im ownCloud Log nach", +"The configuration is invalid. Please have a look at the logs for further details." => "Die Konfiguration ist ungültig. Weitere Details kannst Du in den Logdateien nachlesen.", +"No action specified" => "Keine Aktion spezifiziert", +"No configuration specified" => "Keine Konfiguration spezifiziert", +"No data specified" => "Keine Daten spezifiziert", +" Could not set configuration %s" => "Die Konfiguration %s konnte nicht gesetzt werden", "Deletion failed" => "Löschen fehlgeschlagen", "Take over settings from recent server configuration?" => "Einstellungen von letzter Konfiguration übernehmen?", "Keep settings?" => "Einstellungen beibehalten?", @@ -12,40 +16,60 @@ $TRANSLATIONS = array( "mappings cleared" => "Zuordnungen gelöscht", "Success" => "Erfolgreich", "Error" => "Fehler", +"Configuration OK" => "Konfiguration OK", +"Configuration incorrect" => "Konfiguration nicht korrekt", +"Configuration incomplete" => "Konfiguration nicht vollständig", +"Select groups" => "Wähle Gruppen aus", +"Select object classes" => "Objekt-Klassen auswählen", +"Select attributes" => "Attribute auswählen", "Connection test succeeded" => "Verbindungstest erfolgreich", "Connection test failed" => "Verbindungstest fehlgeschlagen", "Do you really want to delete the current Server Configuration?" => "Möchtest Du die aktuelle Serverkonfiguration wirklich löschen?", "Confirm Deletion" => "Löschung bestätigen", -"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Warnung:</b> Die Anwendungen user_ldap und user_webdavauth sind inkompatibel. Es kann demzufolge zu unerwarteten Verhalten kommen. Bitte\ndeinen Systemadministator eine der beiden Anwendungen zu deaktivieren.", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Warnung:</b> Da das PHP-Modul für LDAP nicht installiert ist, wird das Backend nicht funktionieren. Bitte Deinen Systemadministrator das Modul zu installieren.", -"Server configuration" => "Serverkonfiguration", +"_%s group found_::_%s groups found_" => array("%s Gruppe gefunden","%s Gruppen gefunden"), +"_%s user found_::_%s users found_" => array("%s Benutzer gefunden","%s Benutzer gefunden"), +"Invalid Host" => "Ungültiger Host", +"Could not find the desired feature" => "Konnte die gewünschte Funktion nicht finden", +"Save" => "Speichern", +"Test Configuration" => "Testkonfiguration", +"Help" => "Hilfe", +"Limit the access to %s to groups meeting this criteria:" => "Beschränke den Zugriff auf %s auf Gruppen, die die folgenden Kriterien erfüllen:", +"only those object classes:" => "Nur diese Objekt-Klassen:", +"only from those groups:" => "Nur von diesen Gruppen:", +"Edit raw filter instead" => "Original-Filter stattdessen bearbeiten", +"Raw LDAP filter" => "Original LDAP-Filter", +"The filter specifies which LDAP groups shall have access to the %s instance." => "Der Filter definiert welche LDAP-Gruppen Zugriff auf die %s Instanz haben sollen.", +"groups found" => "Gruppen gefunden", +"What attribute shall be used as login name:" => "Welches Attribut soll als Login-Name verwendet werden:", +"LDAP Username:" => "LDAP-Benutzername:", +"LDAP Email Address:" => "LDAP E-Mail-Adresse:", +"Other Attributes:" => "Andere Attribute:", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Bestimmt den Filter, welcher bei einer Anmeldung angewandt wird. %%uid ersetzt den Benutzernamen bei der Anmeldung. Beispiel: \"uid=%%uid\"", "Add Server Configuration" => "Serverkonfiguration hinzufügen", "Host" => "Host", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Du kannst das Protokoll auslassen, außer wenn Du SSL benötigst. Beginne dann mit ldaps://", -"Base DN" => "Basis-DN", -"One Base DN per line" => "Ein Basis-DN pro Zeile", -"You can specify Base DN for users and groups in the Advanced tab" => "Du kannst Basis-DN für Benutzer und Gruppen in dem \"Erweitert\"-Reiter konfigurieren", +"Port" => "Port", "User DN" => "Benutzer-DN", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "Der DN des Benutzers für LDAP-Bind, z.B.: uid=agent,dc=example,dc=com. Für anonymen Zugriff lasse DN und Passwort leer.", "Password" => "Passwort", "For anonymous access, leave DN and Password empty." => "Lasse die Felder DN und Passwort für anonymen Zugang leer.", -"User Login Filter" => "Benutzer-Login-Filter", -"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Bestimmt den Filter, welcher bei einer Anmeldung angewandt wird. %%uid ersetzt den Benutzernamen bei der Anmeldung. Beispiel: \"uid=%%uid\"", -"User List Filter" => "Benutzer-Filter-Liste", -"Defines the filter to apply, when retrieving users (no placeholders). Example: \"objectClass=person\"" => "Definiert den Filter für die Wiederherstellung eines Benutzers (kein Platzhalter). Beispiel: \"objectClass=person\"", -"Group Filter" => "Gruppen-Filter", -"Defines the filter to apply, when retrieving groups (no placeholders). Example: \"objectClass=posixGroup\"" => "Definiert den Filter für die Wiederherstellung einer Gruppe (kein Platzhalter). Beispiel: \"objectClass=posixGroup\"", +"One Base DN per line" => "Ein Basis-DN pro Zeile", +"You can specify Base DN for users and groups in the Advanced tab" => "Du kannst Basis-DN für Benutzer und Gruppen in dem \"Erweitert\"-Reiter konfigurieren", +"Limit the access to %s to users meeting this criteria:" => "Beschränke den Zugriff auf %s auf Benutzer, die die folgenden Kriterien erfüllen:", +"The filter specifies which LDAP users shall have access to the %s instance." => "Der Filter definiert welche LDAP-Benutzer Zugriff auf die %s Instanz haben sollen.", +"users found" => "Benutzer gefunden", +"Back" => "Zurück", +"Continue" => "Fortsetzen", +"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Warnung:</b> Die Anwendungen user_ldap und user_webdavauth sind inkompatibel. Es kann demzufolge zu unerwarteten Verhalten kommen. Bitte\ndeinen Systemadministator eine der beiden Anwendungen zu deaktivieren.", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Warnung:</b> Da das PHP-Modul für LDAP nicht installiert ist, wird das Backend nicht funktionieren. Bitte Deinen Systemadministrator das Modul zu installieren.", "Connection Settings" => "Verbindungseinstellungen", "Configuration Active" => "Konfiguration aktiv", "When unchecked, this configuration will be skipped." => "Konfiguration wird übersprungen wenn deaktiviert", -"Port" => "Port", "Backup (Replica) Host" => "Backup Host (Kopie)", "Give an optional backup host. It must be a replica of the main LDAP/AD server." => "Gib einen optionalen Backup Host an. Es muss sich um eine Kopie des Haupt LDAP/AD Servers handeln.", "Backup (Replica) Port" => "Backup Port", "Disable Main Server" => "Hauptserver deaktivieren", "Only connect to the replica server." => "Nur zum Replikat-Server verbinden.", -"Use TLS" => "Nutze TLS", -"Do not use it additionally for LDAPS connections, it will fail." => "Benutze es nicht zusammen mit LDAPS Verbindungen, es wird fehlschlagen.", "Case insensitve LDAP server (Windows)" => "LDAP-Server (Windows: Groß- und Kleinschreibung bleibt unbeachtet)", "Turn off SSL certificate validation." => "Schalte die SSL-Zertifikatsprüfung aus.", "Not recommended, use it for testing only! If connection only works with this option, import the LDAP server's SSL certificate in your %s server." => "Nur für Testzwecke geeignet, sollte Standardmäßig nicht verwendet werden. Falls die Verbindung nur mit dieser Option funktioniert, importiere das SSL-Zertifikat des LDAP-Servers in deinen %s Server.", @@ -76,12 +100,11 @@ $TRANSLATIONS = array( "Internal Username Attribute:" => "Attribut für interne Benutzernamen:", "Override UUID detection" => "UUID-Erkennung überschreiben", "By default, the UUID attribute is automatically detected. The UUID attribute is used to doubtlessly identify LDAP users and groups. Also, the internal username will be created based on the UUID, if not specified otherwise above. You can override the setting and pass an attribute of your choice. You must make sure that the attribute of your choice can be fetched for both users and groups and it is unique. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users and groups." => "Standardmäßig wird die UUID-Eigenschaft automatisch erkannt. Die UUID-Eigenschaft wird genutzt, um einen LDAP-Benutzer und Gruppen einwandfrei zu identifizieren. Außerdem wird der interne Benutzername erzeugt, der auf Eigenschaften der UUID basiert, wenn es oben nicht anders angegeben wurde. Du musst allerdings sicherstellen, dass deine gewählten Eigenschaften zur Identifikation der Benutzer und Gruppen eindeutig sind und zugeordnet werden können. Lasse es frei, um es beim Standardverhalten zu belassen. Änderungen wirken sich nur auf neu gemappte (hinzugefügte) LDAP-Benutzer und -Gruppen aus.", -"UUID Attribute:" => "UUID-Attribut:", +"UUID Attribute for Users:" => "UUID-Attribute für Benutzer:", +"UUID Attribute for Groups:" => "UUID-Attribute für Gruppen:", "Username-LDAP User Mapping" => "LDAP-Benutzernamenzuordnung", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have a internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." => "Die Benutzernamen werden genutzt, um (Meta)Daten zuzuordnen und zu speichern. Um Benutzer eindeutig und präzise zu identifizieren, hat jeder LDAP-Benutzer einen internen Benutzernamen. Dies erfordert eine Zuordnung (mappen) von Benutzernamen zum LDAP-Benutzer. Der erstellte Benutzername wird der UUID des LDAP-Benutzernamens zugeordnet. Zusätzlich wird der DN zwischengespeichert, um die Interaktion mit dem LDAP zu minimieren, was aber nicht der Identifikation dient. Ändert sich der DN, werden die Änderungen durch gefunden. Der interne Benutzername, wird in überall verwendet. Werden die Zuordnungen gelöscht, bleiben überall Reste zurück. Die Löschung der Zuordnungen kann nicht in der Konfiguration vorgenommen werden, beeinflusst aber die LDAP-Konfiguration! Löschen Sie niemals die Zuordnungen in einer produktiven Umgebung. Lösche die Zuordnungen nur in einer Test- oder Experimentierumgebung.", "Clear Username-LDAP User Mapping" => "Lösche LDAP-Benutzernamenzuordnung", -"Clear Groupname-LDAP Group Mapping" => "Lösche LDAP-Gruppennamenzuordnung", -"Test Configuration" => "Testkonfiguration", -"Help" => "Hilfe" +"Clear Groupname-LDAP Group Mapping" => "Lösche LDAP-Gruppennamenzuordnung" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/de_AT.php b/apps/user_ldap/l10n/de_AT.php new file mode 100644 index 00000000000..3a1e002311c --- /dev/null +++ b/apps/user_ldap/l10n/de_AT.php @@ -0,0 +1,6 @@ +<?php +$TRANSLATIONS = array( +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("","") +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/de_CH.php b/apps/user_ldap/l10n/de_CH.php index df9175e73b1..5f8e2907f07 100644 --- a/apps/user_ldap/l10n/de_CH.php +++ b/apps/user_ldap/l10n/de_CH.php @@ -4,7 +4,6 @@ $TRANSLATIONS = array( "Failed to delete the server configuration" => "Löschen der Serverkonfiguration fehlgeschlagen", "The configuration is valid and the connection could be established!" => "Die Konfiguration ist gültig und die Verbindung konnte hergestellt werden!", "The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "Die Konfiguration ist gültig aber die Verbindung ist fehlgeschlagen. Bitte überprüfen Sie die Servereinstellungen und die Anmeldeinformationen.", -"The configuration is invalid. Please look in the ownCloud log for further details." => "Die Konfiguration ist ungültig, sehen Sie für weitere Details bitte im ownCloud Log nach", "Deletion failed" => "Löschen fehlgeschlagen", "Take over settings from recent server configuration?" => "Einstellungen von letzter Konfiguration übernehmen?", "Keep settings?" => "Einstellungen beibehalten?", @@ -12,40 +11,37 @@ $TRANSLATIONS = array( "mappings cleared" => "Zuordnungen gelöscht", "Success" => "Erfolg", "Error" => "Fehler", +"Select groups" => "Wähle Gruppen", "Connection test succeeded" => "Verbindungstest erfolgreich", "Connection test failed" => "Verbindungstest fehlgeschlagen", "Do you really want to delete the current Server Configuration?" => "Möchten Sie die aktuelle Serverkonfiguration wirklich löschen?", "Confirm Deletion" => "Löschung bestätigen", -"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Warnung:</b> Die Anwendungen user_ldap und user_webdavauth sind inkompatibel. Es kann demzufolge zu unerwarteten Verhalten kommen. Bitten Sie Ihren Systemadministator eine der beiden Anwendungen zu deaktivieren.", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Warnung:</b> Da das PHP-Modul für LDAP nicht installiert ist, wird das Backend nicht funktionieren. Bitten Sie Ihren Systemadministrator das Modul zu installieren.", -"Server configuration" => "Serverkonfiguration", +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("",""), +"Save" => "Speichern", +"Test Configuration" => "Testkonfiguration", +"Help" => "Hilfe", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Bestimmt den Filter, welcher bei einer Anmeldung angewandt wird. %%uid ersetzt den Benutzernamen bei der Anmeldung. Beispiel: \"uid=%%uid\"", "Add Server Configuration" => "Serverkonfiguration hinzufügen", "Host" => "Host", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Sie können das Protokoll auslassen, ausser wenn Sie SSL benötigen. Beginnen Sie dann mit ldaps://", -"Base DN" => "Basis-DN", -"One Base DN per line" => "Ein Basis-DN pro Zeile", -"You can specify Base DN for users and groups in the Advanced tab" => "Sie können Basis-DN für Benutzer und Gruppen in dem «Erweitert»-Reiter konfigurieren", +"Port" => "Port", "User DN" => "Benutzer-DN", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "Der DN des Benutzers für LDAP-Bind, z.B.: uid=agent,dc=example,dc=com. Für einen anonymen Zugriff lassen Sie DN und Passwort leer.", "Password" => "Passwort", "For anonymous access, leave DN and Password empty." => "Lassen Sie die Felder DN und Passwort für einen anonymen Zugang leer.", -"User Login Filter" => "Benutzer-Login-Filter", -"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Bestimmt den Filter, welcher bei einer Anmeldung angewandt wird. %%uid ersetzt den Benutzernamen bei der Anmeldung. Beispiel: \"uid=%%uid\"", -"User List Filter" => "Benutzer-Filter-Liste", -"Defines the filter to apply, when retrieving users (no placeholders). Example: \"objectClass=person\"" => "Definiert den Filter für die Wiederherstellung eines Benutzers (kein Platzhalter). Beispiel: \"objectClass=person\"", -"Group Filter" => "Gruppen-Filter", -"Defines the filter to apply, when retrieving groups (no placeholders). Example: \"objectClass=posixGroup\"" => "Definiert den Filter für die Wiederherstellung einer Gruppe (kein Platzhalter). Beispiel: \"objectClass=posixGroup\"", +"One Base DN per line" => "Ein Basis-DN pro Zeile", +"You can specify Base DN for users and groups in the Advanced tab" => "Sie können Basis-DN für Benutzer und Gruppen in dem «Erweitert»-Reiter konfigurieren", +"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Warnung:</b> Die Anwendungen user_ldap und user_webdavauth sind inkompatibel. Es kann demzufolge zu unerwarteten Verhalten kommen. Bitten Sie Ihren Systemadministator eine der beiden Anwendungen zu deaktivieren.", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Warnung:</b> Da das PHP-Modul für LDAP nicht installiert ist, wird das Backend nicht funktionieren. Bitten Sie Ihren Systemadministrator das Modul zu installieren.", "Connection Settings" => "Verbindungseinstellungen", "Configuration Active" => "Konfiguration aktiv", "When unchecked, this configuration will be skipped." => "Wenn nicht angehakt, wird diese Konfiguration übersprungen.", -"Port" => "Port", "Backup (Replica) Host" => "Backup Host (Kopie)", "Give an optional backup host. It must be a replica of the main LDAP/AD server." => "Geben Sie einen optionalen Backup Host an. Es muss sich um eine Kopie des Haupt LDAP/AD Servers handeln.", "Backup (Replica) Port" => "Backup Port", "Disable Main Server" => "Hauptserver deaktivieren", "Only connect to the replica server." => "Nur zum Replikat-Server verbinden.", -"Use TLS" => "Nutze TLS", -"Do not use it additionally for LDAPS connections, it will fail." => "Benutzen Sie es nicht in Verbindung mit LDAPS Verbindungen, es wird fehlschlagen.", "Case insensitve LDAP server (Windows)" => "LDAP-Server (Windows: Gross- und Kleinschreibung bleibt unbeachtet)", "Turn off SSL certificate validation." => "Schalten Sie die SSL-Zertifikatsprüfung aus.", "Not recommended, use it for testing only! If connection only works with this option, import the LDAP server's SSL certificate in your %s server." => "Nur für Testzwecke geeignet, sollte Standardmäßig nicht verwendet werden. Falls die Verbindung nur mit dieser Option funktioniert, importieren Sie das SSL-Zertifikat des LDAP-Servers in Ihren %s Server.", @@ -76,12 +72,9 @@ $TRANSLATIONS = array( "Internal Username Attribute:" => "Interne Eigenschaften des Benutzers:", "Override UUID detection" => "UUID-Erkennung überschreiben", "By default, the UUID attribute is automatically detected. The UUID attribute is used to doubtlessly identify LDAP users and groups. Also, the internal username will be created based on the UUID, if not specified otherwise above. You can override the setting and pass an attribute of your choice. You must make sure that the attribute of your choice can be fetched for both users and groups and it is unique. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users and groups." => "Standardmässig wird die UUID-Eigenschaft automatisch erkannt. Die UUID-Eigenschaft wird genutzt, um einen LDAP-Benutzer und Gruppen einwandfrei zu identifizieren. Ausserdem wird der interne Benutzername erzeugt, der auf Eigenschaften der UUID basiert, wenn es oben nicht anders angegeben wurde. Sie müssen allerdings sicherstellen, dass Ihre gewählten Eigenschaften zur Identifikation der Benutzer und Gruppen eindeutig sind und zugeordnet werden können. Lassen Sie es frei, um es beim Standardverhalten zu belassen. Änderungen wirken sich nur auf neu gemappte (hinzugefügte) LDAP-Benutzer und -Gruppen aus.", -"UUID Attribute:" => "UUID-Attribut:", "Username-LDAP User Mapping" => "LDAP-Benutzernamenzuordnung", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have a internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." => "Die Benutzernamen werden genutzt, um (Meta)Daten zuzuordnen und zu speichern. Um Benutzer eindeutig und präzise zu identifizieren, hat jeder LDAP-Benutzer einen internen Benutzernamen. Dies erfordert eine Zuordnung (mappen) von Benutzernamen zum LDAP-Benutzer. Der erstellte Benutzername wird der UUID des LDAP-Benutzernamens zugeordnet. Zusätzlich wird der DN zwischengespeichert, um die Interaktion mit dem LDAP zu minimieren, was aber nicht der Identifikation dient. Ändert sich der DN, werden die Änderungen durch gefunden. Der interne Benutzername, wird in überall verwendet. Werden die Zuordnungen gelöscht, bleiben überall Reste zurück. Die Löschung der Zuordnungen kann nicht in der Konfiguration vorgenommen werden, beeinflusst aber die LDAP-Konfiguration! Löschen Sie niemals die Zuordnungen in einer produktiven Umgebung. Löschen Sie die Zuordnungen nur in einer Test- oder Experimentierumgebung.", "Clear Username-LDAP User Mapping" => "Lösche LDAP-Benutzernamenzuordnung", -"Clear Groupname-LDAP Group Mapping" => "Lösche LDAP-Gruppennamenzuordnung", -"Test Configuration" => "Testkonfiguration", -"Help" => "Hilfe" +"Clear Groupname-LDAP Group Mapping" => "Lösche LDAP-Gruppennamenzuordnung" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/de_DE.php b/apps/user_ldap/l10n/de_DE.php index 677d603ffa0..168f1fe059c 100644 --- a/apps/user_ldap/l10n/de_DE.php +++ b/apps/user_ldap/l10n/de_DE.php @@ -4,7 +4,11 @@ $TRANSLATIONS = array( "Failed to delete the server configuration" => "Löschen der Serverkonfiguration fehlgeschlagen", "The configuration is valid and the connection could be established!" => "Die Konfiguration ist gültig und die Verbindung konnte hergestellt werden!", "The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "Die Konfiguration ist gültig aber die Verbindung ist fehlgeschlagen. Bitte überprüfen Sie die Servereinstellungen und die Anmeldeinformationen.", -"The configuration is invalid. Please look in the ownCloud log for further details." => "Die Konfiguration ist ungültig, sehen Sie für weitere Details bitte im ownCloud Log nach", +"The configuration is invalid. Please have a look at the logs for further details." => "Die Konfiguration ist ungültig. Weitere Details können Sie in den Logdateien nachlesen.", +"No action specified" => "Keine Aktion spezifiziert", +"No configuration specified" => "Keine Konfiguration spezifiziert", +"No data specified" => "Keine Daten spezifiziert", +" Could not set configuration %s" => "Die Konfiguration %s konnte nicht gesetzt werden", "Deletion failed" => "Löschen fehlgeschlagen", "Take over settings from recent server configuration?" => "Einstellungen von letzter Konfiguration übernehmen?", "Keep settings?" => "Einstellungen beibehalten?", @@ -12,40 +16,60 @@ $TRANSLATIONS = array( "mappings cleared" => "Zuordnungen gelöscht", "Success" => "Erfolg", "Error" => "Fehler", +"Configuration OK" => "Konfiguration OK", +"Configuration incorrect" => "Konfiguration nicht korrekt", +"Configuration incomplete" => "Konfiguration nicht vollständig", +"Select groups" => "Wähle Gruppen", +"Select object classes" => "Objekt-Klassen auswählen", +"Select attributes" => "Attribute auswählen", "Connection test succeeded" => "Verbindungstest erfolgreich", "Connection test failed" => "Verbindungstest fehlgeschlagen", "Do you really want to delete the current Server Configuration?" => "Möchten Sie die aktuelle Serverkonfiguration wirklich löschen?", "Confirm Deletion" => "Löschung bestätigen", -"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Warnung:</b> Die Anwendungen user_ldap und user_webdavauth sind inkompatibel. Es kann demzufolge zu unerwarteten Verhalten kommen. Bitten Sie Ihren Systemadministator eine der beiden Anwendungen zu deaktivieren.", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Warnung:</b> Da das PHP-Modul für LDAP nicht installiert ist, wird das Backend nicht funktionieren. Bitten Sie Ihren Systemadministrator das Modul zu installieren.", -"Server configuration" => "Serverkonfiguration", +"_%s group found_::_%s groups found_" => array("%s Gruppe gefunden","%s Gruppen gefunden"), +"_%s user found_::_%s users found_" => array("%s Benutzer gefunden","%s Benutzer gefunden"), +"Invalid Host" => "Ungültiger Host", +"Could not find the desired feature" => "Konnte die gewünschte Funktion nicht finden", +"Save" => "Speichern", +"Test Configuration" => "Testkonfiguration", +"Help" => "Hilfe", +"Limit the access to %s to groups meeting this criteria:" => "Beschränke den Zugriff auf %s auf Gruppen, die die folgenden Kriterien erfüllen:", +"only those object classes:" => "Nur diese Objekt-Klassen:", +"only from those groups:" => "Nur von diesen Gruppen:", +"Edit raw filter instead" => "Original-Filter stattdessen bearbeiten", +"Raw LDAP filter" => "Original LDAP-Filter", +"The filter specifies which LDAP groups shall have access to the %s instance." => "Der Filter definiert welche LDAP-Gruppen Zugriff auf die %s Instanz haben sollen.", +"groups found" => "Gruppen gefunden", +"What attribute shall be used as login name:" => "Welches Attribut soll als Login-Name verwendet werden:", +"LDAP Username:" => "LDAP-Benutzername:", +"LDAP Email Address:" => "LDAP E-Mail-Adresse:", +"Other Attributes:" => "Andere Attribute:", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Bestimmt den Filter, welcher bei einer Anmeldung angewandt wird. %%uid ersetzt den Benutzernamen bei der Anmeldung. Beispiel: \"uid=%%uid\"", "Add Server Configuration" => "Serverkonfiguration hinzufügen", "Host" => "Host", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Sie können das Protokoll auslassen, außer wenn Sie SSL benötigen. Beginnen Sie dann mit ldaps://", -"Base DN" => "Basis-DN", -"One Base DN per line" => "Ein Basis-DN pro Zeile", -"You can specify Base DN for users and groups in the Advanced tab" => "Sie können Basis-DN für Benutzer und Gruppen in dem \"Erweitert\"-Reiter konfigurieren", +"Port" => "Port", "User DN" => "Benutzer-DN", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "Der DN des Benutzers für LDAP-Bind, z.B.: uid=agent,dc=example,dc=com. Für einen anonymen Zugriff lassen Sie DN und Passwort leer.", "Password" => "Passwort", "For anonymous access, leave DN and Password empty." => "Lassen Sie die Felder DN und Passwort für einen anonymen Zugang leer.", -"User Login Filter" => "Benutzer-Login-Filter", -"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Bestimmt den Filter, welcher bei einer Anmeldung angewandt wird. %%uid ersetzt den Benutzernamen bei der Anmeldung. Beispiel: \"uid=%%uid\"", -"User List Filter" => "Benutzer-Filter-Liste", -"Defines the filter to apply, when retrieving users (no placeholders). Example: \"objectClass=person\"" => "Definiert den Filter für die Wiederherstellung eines Benutzers (kein Platzhalter). Beispiel: \"objectClass=person\"", -"Group Filter" => "Gruppen-Filter", -"Defines the filter to apply, when retrieving groups (no placeholders). Example: \"objectClass=posixGroup\"" => "Definiert den Filter für die Wiederherstellung einer Gruppe (kein Platzhalter). Beispiel: \"objectClass=posixGroup\"", +"One Base DN per line" => "Ein Basis-DN pro Zeile", +"You can specify Base DN for users and groups in the Advanced tab" => "Sie können Basis-DN für Benutzer und Gruppen in dem \"Erweitert\"-Reiter konfigurieren", +"Limit the access to %s to users meeting this criteria:" => "Beschränke den Zugriff auf %s auf Benutzer, die die folgenden Kriterien erfüllen:", +"The filter specifies which LDAP users shall have access to the %s instance." => "Der Filter definiert welche LDAP-Benutzer Zugriff auf die %s Instanz haben sollen.", +"users found" => "Benutzer gefunden", +"Back" => "Zurück", +"Continue" => "Fortsetzen", +"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Warnung:</b> Die Anwendungen user_ldap und user_webdavauth sind inkompatibel. Es kann demzufolge zu unerwarteten Verhalten kommen. Bitten Sie Ihren Systemadministator eine der beiden Anwendungen zu deaktivieren.", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Warnung:</b> Da das PHP-Modul für LDAP nicht installiert ist, wird das Backend nicht funktionieren. Bitten Sie Ihren Systemadministrator das Modul zu installieren.", "Connection Settings" => "Verbindungseinstellungen", "Configuration Active" => "Konfiguration aktiv", "When unchecked, this configuration will be skipped." => "Wenn nicht angehakt, wird diese Konfiguration übersprungen.", -"Port" => "Port", "Backup (Replica) Host" => "Backup Host (Kopie)", "Give an optional backup host. It must be a replica of the main LDAP/AD server." => "Geben Sie einen optionalen Backup Host an. Es muss sich um eine Kopie des Haupt LDAP/AD Servers handeln.", "Backup (Replica) Port" => "Backup Port", "Disable Main Server" => "Hauptserver deaktivieren", "Only connect to the replica server." => "Nur zum Replikat-Server verbinden.", -"Use TLS" => "Nutze TLS", -"Do not use it additionally for LDAPS connections, it will fail." => "Benutzen Sie es nicht in Verbindung mit LDAPS Verbindungen, es wird fehlschlagen.", "Case insensitve LDAP server (Windows)" => "LDAP-Server (Windows: Groß- und Kleinschreibung bleibt unbeachtet)", "Turn off SSL certificate validation." => "Schalten Sie die SSL-Zertifikatsprüfung aus.", "Not recommended, use it for testing only! If connection only works with this option, import the LDAP server's SSL certificate in your %s server." => "Nur für Testzwecke geeignet, sollte Standardmäßig nicht verwendet werden. Falls die Verbindung nur mit dieser Option funktioniert, importieren Sie das SSL-Zertifikat des LDAP-Servers in Ihren %s Server.", @@ -76,12 +100,11 @@ $TRANSLATIONS = array( "Internal Username Attribute:" => "Interne Eigenschaften des Benutzers:", "Override UUID detection" => "UUID-Erkennung überschreiben", "By default, the UUID attribute is automatically detected. The UUID attribute is used to doubtlessly identify LDAP users and groups. Also, the internal username will be created based on the UUID, if not specified otherwise above. You can override the setting and pass an attribute of your choice. You must make sure that the attribute of your choice can be fetched for both users and groups and it is unique. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users and groups." => "Standardmäßig wird die UUID-Eigenschaft automatisch erkannt. Die UUID-Eigenschaft wird genutzt, um einen LDAP-Benutzer und Gruppen einwandfrei zu identifizieren. Außerdem wird der interne Benutzername erzeugt, der auf Eigenschaften der UUID basiert, wenn es oben nicht anders angegeben wurde. Sie müssen allerdings sicherstellen, dass Ihre gewählten Eigenschaften zur Identifikation der Benutzer und Gruppen eindeutig sind und zugeordnet werden können. Lassen Sie es frei, um es beim Standardverhalten zu belassen. Änderungen wirken sich nur auf neu gemappte (hinzugefügte) LDAP-Benutzer und -Gruppen aus.", -"UUID Attribute:" => "UUID-Attribut:", +"UUID Attribute for Users:" => "UUID-Attribute für Benutzer:", +"UUID Attribute for Groups:" => "UUID-Attribute für Gruppen:", "Username-LDAP User Mapping" => "LDAP-Benutzernamenzuordnung", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have a internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." => "Die Benutzernamen werden genutzt, um (Meta)Daten zuzuordnen und zu speichern. Um Benutzer eindeutig und präzise zu identifizieren, hat jeder LDAP-Benutzer einen internen Benutzernamen. Dies erfordert eine Zuordnung (mappen) von Benutzernamen zum LDAP-Benutzer. Der erstellte Benutzername wird der UUID des LDAP-Benutzernamens zugeordnet. Zusätzlich wird der DN zwischengespeichert, um die Interaktion mit dem LDAP zu minimieren, was aber nicht der Identifikation dient. Ändert sich der DN, werden die Änderungen durch gefunden. Der interne Benutzername, wird in überall verwendet. Werden die Zuordnungen gelöscht, bleiben überall Reste zurück. Die Löschung der Zuordnungen kann nicht in der Konfiguration vorgenommen werden, beeinflusst aber die LDAP-Konfiguration! Löschen Sie niemals die Zuordnungen in einer produktiven Umgebung. Löschen Sie die Zuordnungen nur in einer Test- oder Experimentierumgebung.", "Clear Username-LDAP User Mapping" => "Lösche LDAP-Benutzernamenzuordnung", -"Clear Groupname-LDAP Group Mapping" => "Lösche LDAP-Gruppennamenzuordnung", -"Test Configuration" => "Testkonfiguration", -"Help" => "Hilfe" +"Clear Groupname-LDAP Group Mapping" => "Lösche LDAP-Gruppennamenzuordnung" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/el.php b/apps/user_ldap/l10n/el.php index d588f90518e..8369dff4895 100644 --- a/apps/user_ldap/l10n/el.php +++ b/apps/user_ldap/l10n/el.php @@ -1,55 +1,87 @@ <?php $TRANSLATIONS = array( +"Failed to clear the mappings." => "Αποτυχία εκκαθάρισης των αντιστοιχιών.", "Failed to delete the server configuration" => "Αποτυχία διαγραφής ρυθμίσεων διακομιστή", "The configuration is valid and the connection could be established!" => "Οι ρυθμίσεις είναι έγκυρες και η σύνδεση μπορεί να πραγματοποιηθεί!", "The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "Οι ρυθμίσεις είναι έγκυρες, αλλά απέτυχε η σύνδεση. Παρακαλώ ελέγξτε τις ρυθμίσεις του διακομιστή και τα διαπιστευτήρια.", -"The configuration is invalid. Please look in the ownCloud log for further details." => "Μη έγκυρες ρυθμίσεις. Παρακαλώ ελέγξτε τις καταγραφές του ownCloud για περισσότερες λεπτομέρειες.", +"The configuration is invalid. Please have a look at the logs for further details." => "Η διαμόρφωση είναι άκυρη. Παρακαλώ ελέγξτε τα αρχεία σφαλμάτων για περαιτέρω λεπτομέρειες.", +"No action specified" => "Καμμία εντολή δεν προσδιορίστηκε", +"No configuration specified" => "Καμμία διαμόρφωση δεν προσδιορίστηκε", +"No data specified" => "Δεν προσδιορίστηκαν δεδομένα", "Deletion failed" => "Η διαγραφή απέτυχε", "Take over settings from recent server configuration?" => "Πάρτε πάνω από τις πρόσφατες ρυθμίσεις διαμόρφωσης του διακομιστή?", "Keep settings?" => "Διατήρηση ρυθμίσεων;", "Cannot add server configuration" => "Αδυναμία προσθήκης ρυθμίσεων διακομιστή", +"mappings cleared" => "αντιστοιχίες εκκαθαρίστηκαν", "Success" => "Επιτυχία", "Error" => "Σφάλμα", +"Configuration OK" => "Η διαμόρφωση είναι εντάξει", +"Configuration incorrect" => "Η διαμόρφωση είναι λανθασμένη", +"Configuration incomplete" => "Η διαμόρφωση είναι ελλιπής", +"Select groups" => "Επιλέξτε ομάδες", +"Select object classes" => "Επιλογή κλάσης αντικειμένων", +"Select attributes" => "Επιλογή χαρακτηριστικών", "Connection test succeeded" => "Επιτυχημένη δοκιμαστική σύνδεση", "Connection test failed" => "Αποτυχημένη δοκιμαστική σύνδεσης.", "Do you really want to delete the current Server Configuration?" => "Θέλετε να διαγράψετε τις τρέχουσες ρυθμίσεις του διακομιστή;", "Confirm Deletion" => "Επιβεβαίωση Διαγραφής", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Προσοχή:</b> Το άρθρωμα PHP LDAP δεν είναι εγκατεστημένο και το σύστημα υποστήριξης δεν θα δουλέψει. Παρακαλώ ζητήστε από τον διαχειριστή συστήματος να το εγκαταστήσει.", -"Server configuration" => "Ρυθμίσεις Διακομιστή", +"_%s group found_::_%s groups found_" => array("%s ομάδα βρέθηκε","%s ομάδες βρέθηκαν"), +"_%s user found_::_%s users found_" => array("%s χρήστης βρέθηκε","%s χρήστες βρέθηκαν"), +"Invalid Host" => "Άκυρος εξυπηρετητής", +"Could not find the desired feature" => "Αδυναμία εύρεσης επιθυμητου χαρακτηριστικού", +"Save" => "Αποθήκευση", +"Test Configuration" => "Δοκιμαστικες ρυθμισεις", +"Help" => "Βοήθεια", +"Limit the access to %s to groups meeting this criteria:" => "Περιορισμός πρόσβασης %s σε ομάδες που ταιριάζουν αυτά τα κριτήρια:", +"only those object classes:" => "μόνο αυτές οι κλάσεις αντικειμένων:", +"only from those groups:" => "μόνο από αυτές τις ομάδες:", +"Edit raw filter instead" => "Επεξεργασία πρωτογενούς φίλτρου αντί αυτού", +"Raw LDAP filter" => "Πρωτογενές φίλτρο ", +"The filter specifies which LDAP groups shall have access to the %s instance." => "Το φίλτρο καθορίζει ποιες ομάδες LDAP θα έχουν πρόσβαση στην εγκατάσταση %s.", +"groups found" => "ομάδες βρέθηκαν", +"What attribute shall be used as login name:" => "Ποια ιδιότητα θα χρησιμοποιηθεί ως όνομα σύνδεσης:", +"LDAP Username:" => "Όνομα χρήστη LDAP:", +"LDAP Email Address:" => "Διεύθυνση ηλ. ταχυδρομείου LDAP:", +"Other Attributes:" => "Άλλες Ιδιότητες:", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Ορίζει το φίλτρο που θα εφαρμοστεί, όταν επιχειριθεί σύνδεση. Το %%uid αντικαθιστά το όνομα χρήστη κατά τη σύνδεση. Παράδειγμα: \"uid=%%uid\"", "Add Server Configuration" => "Προσθήκη Ρυθμίσεων Διακομιστή", "Host" => "Διακομιστής", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Μπορείτε να παραλείψετε το πρωτόκολλο, εκτός αν απαιτείται SSL. Σε αυτή την περίπτωση ξεκινήστε με ldaps://", -"Base DN" => "Base DN", -"One Base DN per line" => "Ένα DN Βάσης ανά γραμμή ", -"You can specify Base DN for users and groups in the Advanced tab" => "Μπορείτε να καθορίσετε το Base DN για χρήστες και ομάδες από την καρτέλα Προηγμένες ρυθμίσεις", +"Port" => "Θύρα", "User DN" => "User DN", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "Το DN του χρήστη πελάτη με το οποίο θα πρέπει να γίνει η σύνδεση, π.χ. uid=agent,dc=example,dc=com. Για χρήση χωρίς πιστοποίηση, αφήστε το DN και τον Κωδικό κενά.", "Password" => "Συνθηματικό", "For anonymous access, leave DN and Password empty." => "Για ανώνυμη πρόσβαση, αφήστε κενά τα πεδία DN και Pasword.", -"User Login Filter" => "User Login Filter", -"User List Filter" => "User List Filter", -"Group Filter" => "Group Filter", +"One Base DN per line" => "Ένα DN Βάσης ανά γραμμή ", +"You can specify Base DN for users and groups in the Advanced tab" => "Μπορείτε να καθορίσετε το Base DN για χρήστες και ομάδες από την καρτέλα Προηγμένες ρυθμίσεις", +"Limit the access to %s to users meeting this criteria:" => "Περιορισμός πρόσβασης %s σε χρήστες που ταιριάζουν αυτά τα κριτήρια:", +"The filter specifies which LDAP users shall have access to the %s instance." => "Το φίλτρο καθορίζει ποιοι χρήστες LDAP θα έχουν πρόσβαση στην εγκατάσταση %s.", +"users found" => "χρήστες βρέθηκαν", +"Back" => "Επιστροφή", +"Continue" => "Συνέχεια", +"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Προσοχή:</b> Οι εφαρμογές user_ldap και user_webdavauth είναι ασύμβατες. Μπορεί να αντιμετωπίσετε απρόβλεπτη συμπεριφορά. Παρακαλώ ζητήστε από τον διαχειριστή συστήματος να απενεργοποιήσει μία από αυτές.", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Προσοχή:</b> Το άρθρωμα PHP LDAP δεν είναι εγκατεστημένο και το σύστημα υποστήριξης δεν θα δουλέψει. Παρακαλώ ζητήστε από τον διαχειριστή συστήματος να το εγκαταστήσει.", "Connection Settings" => "Ρυθμίσεις Σύνδεσης", "Configuration Active" => "Ενεργοποιηση ρυθμισεων", "When unchecked, this configuration will be skipped." => "Όταν δεν είναι επιλεγμένο, αυτή η ρύθμιση θα πρέπει να παραλειφθεί. ", -"Port" => "Θύρα", "Backup (Replica) Host" => "Δημιουργία αντιγράφων ασφαλείας (Replica) Host ", "Give an optional backup host. It must be a replica of the main LDAP/AD server." => "Δώστε μια προαιρετική εφεδρική υποδοχή. Πρέπει να είναι ένα αντίγραφο του κύριου LDAP / AD διακομιστη.", "Backup (Replica) Port" => "Δημιουργία αντιγράφων ασφαλείας (Replica) Υποδοχη", "Disable Main Server" => "Απενεργοποιηση του κεντρικου διακομιστη", -"Use TLS" => "Χρήση TLS", -"Do not use it additionally for LDAPS connections, it will fail." => "Μην το χρησιμοποιήσετε επιπροσθέτως, για LDAPS συνδέσεις , θα αποτύχει.", "Case insensitve LDAP server (Windows)" => "LDAP server (Windows) με διάκριση πεζών-ΚΕΦΑΛΑΙΩΝ", "Turn off SSL certificate validation." => "Απενεργοποίηση επικύρωσης πιστοποιητικού SSL.", +"Not recommended, use it for testing only! If connection only works with this option, import the LDAP server's SSL certificate in your %s server." => "Δεν προτείνεται, χρησιμοποιείστε το μόνο για δοκιμές! Εάν η σύνδεση λειτουργεί μόνο με αυτή την επιλογή, εισάγετε το πιστοποιητικό SSL του διακομιστή LDAP στο %s διακομιστή σας.", "Cache Time-To-Live" => "Cache Time-To-Live", "in seconds. A change empties the cache." => "σε δευτερόλεπτα. Μια αλλαγή αδειάζει την μνήμη cache.", "Directory Settings" => "Ρυθμίσεις Καταλόγου", "User Display Name Field" => "Πεδίο Ονόματος Χρήστη", +"The LDAP attribute to use to generate the user's display name." => "Η ιδιότητα LDAP προς χρήση για δημιουργία του προβαλλόμενου ονόματος χρήστη.", "Base User Tree" => "Base User Tree", "One User Base DN per line" => "Ένα DN βάσης χρηστών ανά γραμμή", "User Search Attributes" => "Χαρακτηριστικά αναζήτησης των χρηστών ", "Optional; one attribute per line" => "Προαιρετικά? Ένα χαρακτηριστικό ανά γραμμή ", "Group Display Name Field" => "Group Display Name Field", +"The LDAP attribute to use to generate the groups's display name." => "Η ιδιότητα LDAP προς χρήση για δημιουργία του προβαλλόμενου ονόματος ομάδας.", "Base Group Tree" => "Base Group Tree", "One Group Base DN per line" => "Μια ομαδικη Βάση DN ανά γραμμή", "Group Search Attributes" => "Ομάδα Χαρακτηριστικων Αναζήτηση", @@ -61,7 +93,16 @@ $TRANSLATIONS = array( "Email Field" => "Email τυπος", "User Home Folder Naming Rule" => "Χρήστης Προσωπικόςφάκελος Ονομασία Κανόνας ", "Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "Αφήστε το κενό για το όνομα χρήστη (προεπιλογή). Διαφορετικά, συμπληρώστε μία ιδιότητα LDAP/AD.", -"Test Configuration" => "Δοκιμαστικες ρυθμισεις", -"Help" => "Βοήθεια" +"Internal Username" => "Εσωτερικό Όνομα Χρήστη", +"By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. To achieve a similar behavior as before ownCloud 5 enter the user display name attribute in the following field. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users." => "Εξ ορισμού, το εσωτερικό όνομα χρήστη θα δημιουργηθεί από το χαρακτηριστικό UUID. Αυτό βεβαιώνει ότι το όνομα χρήστη είναι μοναδικό και δεν χρειάζεται μετατροπή χαρακτήρων. Το εσωτερικό όνομα χρήστη έχει τον περιορισμό ότι μόνο αυτοί οι χαρακτήρες επιτρέπονται: [ a-zA-Z0-9_.@- ]. Οι άλλοι χαρακτήρες αντικαθίστανται με τους αντίστοιχους ASCII ή απλά παραλείπονται. Στις συγκρούσεις ένας αριθμός θα προστεθεί / αυξηθεί. Το εσωτερικό όνομα χρήστη χρησιμοποιείται για την αναγνώριση ενός χρήστη εσωτερικά. Είναι επίσης το προεπιλεγμένο όνομα για τον αρχικό φάκελο χρήστη. Αποτελεί επίσης μέρος των απομακρυσμένων διευθύνσεων URL, για παράδειγμα για όλες τις υπηρεσίες *DAV. Με αυτή τη ρύθμιση, η προεπιλεγμένη συμπεριφορά μπορεί να παρακαμφθεί. Για να επιτευχθεί μια παρόμοια συμπεριφορά όπως πριν το ownCloud 5 εισάγετε το χαρακτηριστικό του προβαλλόμενου ονόματος χρήστη στο παρακάτω πεδίο. Αφήστε το κενό για την προεπιλεγμένη λειτουργία. Οι αλλαγές θα έχουν ισχύ μόνο σε νεώτερους (προστιθέμενους) χρήστες LDAP.", +"Internal Username Attribute:" => "Ιδιότητα Εσωτερικού Ονόματος Χρήστη:", +"Override UUID detection" => "Παράκαμψη ανίχνευσης UUID", +"By default, the UUID attribute is automatically detected. The UUID attribute is used to doubtlessly identify LDAP users and groups. Also, the internal username will be created based on the UUID, if not specified otherwise above. You can override the setting and pass an attribute of your choice. You must make sure that the attribute of your choice can be fetched for both users and groups and it is unique. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users and groups." => "Από προεπιλογή, το χαρακτηριστικό UUID εντοπίζεται αυτόματα. Το χαρακτηριστικό UUID χρησιμοποιείται για την αναγνώριση χωρίς αμφιβολία χρηστών και ομάδων LDAP. Επίσης, το εσωτερικό όνομα χρήστη θα δημιουργηθεί με βάση το UUID, εφόσον δεν ορίζεται διαφορετικά ανωτέρω. Μπορείτε να παρακάμψετε τη ρύθμιση και να ορίσετε ένα χαρακτηριστικό της επιλογής σας. Θα πρέπει να βεβαιωθείτε ότι το χαρακτηριστικό της επιλογής σας μπορεί να ληφθεί για τους χρήστες και τις ομάδες και ότι είναι μοναδικό. Αφήστε το κενό για την προεπιλεγμένη λειτουργία. Οι αλλαγές θα έχουν ισχύ μόνο σε πρόσφατα αντιστοιχισμένους (προστιθέμενους) χρήστες και ομάδες LDAP.", +"UUID Attribute for Users:" => "Χαρακτηριστικό UUID για Χρήστες:", +"UUID Attribute for Groups:" => "Χαρακτηριστικό UUID για Ομάδες:", +"Username-LDAP User Mapping" => "Αντιστοίχιση Χρηστών Όνομα Χρήστη-LDAP", +"Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have a internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." => "Τα ονόματα χρηστών χρησιμοποιούνται για την αποθήκευση και την ανάθεση (μετα) δεδομένων. Προκειμένου να προσδιοριστούν με ακρίβεια και να αναγνωρίστουν οι χρήστες, κάθε χρήστης LDAP θα έχει ένα εσωτερικό όνομα. Αυτό απαιτεί μια αντιστοίχιση του ονόματος χρήστη με το χρήστη LDAP. Το όνομα χρήστη που δημιουργήθηκε αντιστοιχίζεται στην UUID του χρήστη LDAP. Επιπροσθέτως, το DN αποθηκεύεται προσωρινά (cache) ώστε να μειωθεί η αλληλεπίδραση LDAP, αλλά δεν χρησιμοποιείται για την ταυτοποίηση. Αν το DN αλλάξει, οι αλλαγές θα βρεθούν. Το εσωτερικό όνομα χρήστη χρησιμοποιείται παντού. Η εκκαθάριση των αντιστοιχίσεων θα αφήσει κατάλοιπα παντού. Η εκκαθάριση των αντιστοιχίσεων δεν επηρεάζεται από τη διαμόρφωση, επηρεάζει όλες τις διαμορφώσεις LDAP! Μην διαγράψετε ποτέ τις αντιστοιχίσεις σε ένα λειτουργικό περιβάλλον παρά μόνο σε δοκιμές ή σε πειραματικό στάδιο.", +"Clear Username-LDAP User Mapping" => "Διαγραφή αντιστοίχησης Ονόματος Χρήστη LDAP-Χρήστη", +"Clear Groupname-LDAP Group Mapping" => "Διαγραφή αντιστοίχησης Ονόματος Ομάδας-LDAP Ομάδας" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/en@pirate.php b/apps/user_ldap/l10n/en@pirate.php index e269c57c3d0..35308522f04 100644 --- a/apps/user_ldap/l10n/en@pirate.php +++ b/apps/user_ldap/l10n/en@pirate.php @@ -1,5 +1,7 @@ <?php $TRANSLATIONS = array( +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("",""), "Password" => "Passcode" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/en_GB.php b/apps/user_ldap/l10n/en_GB.php index d613be34868..b83229d5a53 100644 --- a/apps/user_ldap/l10n/en_GB.php +++ b/apps/user_ldap/l10n/en_GB.php @@ -4,7 +4,11 @@ $TRANSLATIONS = array( "Failed to delete the server configuration" => "Failed to delete the server configuration", "The configuration is valid and the connection could be established!" => "The configuration is valid and the connection could be established!", "The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "The configuration is valid, but the Bind failed. Please check the server settings and credentials.", -"The configuration is invalid. Please look in the ownCloud log for further details." => "The configuration is invalid. Please look in the ownCloud log for further details.", +"The configuration is invalid. Please have a look at the logs for further details." => "The configuration is invalid. Please have a look at the logs for further details.", +"No action specified" => "No action specified", +"No configuration specified" => "No configuration specified", +"No data specified" => "No data specified", +" Could not set configuration %s" => " Could not set configuration %s", "Deletion failed" => "Deletion failed", "Take over settings from recent server configuration?" => "Take over settings from recent server configuration?", "Keep settings?" => "Keep settings?", @@ -12,40 +16,60 @@ $TRANSLATIONS = array( "mappings cleared" => "mappings cleared", "Success" => "Success", "Error" => "Error", +"Configuration OK" => "Configuration OK", +"Configuration incorrect" => "Configuration incorrect", +"Configuration incomplete" => "Configuration incomplete", +"Select groups" => "Select groups", +"Select object classes" => "Select object classes", +"Select attributes" => "Select attributes", "Connection test succeeded" => "Connection test succeeded", "Connection test failed" => "Connection test failed", "Do you really want to delete the current Server Configuration?" => "Do you really want to delete the current Server Configuration?", "Confirm Deletion" => "Confirm Deletion", -"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them.", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it.", -"Server configuration" => "Server configuration", +"_%s group found_::_%s groups found_" => array("%s group found","%s groups found"), +"_%s user found_::_%s users found_" => array("%s user found","%s users found"), +"Invalid Host" => "Invalid Host", +"Could not find the desired feature" => "Could not find the desired feature", +"Save" => "Save", +"Test Configuration" => "Test Configuration", +"Help" => "Help", +"Limit the access to %s to groups meeting this criteria:" => "Limit the access to %s to groups meeting this criteria:", +"only those object classes:" => "only those object classes:", +"only from those groups:" => "only from those groups:", +"Edit raw filter instead" => "Edit raw filter instead", +"Raw LDAP filter" => "Raw LDAP filter", +"The filter specifies which LDAP groups shall have access to the %s instance." => "The filter specifies which LDAP groups shall have access to the %s instance.", +"groups found" => "groups found", +"What attribute shall be used as login name:" => "What attribute should be used as login name:", +"LDAP Username:" => "LDAP Username:", +"LDAP Email Address:" => "LDAP Email Address:", +"Other Attributes:" => "Other Attributes:", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"", "Add Server Configuration" => "Add Server Configuration", "Host" => "Host", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "You can omit the protocol, except you require SSL. Then start with ldaps://", -"Base DN" => "Base DN", -"One Base DN per line" => "One Base DN per line", -"You can specify Base DN for users and groups in the Advanced tab" => "You can specify Base DN for users and groups in the Advanced tab", +"Port" => "Port", "User DN" => "User DN", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty.", "Password" => "Password", "For anonymous access, leave DN and Password empty." => "For anonymous access, leave DN and Password empty.", -"User Login Filter" => "User Login Filter", -"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"", -"User List Filter" => "User List Filter", -"Defines the filter to apply, when retrieving users (no placeholders). Example: \"objectClass=person\"" => "Defines the filter to apply, when retrieving users (no placeholders). Example: \"objectClass=person\"", -"Group Filter" => "Group Filter", -"Defines the filter to apply, when retrieving groups (no placeholders). Example: \"objectClass=posixGroup\"" => "Defines the filter to apply, when retrieving groups (no placeholders). Example: \"objectClass=posixGroup\"", +"One Base DN per line" => "One Base DN per line", +"You can specify Base DN for users and groups in the Advanced tab" => "You can specify Base DN for users and groups in the Advanced tab", +"Limit the access to %s to users meeting this criteria:" => "Limit the access to %s to users meeting this criteria:", +"The filter specifies which LDAP users shall have access to the %s instance." => "The filter specifies which LDAP users shall have access to the %s instance.", +"users found" => "users found", +"Back" => "Back", +"Continue" => "Continue", +"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them.", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it.", "Connection Settings" => "Connection Settings", "Configuration Active" => "Configuration Active", "When unchecked, this configuration will be skipped." => "When unchecked, this configuration will be skipped.", -"Port" => "Port", "Backup (Replica) Host" => "Backup (Replica) Host", "Give an optional backup host. It must be a replica of the main LDAP/AD server." => "Give an optional backup host. It must be a replica of the main LDAP/AD server.", "Backup (Replica) Port" => "Backup (Replica) Port", "Disable Main Server" => "Disable Main Server", "Only connect to the replica server." => "Only connect to the replica server.", -"Use TLS" => "Use TLS", -"Do not use it additionally for LDAPS connections, it will fail." => "Do not use it additionally for LDAPS connections, it will fail.", "Case insensitve LDAP server (Windows)" => "Case insensitve LDAP server (Windows)", "Turn off SSL certificate validation." => "Turn off SSL certificate validation.", "Not recommended, use it for testing only! If connection only works with this option, import the LDAP server's SSL certificate in your %s server." => "Not recommended, use it for testing only! If connection only works with this option, import the LDAP server's SSL certificate in your %s server.", @@ -76,12 +100,11 @@ $TRANSLATIONS = array( "Internal Username Attribute:" => "Internal Username Attribute:", "Override UUID detection" => "Override UUID detection", "By default, the UUID attribute is automatically detected. The UUID attribute is used to doubtlessly identify LDAP users and groups. Also, the internal username will be created based on the UUID, if not specified otherwise above. You can override the setting and pass an attribute of your choice. You must make sure that the attribute of your choice can be fetched for both users and groups and it is unique. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users and groups." => "By default, the UUID attribute is automatically detected. The UUID attribute is used to unambiguously identify LDAP users and groups. Also, the internal username will be created based on the UUID, if not specified otherwise above. You can override the setting and pass an attribute of your choice. You must make sure that the attribute of your choice can be fetched for both users and groups and it is unique. Leave it empty for default behaviour. Changes will have effect only on newly mapped (added) LDAP users and groups.", -"UUID Attribute:" => "UUID Attribute:", +"UUID Attribute for Users:" => "UUID Attribute for Users:", +"UUID Attribute for Groups:" => "UUID Attribute for Groups:", "Username-LDAP User Mapping" => "Username-LDAP User Mapping", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have a internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." => "Usernames are used to store and assign (meta) data. In order to precisely identify and recognise users, each LDAP user will have a internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage.", "Clear Username-LDAP User Mapping" => "Clear Username-LDAP User Mapping", -"Clear Groupname-LDAP Group Mapping" => "Clear Groupname-LDAP Group Mapping", -"Test Configuration" => "Test Configuration", -"Help" => "Help" +"Clear Groupname-LDAP Group Mapping" => "Clear Groupname-LDAP Group Mapping" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/eo.php b/apps/user_ldap/l10n/eo.php index 26d46b81b9f..0cae524bcc1 100644 --- a/apps/user_ldap/l10n/eo.php +++ b/apps/user_ldap/l10n/eo.php @@ -1,29 +1,58 @@ <?php $TRANSLATIONS = array( +"Failed to delete the server configuration" => "Malsukcesis forigo de la agordo de servilo", "Deletion failed" => "Forigo malsukcesis", +"Keep settings?" => "Ĉu daŭrigi la agordon?", +"Cannot add server configuration" => "Ne eblas aldoni agordon de servilo", "Success" => "Sukceso", "Error" => "Eraro", +"Select groups" => "Elekti grupojn", +"Select object classes" => "Elekti objektoklasojn", +"Select attributes" => "Elekti atribuojn", +"Connection test succeeded" => "Provo de konekto sukcesis", +"Connection test failed" => "Provo de konekto malsukcesis", +"Confirm Deletion" => "Konfirmi forigon", +"_%s group found_::_%s groups found_" => array("%s grupo troviĝis","%s grupoj troviĝis"), +"_%s user found_::_%s users found_" => array("%s uzanto troviĝis","%s uzanto troviĝis"), +"Invalid Host" => "Nevalida gastigo", +"Save" => "Konservi", +"Test Configuration" => "Provi agordon", +"Help" => "Helpo", +"only those object classes:" => "nur tiuj objektoklasoj:", +"only from those groups:" => "nur el tiuj grupoj:", +"groups found" => "grupoj trovitaj", +"LDAP Username:" => "LDAP-uzantonomo:", +"LDAP Email Address:" => "LDAP-retpoŝtadreso:", +"Other Attributes:" => "Aliaj atribuoj:", +"Add Server Configuration" => "Aldoni agordon de servilo", "Host" => "Gastigo", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Vi povas neglekti la protokolon, escepte se vi bezonas SSL-on. Tiuokaze, komencu per ldaps://", -"Base DN" => "Bazo-DN", +"Port" => "Pordo", "User DN" => "Uzanto-DN", "Password" => "Pasvorto", "For anonymous access, leave DN and Password empty." => "Por sennoman aliron, lasu DN-on kaj Pasvorton malplenaj.", -"User Login Filter" => "Filtrilo de uzantensaluto", -"User List Filter" => "Filtrilo de uzantolisto", -"Group Filter" => "Filtrilo de grupo", -"Port" => "Pordo", -"Use TLS" => "Uzi TLS-on", +"users found" => "uzantoj trovitaj", +"Back" => "Antaŭen", +"Connection Settings" => "Agordo de konekto", +"Disable Main Server" => "Malkapabligi la ĉefan servilon", "Case insensitve LDAP server (Windows)" => "LDAP-servilo blinda je litergrandeco (Vindozo)", "Turn off SSL certificate validation." => "Malkapabligi validkontrolon de SSL-atestiloj.", +"Cache Time-To-Live" => "Vivotempo de la kaŝmemoro", "in seconds. A change empties the cache." => "sekunde. Ajna ŝanĝo malplenigas la kaŝmemoron.", "User Display Name Field" => "Kampo de vidignomo de uzanto", "Base User Tree" => "Baza uzantarbo", "Group Display Name Field" => "Kampo de vidignomo de grupo", "Base Group Tree" => "Baza gruparbo", +"Group Search Attributes" => "Atribuoj de gruposerĉo", "Group-Member association" => "Asocio de grupo kaj membro", +"Special Attributes" => "Specialaj atribuoj", +"Quota Field" => "Kampo de kvoto", "in bytes" => "duumoke", +"Email Field" => "Kampo de retpoŝto", "Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "Lasu malplena por uzantonomo (defaŭlto). Alie, specifu LDAP/AD-atributon.", -"Help" => "Helpo" +"Internal Username" => "Ena uzantonomo", +"Internal Username Attribute:" => "Atribuo de ena uzantonomo:", +"UUID Attribute for Users:" => "UUID-atribuo por uzantoj:", +"UUID Attribute for Groups:" => "UUID-atribuo por grupoj:" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/es.php b/apps/user_ldap/l10n/es.php index 4f37d5177a7..3348003e3e2 100644 --- a/apps/user_ldap/l10n/es.php +++ b/apps/user_ldap/l10n/es.php @@ -4,7 +4,11 @@ $TRANSLATIONS = array( "Failed to delete the server configuration" => "No se pudo borrar la configuración del servidor", "The configuration is valid and the connection could be established!" => "¡La configuración es válida y la conexión puede establecerse!", "The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "La configuración es válida, pero falló el Enlace. Por favor, compruebe la configuración del servidor y las credenciales.", -"The configuration is invalid. Please look in the ownCloud log for further details." => "La configuración no es válida. Por favor, busque en el log de ownCloud para más detalles.", +"The configuration is invalid. Please have a look at the logs for further details." => "La configuración no es válida. Por favor, busque en el log para más detalles.", +"No action specified" => "No se ha especificado la acción", +"No configuration specified" => "No se ha especificado la configuración", +"No data specified" => "No se han especificado los datos", +" Could not set configuration %s" => "No se pudo establecer la configuración %s", "Deletion failed" => "Falló el borrado", "Take over settings from recent server configuration?" => "¿Asumir los ajustes actuales de la configuración del servidor?", "Keep settings?" => "¿Mantener la configuración?", @@ -12,40 +16,60 @@ $TRANSLATIONS = array( "mappings cleared" => "Asignaciones borradas", "Success" => "Éxito", "Error" => "Error", +"Configuration OK" => "Configuración OK", +"Configuration incorrect" => "Configuración Incorrecta", +"Configuration incomplete" => "Configuración incompleta", +"Select groups" => "Seleccionar grupos", +"Select object classes" => "Seleccionar la clase de objeto", +"Select attributes" => "Seleccionar atributos", "Connection test succeeded" => "La prueba de conexión fue exitosa", "Connection test failed" => "La prueba de conexión falló", "Do you really want to delete the current Server Configuration?" => "¿Realmente desea eliminar la configuración actual del servidor?", "Confirm Deletion" => "Confirmar eliminación", -"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Advertencia:</b> Las apps user_ldap y user_webdavauth son incompatibles. Puede que experimente un comportamiento inesperado. Pregunte al su administrador de sistemas para desactivar uno de ellos.", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Advertencia:</b> El módulo LDAP de PHP no está instalado, el sistema no funcionará. Por favor consulte al administrador del sistema para instalarlo.", -"Server configuration" => "Configuración del Servidor", +"_%s group found_::_%s groups found_" => array("Grupo %s encontrado","Grupos %s encontrados"), +"_%s user found_::_%s users found_" => array("Usuario %s encontrado","Usuarios %s encontrados"), +"Invalid Host" => "Host inválido", +"Could not find the desired feature" => "No se puede encontrar la función deseada.", +"Save" => "Guardar", +"Test Configuration" => "Configuración de prueba", +"Help" => "Ayuda", +"Limit the access to %s to groups meeting this criteria:" => "Limitar el acceso a %s a los grupos que cumplan este criterio:", +"only those object classes:" => "solamente de estas clases de objeto:", +"only from those groups:" => "solamente de estos grupos:", +"Edit raw filter instead" => "Editar el filtro en bruto en su lugar", +"Raw LDAP filter" => "Filtro LDAP en bruto", +"The filter specifies which LDAP groups shall have access to the %s instance." => "El filtro especifica que grupos LDAP tendrán acceso a %s.", +"groups found" => "grupos encontrados", +"What attribute shall be used as login name:" => "Que atributo debe ser usado como login:", +"LDAP Username:" => "Nombre de usuario LDAP:", +"LDAP Email Address:" => "Dirección e-mail LDAP:", +"Other Attributes:" => "Otros atributos:", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Define el filtro a aplicar cuando se intenta identificar. %%uid remplazará al nombre de usuario en el proceso de identificación. Por ejemplo: \"uid=%%uid\"", "Add Server Configuration" => "Agregar configuracion del servidor", "Host" => "Servidor", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Puede omitir el protocolo, excepto si requiere SSL. En ese caso, empiece con ldaps://", -"Base DN" => "DN base", -"One Base DN per line" => "Un DN Base por línea", -"You can specify Base DN for users and groups in the Advanced tab" => "Puede especificar el DN base para usuarios y grupos en la pestaña Avanzado", +"Port" => "Puerto", "User DN" => "DN usuario", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "El DN del usuario cliente con el que se hará la asociación, p.ej. uid=agente,dc=ejemplo,dc=com. Para acceso anónimo, deje DN y contraseña vacíos.", "Password" => "Contraseña", "For anonymous access, leave DN and Password empty." => "Para acceso anónimo, deje DN y contraseña vacíos.", -"User Login Filter" => "Filtro de inicio de sesión de usuario", -"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Define el filtro a aplicar cuando se intenta identificar. %%uid remplazará al nombre de usuario en el proceso de identificación. Por ejemplo: \"uid=%%uid\"", -"User List Filter" => "Lista de filtros de usuario", -"Defines the filter to apply, when retrieving users (no placeholders). Example: \"objectClass=person\"" => "Define el filtro a aplicar, cuando se obtienen usuarios (sin comodines). Por ejemplo: \"objectClass=person\"", -"Group Filter" => "Filtro de grupo", -"Defines the filter to apply, when retrieving groups (no placeholders). Example: \"objectClass=posixGroup\"" => "Define el filtro a aplicar, cuando se obtienen grupos (sin comodines). Por ejemplo: \"objectClass=posixGroup\"", +"One Base DN per line" => "Un DN Base por línea", +"You can specify Base DN for users and groups in the Advanced tab" => "Puede especificar el DN base para usuarios y grupos en la pestaña Avanzado", +"Limit the access to %s to users meeting this criteria:" => "Limitar el acceso a %s a los usuarios que cumplan el siguiente criterio:", +"The filter specifies which LDAP users shall have access to the %s instance." => "El filtro especifica que usuarios LDAP pueden tener acceso a %s.", +"users found" => "usuarios encontrados", +"Back" => "Atrás", +"Continue" => "Continuar", +"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Advertencia:</b> Las apps user_ldap y user_webdavauth son incompatibles. Puede que experimente un comportamiento inesperado. Pregunte al su administrador de sistemas para desactivar uno de ellos.", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Advertencia:</b> El módulo LDAP de PHP no está instalado, el sistema no funcionará. Por favor consulte al administrador del sistema para instalarlo.", "Connection Settings" => "Configuración de conexión", "Configuration Active" => "Configuracion activa", "When unchecked, this configuration will be skipped." => "Cuando deseleccione, esta configuracion sera omitida.", -"Port" => "Puerto", "Backup (Replica) Host" => "Servidor de copia de seguridad (Replica)", "Give an optional backup host. It must be a replica of the main LDAP/AD server." => "Dar un servidor de copia de seguridad opcional. Debe ser una réplica del servidor principal LDAP / AD.", "Backup (Replica) Port" => "Puerto para copias de seguridad (Replica)", "Disable Main Server" => "Deshabilitar servidor principal", "Only connect to the replica server." => "Conectar sólo con el servidor de réplica.", -"Use TLS" => "Usar TLS", -"Do not use it additionally for LDAPS connections, it will fail." => "No lo use para conexiones LDAPS, Fallará.", "Case insensitve LDAP server (Windows)" => "Servidor de LDAP no sensible a mayúsculas/minúsculas (Windows)", "Turn off SSL certificate validation." => "Apagar la validación por certificado SSL.", "Not recommended, use it for testing only! If connection only works with this option, import the LDAP server's SSL certificate in your %s server." => "No se recomienda, ¡utilízalo únicamente para pruebas! Si la conexión únicamente funciona con esta opción, importa el certificado SSL del servidor LDAP en tu servidor %s.", @@ -76,12 +100,11 @@ $TRANSLATIONS = array( "Internal Username Attribute:" => "Atributo Nombre de usuario Interno:", "Override UUID detection" => "Sobrescribir la detección UUID", "By default, the UUID attribute is automatically detected. The UUID attribute is used to doubtlessly identify LDAP users and groups. Also, the internal username will be created based on the UUID, if not specified otherwise above. You can override the setting and pass an attribute of your choice. You must make sure that the attribute of your choice can be fetched for both users and groups and it is unique. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users and groups." => "Por defecto, el atributo UUID es autodetectado. Este atributo es usado para identificar indudablemente usuarios y grupos LDAP. Además, el nombre de usuario interno será creado en base al UUID, si no ha sido especificado otro comportamiento arriba. Puedes sobrescribir la configuración y pasar un atributo de tu elección. Debes asegurarte de que el atributo de tu elección sea accesible por los usuarios y grupos y ser único. Déjalo en blanco para usar el comportamiento por defecto. Los cambios tendrán efecto solo en los usuarios y grupos de LDAP mapeados (añadidos) recientemente.", -"UUID Attribute:" => "Atributo UUID:", +"UUID Attribute for Users:" => "Atributo UUID para usuarios:", +"UUID Attribute for Groups:" => "Atributo UUID para Grupos:", "Username-LDAP User Mapping" => "Asignación del Nombre de usuario de un usuario LDAP", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have a internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." => "Los usuarios son usados para almacenar y asignar (meta) datos. Con el fin de identificar de forma precisa y reconocer usuarios, cada usuario de LDAP tendrá un nombre de usuario interno. Esto requiere un mapeo entre el nombre de usuario y el usuario del LDAP. El nombre de usuario creado es mapeado respecto al UUID del usuario en el LDAP. De forma adicional, el DN es cacheado para reducir la interacción entre el LDAP, pero no es usado para identificar. Si el DN cambia, los cambios serán aplicados. El nombre de usuario interno es usado por encima de todo. Limpiar los mapeos dejará restos por todas partes, no es sensible a configuración, ¡afecta a todas las configuraciones del LDAP! Nunca limpies los mapeos en un entorno de producción, únicamente en una fase de desarrollo o experimental.", "Clear Username-LDAP User Mapping" => "Borrar la asignación de los Nombres de usuario de los usuarios LDAP", -"Clear Groupname-LDAP Group Mapping" => "Borrar la asignación de los Nombres de grupo de los grupos de LDAP", -"Test Configuration" => "Configuración de prueba", -"Help" => "Ayuda" +"Clear Groupname-LDAP Group Mapping" => "Borrar la asignación de los Nombres de grupo de los grupos de LDAP" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/es_AR.php b/apps/user_ldap/l10n/es_AR.php index 2436df8de77..3a8f42e2c9c 100644 --- a/apps/user_ldap/l10n/es_AR.php +++ b/apps/user_ldap/l10n/es_AR.php @@ -4,7 +4,6 @@ $TRANSLATIONS = array( "Failed to delete the server configuration" => "Fallo al borrar la configuración del servidor", "The configuration is valid and the connection could be established!" => "La configuración es válida y la conexión pudo ser establecida.", "The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "La configuración es válida, pero el enlace falló. Por favor, comprobá la configuración del servidor y las credenciales.", -"The configuration is invalid. Please look in the ownCloud log for further details." => "La configuración no es válida. Por favor, buscá en el log de ownCloud más detalles.", "Deletion failed" => "Error al borrar", "Take over settings from recent server configuration?" => "Tomar los valores de la anterior configuración de servidor?", "Keep settings?" => "¿Mantener preferencias?", @@ -12,40 +11,38 @@ $TRANSLATIONS = array( "mappings cleared" => "Asignaciones borradas", "Success" => "Éxito", "Error" => "Error", +"Select groups" => "Seleccionar grupos", "Connection test succeeded" => "El este de conexión ha sido completado satisfactoriamente", "Connection test failed" => "Falló es test de conexión", "Do you really want to delete the current Server Configuration?" => "¿Realmente desea borrar la configuración actual del servidor?", "Confirm Deletion" => "Confirmar borrado", -"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Advertencia:</b> Las apps user_ldap y user_webdavauth son incompatibles. Puede ser que experimentes comportamientos inesperados. Pedile al administrador que desactive uno de ellos.", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Atención:</b> El módulo PHP LDAP no está instalado, este elemento no va a funcionar. Por favor, pedile al administrador que lo instale.", -"Server configuration" => "Configuración del Servidor", +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("",""), +"Save" => "Guardar", +"Test Configuration" => "Probar configuración", +"Help" => "Ayuda", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Define el filtro a aplicar cuando se intenta ingresar. %%uid remplaza el nombre de usuario en el proceso de identificación. Por ejemplo: \"uid=%%uid\"", "Add Server Configuration" => "Añadir Configuración del Servidor", "Host" => "Servidor", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Podés omitir el protocolo, excepto si SSL es requerido. En ese caso, empezá con ldaps://", -"Base DN" => "DN base", -"One Base DN per line" => "Una DN base por línea", -"You can specify Base DN for users and groups in the Advanced tab" => "Podés especificar el DN base para usuarios y grupos en la pestaña \"Avanzado\"", +"Port" => "Puerto", "User DN" => "DN usuario", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "El DN del usuario cliente con el que se hará la asociación, p.ej. uid=agente,dc=ejemplo,dc=com. Para acceso anónimo, dejá DN y contraseña vacíos.", "Password" => "Contraseña", "For anonymous access, leave DN and Password empty." => "Para acceso anónimo, dejá DN y contraseña vacíos.", -"User Login Filter" => "Filtro de inicio de sesión de usuario", -"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Define el filtro a aplicar cuando se intenta ingresar. %%uid remplaza el nombre de usuario en el proceso de identificación. Por ejemplo: \"uid=%%uid\"", -"User List Filter" => "Lista de filtros de usuario", -"Defines the filter to apply, when retrieving users (no placeholders). Example: \"objectClass=person\"" => "Define el filtro a aplicar al obtener usuarios (sin comodines). Por ejemplo: \"objectClass=person\"", -"Group Filter" => "Filtro de grupo", -"Defines the filter to apply, when retrieving groups (no placeholders). Example: \"objectClass=posixGroup\"" => "Define el filtro a aplicar al obtener grupos (sin comodines). Por ejemplo: \"objectClass=posixGroup\"", +"One Base DN per line" => "Una DN base por línea", +"You can specify Base DN for users and groups in the Advanced tab" => "Podés especificar el DN base para usuarios y grupos en la pestaña \"Avanzado\"", +"Back" => "Volver", +"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Advertencia:</b> Las apps user_ldap y user_webdavauth son incompatibles. Puede ser que experimentes comportamientos inesperados. Pedile al administrador que desactive uno de ellos.", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Atención:</b> El módulo PHP LDAP no está instalado, este elemento no va a funcionar. Por favor, pedile al administrador que lo instale.", "Connection Settings" => "Configuración de Conección", "Configuration Active" => "Configuración activa", "When unchecked, this configuration will be skipped." => "Si no está seleccionada, esta configuración será omitida.", -"Port" => "Puerto", "Backup (Replica) Host" => "Host para copia de seguridad (réplica)", "Give an optional backup host. It must be a replica of the main LDAP/AD server." => "Dar un servidor de copia de seguridad opcional. Debe ser una réplica del servidor principal LDAP/AD.", "Backup (Replica) Port" => "Puerto para copia de seguridad (réplica)", "Disable Main Server" => "Deshabilitar el Servidor Principal", "Only connect to the replica server." => "Conectarse únicamente al servidor de réplica.", -"Use TLS" => "Usar TLS", -"Do not use it additionally for LDAPS connections, it will fail." => "No usar adicionalmente para conexiones LDAPS, las mismas fallarán", "Case insensitve LDAP server (Windows)" => "Servidor de LDAP sensible a mayúsculas/minúsculas (Windows)", "Turn off SSL certificate validation." => "Desactivar la validación por certificado SSL.", "Not recommended, use it for testing only! If connection only works with this option, import the LDAP server's SSL certificate in your %s server." => "No es recomendado, ¡Usalo solamente para pruebas! Si la conexión únicamente funciona con esta opción, importá el certificado SSL del servidor LDAP en tu servidor %s.", @@ -76,12 +73,11 @@ $TRANSLATIONS = array( "Internal Username Attribute:" => "Atributo Nombre Interno de usuario:", "Override UUID detection" => "Sobrescribir la detección UUID", "By default, the UUID attribute is automatically detected. The UUID attribute is used to doubtlessly identify LDAP users and groups. Also, the internal username will be created based on the UUID, if not specified otherwise above. You can override the setting and pass an attribute of your choice. You must make sure that the attribute of your choice can be fetched for both users and groups and it is unique. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users and groups." => "Por defecto, el atributo UUID es detectado automáticamente. Este atributo es usado para identificar de manera certera usuarios y grupos LDAP. Además, el nombre de usuario interno será creado en base al UUID, si no fue especificado otro comportamiento más arriba. Podés sobrescribir la configuración y pasar un atributo de tu elección. Tenés que asegurarte que el atributo de tu elección sea accesible por los usuarios y grupos y que sea único. Dejalo en blanco para usar el comportamiento por defecto. Los cambios tendrán efecto sólo en los nuevos usuarios y grupos de LDAP mapeados (agregados).", -"UUID Attribute:" => "Atributo UUID:", +"UUID Attribute for Users:" => "Atributo UUID para usuarios:", +"UUID Attribute for Groups:" => "Atributo UUID para grupos:", "Username-LDAP User Mapping" => "Asignación del Nombre de usuario de un usuario LDAP", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have a internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." => "Los usuarios son usados para almacenar y asignar datos (metadatos). Con el fin de identificar de forma precisa y reconocer usuarios, a cada usuario de LDAP se será asignado un nombre de usuario interno. Esto requiere un mapeo entre el nombre de usuario y el usuario del LDAP. El nombre de usuario creado es mapeado respecto al UUID del usuario en el LDAP. De forma adicional, el DN es dejado en caché para reducir la interacción entre el LDAP, pero no es usado para la identificación. Si el DN cambia, los cambios van a ser aplicados. El nombre de usuario interno es usado en todos los lugares. Vaciar los mapeos, deja restos por todas partes. Vaciar los mapeos, no es sensible a configuración, ¡afecta a todas las configuraciones del LDAP! Nunca limpies los mapeos en un entorno de producción, solamente en fase de desarrollo o experimental.", "Clear Username-LDAP User Mapping" => "Borrar la asignación de los Nombres de usuario de los usuarios LDAP", -"Clear Groupname-LDAP Group Mapping" => "Borrar la asignación de los Nombres de grupo de los grupos de LDAP", -"Test Configuration" => "Probar configuración", -"Help" => "Ayuda" +"Clear Groupname-LDAP Group Mapping" => "Borrar la asignación de los Nombres de grupo de los grupos de LDAP" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/es_CL.php b/apps/user_ldap/l10n/es_CL.php new file mode 100644 index 00000000000..b3522617b42 --- /dev/null +++ b/apps/user_ldap/l10n/es_CL.php @@ -0,0 +1,7 @@ +<?php +$TRANSLATIONS = array( +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("",""), +"Password" => "Clave" +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/es_MX.php b/apps/user_ldap/l10n/es_MX.php new file mode 100644 index 00000000000..16aaa91fd51 --- /dev/null +++ b/apps/user_ldap/l10n/es_MX.php @@ -0,0 +1,110 @@ +<?php +$TRANSLATIONS = array( +"Failed to clear the mappings." => "Ocurrió un fallo al borrar las asignaciones.", +"Failed to delete the server configuration" => "No se pudo borrar la configuración del servidor", +"The configuration is valid and the connection could be established!" => "¡La configuración es válida y la conexión puede establecerse!", +"The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "La configuración es válida, pero falló el Enlace. Por favor, compruebe la configuración del servidor y las credenciales.", +"The configuration is invalid. Please have a look at the logs for further details." => "La configuración no es válida. Por favor, busque en el log para más detalles.", +"No action specified" => "No se ha especificado la acción", +"No configuration specified" => "No se ha especificado la configuración", +"No data specified" => "No se han especificado los datos", +" Could not set configuration %s" => "No se pudo establecer la configuración %s", +"Deletion failed" => "Falló el borrado", +"Take over settings from recent server configuration?" => "¿Asumir los ajustes actuales de la configuración del servidor?", +"Keep settings?" => "¿Mantener la configuración?", +"Cannot add server configuration" => "No se puede añadir la configuración del servidor", +"mappings cleared" => "Asignaciones borradas", +"Success" => "Éxito", +"Error" => "Error", +"Configuration OK" => "Configuración OK", +"Configuration incorrect" => "Configuración Incorrecta", +"Configuration incomplete" => "Configuración incompleta", +"Select groups" => "Seleccionar grupos", +"Select object classes" => "Seleccionar la clase de objeto", +"Select attributes" => "Seleccionar atributos", +"Connection test succeeded" => "La prueba de conexión fue exitosa", +"Connection test failed" => "La prueba de conexión falló", +"Do you really want to delete the current Server Configuration?" => "¿Realmente desea eliminar la configuración actual del servidor?", +"Confirm Deletion" => "Confirmar eliminación", +"_%s group found_::_%s groups found_" => array("Grupo %s encontrado","Grupos %s encontrados"), +"_%s user found_::_%s users found_" => array("Usuario %s encontrado","Usuarios %s encontrados"), +"Invalid Host" => "Host inválido", +"Could not find the desired feature" => "No se puede encontrar la función deseada.", +"Save" => "Guardar", +"Test Configuration" => "Configuración de prueba", +"Help" => "Ayuda", +"Limit the access to %s to groups meeting this criteria:" => "Limitar el acceso a %s a los grupos que cumplan este criterio:", +"only those object classes:" => "solamente de estas clases de objeto:", +"only from those groups:" => "solamente de estos grupos:", +"Edit raw filter instead" => "Editar el filtro en bruto en su lugar", +"Raw LDAP filter" => "Filtro LDAP en bruto", +"The filter specifies which LDAP groups shall have access to the %s instance." => "El filtro especifica que grupos LDAP tendrán acceso a %s.", +"groups found" => "grupos encontrados", +"What attribute shall be used as login name:" => "Que atributo debe ser usado como login:", +"LDAP Username:" => "Nombre de usuario LDAP:", +"LDAP Email Address:" => "Dirección e-mail LDAP:", +"Other Attributes:" => "Otros atributos:", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Define el filtro a aplicar cuando se intenta identificar. %%uid remplazará al nombre de usuario en el proceso de identificación. Por ejemplo: \"uid=%%uid\"", +"Add Server Configuration" => "Agregar configuracion del servidor", +"Host" => "Servidor", +"You can omit the protocol, except you require SSL. Then start with ldaps://" => "Puede omitir el protocolo, excepto si requiere SSL. En ese caso, empiece con ldaps://", +"Port" => "Puerto", +"User DN" => "DN usuario", +"The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "El DN del usuario cliente con el que se hará la asociación, p.ej. uid=agente,dc=ejemplo,dc=com. Para acceso anónimo, deje DN y contraseña vacíos.", +"Password" => "Contraseña", +"For anonymous access, leave DN and Password empty." => "Para acceso anónimo, deje DN y contraseña vacíos.", +"One Base DN per line" => "Un DN Base por línea", +"You can specify Base DN for users and groups in the Advanced tab" => "Puede especificar el DN base para usuarios y grupos en la pestaña Avanzado", +"Limit the access to %s to users meeting this criteria:" => "Limitar el acceso a %s a los usuarios que cumplan el siguiente criterio:", +"The filter specifies which LDAP users shall have access to the %s instance." => "El filtro especifica que usuarios LDAP pueden tener acceso a %s.", +"users found" => "usuarios encontrados", +"Back" => "Atrás", +"Continue" => "Continuar", +"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Advertencia:</b> Las apps user_ldap y user_webdavauth son incompatibles. Puede que experimente un comportamiento inesperado. Pregunte al su administrador de sistemas para desactivar uno de ellos.", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Advertencia:</b> El módulo LDAP de PHP no está instalado, el sistema no funcionará. Por favor consulte al administrador del sistema para instalarlo.", +"Connection Settings" => "Configuración de conexión", +"Configuration Active" => "Configuracion activa", +"When unchecked, this configuration will be skipped." => "Cuando deseleccione, esta configuracion sera omitida.", +"Backup (Replica) Host" => "Servidor de copia de seguridad (Replica)", +"Give an optional backup host. It must be a replica of the main LDAP/AD server." => "Dar un servidor de copia de seguridad opcional. Debe ser una réplica del servidor principal LDAP / AD.", +"Backup (Replica) Port" => "Puerto para copias de seguridad (Replica)", +"Disable Main Server" => "Deshabilitar servidor principal", +"Only connect to the replica server." => "Conectar sólo con el servidor de réplica.", +"Case insensitve LDAP server (Windows)" => "Servidor de LDAP no sensible a mayúsculas/minúsculas (Windows)", +"Turn off SSL certificate validation." => "Apagar la validación por certificado SSL.", +"Not recommended, use it for testing only! If connection only works with this option, import the LDAP server's SSL certificate in your %s server." => "No se recomienda, ¡utilízalo únicamente para pruebas! Si la conexión únicamente funciona con esta opción, importa el certificado SSL del servidor LDAP en tu servidor %s.", +"Cache Time-To-Live" => "Cache TTL", +"in seconds. A change empties the cache." => "en segundos. Un cambio vacía la caché.", +"Directory Settings" => "Configuración de directorio", +"User Display Name Field" => "Campo de nombre de usuario a mostrar", +"The LDAP attribute to use to generate the user's display name." => "El campo LDAP a usar para generar el nombre para mostrar del usuario.", +"Base User Tree" => "Árbol base de usuario", +"One User Base DN per line" => "Un DN Base de Usuario por línea", +"User Search Attributes" => "Atributos de la busqueda de usuario", +"Optional; one attribute per line" => "Opcional; un atributo por linea", +"Group Display Name Field" => "Campo de nombre de grupo a mostrar", +"The LDAP attribute to use to generate the groups's display name." => "El campo LDAP a usar para generar el nombre para mostrar del grupo.", +"Base Group Tree" => "Árbol base de grupo", +"One Group Base DN per line" => "Un DN Base de Grupo por línea", +"Group Search Attributes" => "Atributos de busqueda de grupo", +"Group-Member association" => "Asociación Grupo-Miembro", +"Special Attributes" => "Atributos especiales", +"Quota Field" => "Cuota", +"Quota Default" => "Cuota por defecto", +"in bytes" => "en bytes", +"Email Field" => "E-mail", +"User Home Folder Naming Rule" => "Regla para la carpeta Home de usuario", +"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "Vacío para el nombre de usuario (por defecto). En otro caso, especifique un atributo LDAP/AD.", +"Internal Username" => "Nombre de usuario interno", +"By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. To achieve a similar behavior as before ownCloud 5 enter the user display name attribute in the following field. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users." => "El nombre de usuario interno será creado de forma predeterminada desde el atributo UUID. Esto asegura que el nombre de usuario es único y los caracteres no necesitan ser convertidos. En el nombre de usuario interno sólo se pueden usar estos caracteres: [ a-zA-Z0-9_.@- ]. El resto de caracteres son sustituidos por su correspondiente en ASCII o simplemente omitidos. En caso de duplicidades, se añadirá o incrementará un número. El nombre de usuario interno es usado para identificar un usuario. Es también el nombre predeterminado para la carpeta personal del usuario en ownCloud. También es parte de URLs remotas, por ejemplo, para todos los servicios *DAV. Con esta configuración el comportamiento predeterminado puede ser cambiado. Para conseguir un comportamiento similar a como era antes de ownCloud 5, introduzca el campo del nombre para mostrar del usuario en la siguiente caja. Déjelo vacío para el comportamiento predeterminado. Los cambios solo tendrán efecto en los usuarios LDAP mapeados (añadidos) recientemente.", +"Internal Username Attribute:" => "Atributo Nombre de usuario Interno:", +"Override UUID detection" => "Sobrescribir la detección UUID", +"By default, the UUID attribute is automatically detected. The UUID attribute is used to doubtlessly identify LDAP users and groups. Also, the internal username will be created based on the UUID, if not specified otherwise above. You can override the setting and pass an attribute of your choice. You must make sure that the attribute of your choice can be fetched for both users and groups and it is unique. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users and groups." => "Por defecto, el atributo UUID es autodetectado. Este atributo es usado para identificar indudablemente usuarios y grupos LDAP. Además, el nombre de usuario interno será creado en base al UUID, si no ha sido especificado otro comportamiento arriba. Puedes sobrescribir la configuración y pasar un atributo de tu elección. Debes asegurarte de que el atributo de tu elección sea accesible por los usuarios y grupos y ser único. Déjalo en blanco para usar el comportamiento por defecto. Los cambios tendrán efecto solo en los usuarios y grupos de LDAP mapeados (añadidos) recientemente.", +"UUID Attribute for Users:" => "Atributo UUID para usuarios:", +"UUID Attribute for Groups:" => "Atributo UUID para Grupos:", +"Username-LDAP User Mapping" => "Asignación del Nombre de usuario de un usuario LDAP", +"Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have a internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." => "Los usuarios son usados para almacenar y asignar (meta) datos. Con el fin de identificar de forma precisa y reconocer usuarios, cada usuario de LDAP tendrá un nombre de usuario interno. Esto requiere un mapeo entre el nombre de usuario y el usuario del LDAP. El nombre de usuario creado es mapeado respecto al UUID del usuario en el LDAP. De forma adicional, el DN es cacheado para reducir la interacción entre el LDAP, pero no es usado para identificar. Si el DN cambia, los cambios serán aplicados. El nombre de usuario interno es usado por encima de todo. Limpiar los mapeos dejará restos por todas partes, no es sensible a configuración, ¡afecta a todas las configuraciones del LDAP! Nunca limpies los mapeos en un entorno de producción, únicamente en una fase de desarrollo o experimental.", +"Clear Username-LDAP User Mapping" => "Borrar la asignación de los Nombres de usuario de los usuarios LDAP", +"Clear Groupname-LDAP Group Mapping" => "Borrar la asignación de los Nombres de grupo de los grupos de LDAP" +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/et_EE.php b/apps/user_ldap/l10n/et_EE.php index b949fe02041..10f513c8b80 100644 --- a/apps/user_ldap/l10n/et_EE.php +++ b/apps/user_ldap/l10n/et_EE.php @@ -4,7 +4,11 @@ $TRANSLATIONS = array( "Failed to delete the server configuration" => "Serveri seadistuse kustutamine ebaõnnestus", "The configuration is valid and the connection could be established!" => "Seadistus on korrektne ning ühendus on olemas!", "The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "Seadistus on korrektne, kuid ühendus ebaõnnestus. Palun kontrolli serveri seadeid ja ühenduseks kasutatavaid kasutajatunnuseid.", -"The configuration is invalid. Please look in the ownCloud log for further details." => "Seadistus on vigane. Palun vaata ownCloud logist täpsemalt.", +"The configuration is invalid. Please have a look at the logs for further details." => "Seadistus on vigane. Lisainfot vaata palun logidest.", +"No action specified" => "Tegevusi pole määratletud", +"No configuration specified" => "Seadistust pole määratletud", +"No data specified" => "Andmeid pole määratletud", +" Could not set configuration %s" => "Ei suutnud seadistada %s", "Deletion failed" => "Kustutamine ebaõnnestus", "Take over settings from recent server configuration?" => "Võta sätted viimasest serveri seadistusest?", "Keep settings?" => "Säilitada seadistused?", @@ -12,50 +16,70 @@ $TRANSLATIONS = array( "mappings cleared" => "vastendused puhastatud", "Success" => "Korras", "Error" => "Viga", +"Configuration OK" => "Seadistus on korras", +"Configuration incorrect" => "Seadistus on vigane", +"Configuration incomplete" => "Seadistus on puudulik", +"Select groups" => "Vali grupid", +"Select object classes" => "Vali objekti klassid", +"Select attributes" => "Vali atribuudid", "Connection test succeeded" => "Ühenduse testimine õnnestus", "Connection test failed" => "Ühenduse testimine ebaõnnestus", "Do you really want to delete the current Server Configuration?" => "Oled kindel, et tahad kustutada praegust serveri seadistust?", "Confirm Deletion" => "Kinnita kustutamine", -"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Hoiatus:</b> rakendused user_ldap ja user_webdavauht ei ole ühilduvad. Töös võib esineda ootamatuid tõrkeid.\nPalu oma süsteemihalduril üks neist rakendustest kasutusest eemaldada.", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Hoiatus:</b>PHP LDAP moodul pole paigaldatud ning LDAP kasutamine ei ole võimalik. Palu oma süsteeihaldurit see paigaldada.", -"Server configuration" => "Serveri seadistus", +"_%s group found_::_%s groups found_" => array("%s grupp leitud","%s gruppi leitud"), +"_%s user found_::_%s users found_" => array("%s kasutaja leitud","%s kasutajat leitud"), +"Invalid Host" => "Vigane server", +"Could not find the desired feature" => "Ei suuda leida soovitud funktsioonaalsust", +"Save" => "Salvesta", +"Test Configuration" => "Testi seadistust", +"Help" => "Abiinfo", +"Limit the access to %s to groups meeting this criteria:" => "Piira ligipääs %s grupile, mis sobivad kriteeriumiga:", +"only those object classes:" => "ainult need objektiklassid:", +"only from those groups:" => "ainult nendest gruppidest:", +"Edit raw filter instead" => "Selle asemel muuda filtrit", +"Raw LDAP filter" => "LDAP filter", +"The filter specifies which LDAP groups shall have access to the %s instance." => "Filter määrab millised LDAP grupid saavad ligipääsu sellele %s instantsile.", +"groups found" => "gruppi leitud", +"What attribute shall be used as login name:" => "Mis atribuuti kasutada sisselogimise kasutajatunnusena:", +"LDAP Username:" => "LDAP kasutajanimi:", +"LDAP Email Address:" => "LDAP e-posti aadress:", +"Other Attributes:" => "Muud atribuudid:", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Määrab sisselogimisel kasutatava filtri. %%uid asendab sisselogimistegevuses kasutajanime. Näide: \"uid=%%uid\"", "Add Server Configuration" => "Lisa serveri seadistus", "Host" => "Host", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Sa ei saa protokolli ära jätta, välja arvatud siis, kui sa nõuad SSL-ühendust. Sel juhul alusta eesliitega ldaps://", -"Base DN" => "Baas DN", -"One Base DN per line" => "Üks baas-DN rea kohta", -"You can specify Base DN for users and groups in the Advanced tab" => "Sa saad kasutajate ja gruppide baas DN-i määrata lisavalikute vahekaardilt", +"Port" => "Port", "User DN" => "Kasutaja DN", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "Klientkasutaja DN, kellega seotakse, nt. uid=agent,dc=näidis,dc=com. Anonüümseks ligipääsuks jäta DN ja parool tühjaks.", "Password" => "Parool", "For anonymous access, leave DN and Password empty." => "Anonüümseks ligipääsuks jäta DN ja parool tühjaks.", -"User Login Filter" => "Kasutajanime filter", -"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Määrab sisselogimisel kasutatava filtri. %%uid asendab sisselogimistegevuses kasutajanime. Näide: \"uid=%%uid\"", -"User List Filter" => "Kasutajate nimekirja filter", -"Defines the filter to apply, when retrieving users (no placeholders). Example: \"objectClass=person\"" => "Määrab kasutajate leidmiseks kasutatava filtri (ilma muutujateta). Näide: \"objectClass=person\"", -"Group Filter" => "Grupi filter", -"Defines the filter to apply, when retrieving groups (no placeholders). Example: \"objectClass=posixGroup\"" => "Määrab gruppide leidmiseks kasutatava filtri (ilma muutujateta). Näide: \"objectClass=posixGroup\"", +"One Base DN per line" => "Üks baas-DN rea kohta", +"You can specify Base DN for users and groups in the Advanced tab" => "Sa saad kasutajate ja gruppide baas DN-i määrata lisavalikute vahekaardilt", +"Limit the access to %s to users meeting this criteria:" => "Piira ligipääs %s kasutajale, kes sobivad kriteeriumiga:", +"The filter specifies which LDAP users shall have access to the %s instance." => "Filter määrab millised LDAP kasutajad pääsevad ligi %s instantsile.", +"users found" => "kasutajat leitud", +"Back" => "Tagasi", +"Continue" => "Jätka", +"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Hoiatus:</b> rakendused user_ldap ja user_webdavauht ei ole ühilduvad. Töös võib esineda ootamatuid tõrkeid.\nPalu oma süsteemihalduril üks neist rakendustest kasutusest eemaldada.", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Hoiatus:</b>PHP LDAP moodul pole paigaldatud ning LDAP kasutamine ei ole võimalik. Palu oma süsteeihaldurit see paigaldada.", "Connection Settings" => "Ühenduse seaded", "Configuration Active" => "Seadistus aktiivne", -"When unchecked, this configuration will be skipped." => "Kui märkimata, siis seadistust ei kasutata", -"Port" => "Port", +"When unchecked, this configuration will be skipped." => "Kui on märkimata, siis seadistust ei kasutata.", "Backup (Replica) Host" => "Varuserver", -"Give an optional backup host. It must be a replica of the main LDAP/AD server." => "Lisa täiendav LDAP/AD server, mida replikeeritakse peaserveriga.", +"Give an optional backup host. It must be a replica of the main LDAP/AD server." => "Lisa valikuline varuserver. See peab olema koopia peamisest LDAP/AD serverist.", "Backup (Replica) Port" => "Varuserveri (replika) port", "Disable Main Server" => "Ära kasuta peaserverit", "Only connect to the replica server." => "Ühendu ainult replitseeriva serveriga.", -"Use TLS" => "Kasuta TLS-i", -"Do not use it additionally for LDAPS connections, it will fail." => "LDAPS puhul ära kasuta. Ühendus ei toimi.", "Case insensitve LDAP server (Windows)" => "Mittetõstutundlik LDAP server (Windows)", "Turn off SSL certificate validation." => "Lülita SSL sertifikaadi kontrollimine välja.", "Not recommended, use it for testing only! If connection only works with this option, import the LDAP server's SSL certificate in your %s server." => "Pole soovitatav, kasuta seda ainult testimiseks! Kui ühendus toimib ainult selle valikuga, siis impordi LDAP serveri SSL sertifikaat oma %s serverisse.", "Cache Time-To-Live" => "Puhvri iga", "in seconds. A change empties the cache." => "sekundites. Muudatus tühjendab vahemälu.", -"Directory Settings" => "Kataloogi seaded", +"Directory Settings" => "Kausta seaded", "User Display Name Field" => "Kasutaja näidatava nime väli", "The LDAP attribute to use to generate the user's display name." => "LDAP atribuut, mida kasutatakse kasutaja kuvatava nime loomiseks.", "Base User Tree" => "Baaskasutaja puu", -"One User Base DN per line" => "Üks kasutajate baas-DN rea kohta", +"One User Base DN per line" => "Üks kasutaja baas-DN rea kohta", "User Search Attributes" => "Kasutaja otsingu atribuudid", "Optional; one attribute per line" => "Valikuline; üks atribuut rea kohta", "Group Display Name Field" => "Grupi näidatava nime väli", @@ -68,7 +92,7 @@ $TRANSLATIONS = array( "Quota Field" => "Mahupiirangu atribuut", "Quota Default" => "Vaikimisi mahupiirang", "in bytes" => "baitides", -"Email Field" => "Email atribuut", +"Email Field" => "E-posti väli", "User Home Folder Naming Rule" => "Kasutaja kodukataloogi nimetamise reegel", "Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "Kasutajanime (vaikeväärtus) kasutamiseks jäta tühjaks. Vastasel juhul määra LDAP/AD omadus.", "Internal Username" => "Sisemine kasutajanimi", @@ -76,12 +100,11 @@ $TRANSLATIONS = array( "Internal Username Attribute:" => "Sisemise kasutajatunnuse atribuut:", "Override UUID detection" => "Tühista UUID tuvastus", "By default, the UUID attribute is automatically detected. The UUID attribute is used to doubtlessly identify LDAP users and groups. Also, the internal username will be created based on the UUID, if not specified otherwise above. You can override the setting and pass an attribute of your choice. You must make sure that the attribute of your choice can be fetched for both users and groups and it is unique. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users and groups." => "Vaikimis ownCloud tuvastab automaatselt UUID atribuudi. UUID atribuuti kasutatakse LDAP kasutajate ja gruppide kindlaks tuvastamiseks. Samuti tekitatakse sisemine kasutajanimi UUID alusel, kui pole määratud teisiti. Sa saad tühistada selle seadistuse ning määrata atribuudi omal valikul. Pead veenduma, et valitud atribuut toimib nii kasutajate kui gruppide puhul ning on unikaalne. Vaikimisi seadistuseks jäta tühjaks. Muudatused mõjutavad ainult uusi (lisatud) LDAP kasutajate vastendusi.", -"UUID Attribute:" => "UUID atribuut:", +"UUID Attribute for Users:" => "UUID atribuut kasutajatele:", +"UUID Attribute for Groups:" => "UUID atribuut gruppidele:", "Username-LDAP User Mapping" => "LDAP-Kasutajatunnus Kasutaja Vastendus", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have a internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." => "ownCloud kasutab kasutajanime talletamaks ja omistamaks (pseudo) andmeid. Et täpselt tuvastada ja määratleda kasutajaid, peab iga LDAP kasutaja omama sisemist kasutajatunnust. See vajab ownCloud kasutajatunnuse vastendust LDAP kasutajaks. Tekitatud kasutajanimi vastendatakse LDAP kasutaja UUID-iks. Lisaks puhverdatakse DN vähendamaks LDAP päringuid, kuid seda ei kasutata tuvastamisel. ownCloud suudab tuvastada ka DN muutumise. ownCloud sisemist kasutajatunnust kasutatakse üle kogu ownCloudi. Eemaldates vastenduse tekivad kõikjal andmejäägid. Vastenduste eemaldamine ei ole konfiguratsiooni tundlik, see mõjutab kõiki LDAP seadistusi! Ära kunagi eemalda vastendusi produktsioonis! Seda võid teha ainult testis või katsetuste masinas.", "Clear Username-LDAP User Mapping" => "Puhasta LDAP-Kasutajatunnus Kasutaja Vastendus", -"Clear Groupname-LDAP Group Mapping" => "Puhasta LDAP-Grupinimi Grupp Vastendus", -"Test Configuration" => "Testi seadistust", -"Help" => "Abiinfo" +"Clear Groupname-LDAP Group Mapping" => "Puhasta LDAP-Grupinimi Grupp Vastendus" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/eu.php b/apps/user_ldap/l10n/eu.php index 664d4901947..1026e017159 100644 --- a/apps/user_ldap/l10n/eu.php +++ b/apps/user_ldap/l10n/eu.php @@ -3,53 +3,80 @@ $TRANSLATIONS = array( "Failed to delete the server configuration" => "Zerbitzariaren konfigurazioa ezabatzeak huts egin du", "The configuration is valid and the connection could be established!" => "Konfigurazioa egokia da eta konexioa ezarri daiteke!", "The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "Konfigurazioa ongi dago, baina Bind-ek huts egin du. Mesedez egiaztatu zerbitzariaren ezarpenak eta kredentzialak.", -"The configuration is invalid. Please look in the ownCloud log for further details." => "Konfigurazioa ez dago ongi. Mesedez ikusi ownCloud-en egunerokoa informazio gehiago eskuratzeko.", +"The configuration is invalid. Please have a look at the logs for further details." => "Konfigurazioa ez dago ongi. Mesedez ikusi egunerokoak (log) informazio gehiago eskuratzeko.", +"No action specified" => "Ez da ekintzarik zehaztu", +"No configuration specified" => "Ez da konfiguraziorik zehaztu", +"No data specified" => "Ez da daturik zehaztu", +" Could not set configuration %s" => "Ezin izan da %s konfigurazioa ezarri", "Deletion failed" => "Ezabaketak huts egin du", "Take over settings from recent server configuration?" => "oraintsuko zerbitzariaren konfigurazioaren ezarpenen ardura hartu?", "Keep settings?" => "Mantendu ezarpenak?", "Cannot add server configuration" => "Ezin da zerbitzariaren konfigurazioa gehitu", "Success" => "Arrakasta", "Error" => "Errorea", +"Configuration OK" => "Konfigurazioa ongi dago", +"Configuration incorrect" => "Konfigurazioa ez dago ongi", +"Configuration incomplete" => "Konfigurazioa osatu gabe dago", +"Select groups" => "Hautatu taldeak", +"Select object classes" => "Hautatu objektu klaseak", +"Select attributes" => "Hautatu atributuak", "Connection test succeeded" => "Konexio froga ongi burutu da", "Connection test failed" => "Konexio frogak huts egin du", "Do you really want to delete the current Server Configuration?" => "Ziur zaude Zerbitzariaren Konfigurazioa ezabatu nahi duzula?", "Confirm Deletion" => "Baieztatu Ezabatzea", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Abisua:</b> PHPk behar duen LDAP modulua ez dago instalaturik, motorrak ez du funtzionatuko. Mesedez eskatu zure sistema kudeatzaileari instala dezan.", -"Server configuration" => "Zerbitzariaren konfigurazioa", +"_%s group found_::_%s groups found_" => array("Talde %s aurkitu da","%s talde aurkitu dira"), +"_%s user found_::_%s users found_" => array("Erabiltzaile %s aurkitu da","%s erabiltzaile aurkitu dira"), +"Invalid Host" => "Baliogabeko hostalaria", +"Could not find the desired feature" => "Ezin izan da nahi zen ezaugarria aurkitu", +"Save" => "Gorde", +"Test Configuration" => "Egiaztatu Konfigurazioa", +"Help" => "Laguntza", +"Limit the access to %s to groups meeting this criteria:" => "Mugatu sarrera baldintza hauek betetzen dituzten %s taldetara:", +"only those object classes:" => "bakarrik objektu klase hauetakoak:", +"only from those groups:" => "bakarrik talde hauetakoak:", +"The filter specifies which LDAP groups shall have access to the %s instance." => "Iragazkiak zehazten du ze LDAP taldek izango duten sarrera %s instantziara:", +"groups found" => "talde aurkituta", +"What attribute shall be used as login name:" => "Sarrera izen gisa erabiliko den atributua:", +"LDAP Username:" => "LDAP Erabiltzaile izena:", +"LDAP Email Address:" => "LDAP Eposta helbidea:", +"Other Attributes:" => "Bestelako atributuak:", "Add Server Configuration" => "Gehitu Zerbitzariaren Konfigurazioa", "Host" => "Hostalaria", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Protokoloa ez da beharrezkoa, SSL behar baldin ez baduzu. Honela bada hasi ldaps://", -"Base DN" => "Oinarrizko DN", -"One Base DN per line" => "DN Oinarri bat lerroko", -"You can specify Base DN for users and groups in the Advanced tab" => "Erabiltzaile eta taldeentzako Oinarrizko DN zehaztu dezakezu Aurreratu fitxan", +"Port" => "Portua", "User DN" => "Erabiltzaile DN", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "Lotura egingo den bezero erabiltzailearen DNa, adb. uid=agent,dc=example,dc=com. Sarrera anonimoak gaitzeko utzi DN eta Pasahitza hutsik.", "Password" => "Pasahitza", "For anonymous access, leave DN and Password empty." => "Sarrera anonimoak gaitzeko utzi DN eta Pasahitza hutsik.", -"User Login Filter" => "Erabiltzaileen saioa hasteko iragazkia", -"User List Filter" => "Erabiltzaile zerrendaren Iragazkia", -"Group Filter" => "Taldeen iragazkia", +"One Base DN per line" => "DN Oinarri bat lerroko", +"You can specify Base DN for users and groups in the Advanced tab" => "Erabiltzaile eta taldeentzako Oinarrizko DN zehaztu dezakezu Aurreratu fitxan", +"Limit the access to %s to users meeting this criteria:" => "Mugatu sarrera hurrengo baldintzak betetzen duten %s erabiltzaileei:", +"The filter specifies which LDAP users shall have access to the %s instance." => "Iragazkiak zehazten du ze LDAP erabiltzailek izango duten sarrera %s instantziara:", +"users found" => "erabiltzaile aurkituta", +"Back" => "Atzera", +"Continue" => "Jarraitu", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Abisua:</b> PHPk behar duen LDAP modulua ez dago instalaturik, motorrak ez du funtzionatuko. Mesedez eskatu zure sistema kudeatzaileari instala dezan.", "Connection Settings" => "Konexio Ezarpenak", "Configuration Active" => "Konfigurazio Aktiboa", "When unchecked, this configuration will be skipped." => "Markatuta ez dagoenean, konfigurazio hau ez da kontutan hartuko.", -"Port" => "Portua", "Backup (Replica) Host" => "Babeskopia (Replica) Ostalaria", "Give an optional backup host. It must be a replica of the main LDAP/AD server." => "Eman babeskopia ostalari gehigarri bat. LDAP/AD zerbitzari nagusiaren replica bat izan behar da.", "Backup (Replica) Port" => "Babeskopia (Replica) Ataka", "Disable Main Server" => "Desgaitu Zerbitzari Nagusia", -"Use TLS" => "Erabili TLS", -"Do not use it additionally for LDAPS connections, it will fail." => "Ez erabili LDAPS konexioetarako, huts egingo du.", +"Only connect to the replica server." => "Konektatu bakarrik erreplika zerbitzarira", "Case insensitve LDAP server (Windows)" => "Maiuskulak eta minuskulak ezberditzen ez dituen LDAP zerbitzaria (windows)", "Turn off SSL certificate validation." => "Ezgaitu SSL ziurtagirien egiaztapena.", "Cache Time-To-Live" => "Katxearen Bizi-Iraupena", "in seconds. A change empties the cache." => "segundutan. Aldaketak katxea husten du.", "Directory Settings" => "Karpetaren Ezarpenak", "User Display Name Field" => "Erabiltzaileen bistaratzeko izena duen eremua", +"The LDAP attribute to use to generate the user's display name." => "Erabiltzailearen bistaratze izena sortzeko erabiliko den LDAP atributua.", "Base User Tree" => "Oinarrizko Erabiltzaile Zuhaitza", "One User Base DN per line" => "Erabiltzaile DN Oinarri bat lerroko", "User Search Attributes" => "Erabili Bilaketa Atributuak ", "Optional; one attribute per line" => "Aukerakoa; atributu bat lerro bakoitzeko", "Group Display Name Field" => "Taldeen bistaratzeko izena duen eremua", +"The LDAP attribute to use to generate the groups's display name." => "Taldearen bistaratze izena sortzeko erabiliko den LDAP atributua.", "Base Group Tree" => "Oinarrizko Talde Zuhaitza", "One Group Base DN per line" => "Talde DN Oinarri bat lerroko", "Group Search Attributes" => "Taldekatu Bilaketa Atributuak ", @@ -62,7 +89,9 @@ $TRANSLATIONS = array( "User Home Folder Naming Rule" => "Erabiltzailearen Karpeta Nagusia Izendatzeko Patroia", "Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "Utzi hutsik erabiltzaile izenarako (lehentsia). Bestela zehaztu LDAP/AD atributua.", "Internal Username" => "Barneko erabiltzaile izena", -"Test Configuration" => "Egiaztatu Konfigurazioa", -"Help" => "Laguntza" +"Internal Username Attribute:" => "Baliogabeko Erabiltzaile Izen atributua", +"Override UUID detection" => "Gainidatzi UUID antzematea", +"UUID Attribute for Users:" => "Erabiltzaileentzako UUID atributuak:", +"UUID Attribute for Groups:" => "Taldeentzako UUID atributuak:" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/fa.php b/apps/user_ldap/l10n/fa.php index c4db39521dd..688a6ee0d42 100644 --- a/apps/user_ldap/l10n/fa.php +++ b/apps/user_ldap/l10n/fa.php @@ -14,26 +14,26 @@ $TRANSLATIONS = array( "Connection test failed" => "تست اتصال ناموفق بود", "Do you really want to delete the current Server Configuration?" => "آیا واقعا می خواهید پیکربندی کنونی سرور را حذف کنید؟", "Confirm Deletion" => "تایید حذف", -"Server configuration" => "پیکربندی سرور", +"_%s group found_::_%s groups found_" => array(""), +"_%s user found_::_%s users found_" => array(""), +"Save" => "ذخیره", +"Test Configuration" => "امتحان پیکربندی", +"Help" => "راهنما", "Add Server Configuration" => "افزودن پیکربندی سرور", "Host" => "میزبانی", -"Base DN" => "پایه DN", -"One Base DN per line" => "یک پایه DN در هر خط", -"You can specify Base DN for users and groups in the Advanced tab" => "شما می توانید پایه DN را برای کاربران و گروه ها در زبانه Advanced مشخص کنید.", +"Port" => "درگاه", "User DN" => "کاربر DN", "Password" => "گذرواژه", "For anonymous access, leave DN and Password empty." => "برای دسترسی ناشناس، DN را رها نموده و رمزعبور را خالی بگذارید.", -"User Login Filter" => "فیلتر ورودی کاربر", -"Group Filter" => "فیلتر گروه", +"One Base DN per line" => "یک پایه DN در هر خط", +"You can specify Base DN for users and groups in the Advanced tab" => "شما می توانید پایه DN را برای کاربران و گروه ها در زبانه Advanced مشخص کنید.", +"Back" => "بازگشت", "Connection Settings" => "تنظیمات اتصال", "Configuration Active" => "پیکربندی فعال", "When unchecked, this configuration will be skipped." => "زمانیکه انتخاب نشود، این پیکربندی نادیده گرفته خواهد شد.", -"Port" => "درگاه", "Backup (Replica) Host" => "پشتیبان گیری (بدل) میزبان", "Backup (Replica) Port" => "پشتیبان گیری (بدل) پورت", "Disable Main Server" => "غیر فعال کردن سرور اصلی", -"Use TLS" => "استفاده ازTLS", -"Do not use it additionally for LDAPS connections, it will fail." => "علاوه بر این برای اتصالات LDAPS از آن استفاده نکنید، با شکست مواجه خواهد شد.", "Case insensitve LDAP server (Windows)" => "غیر حساس به بزرگی و کوچکی حروف LDAP سرور (ویندوز)", "Turn off SSL certificate validation." => "غیرفعال کردن اعتبار گواهی نامه SSL .", "Directory Settings" => "تنظیمات پوشه", @@ -57,11 +57,8 @@ $TRANSLATIONS = array( "Internal Username" => "نام کاربری داخلی", "Internal Username Attribute:" => "ویژگی نام کاربری داخلی:", "Override UUID detection" => "نادیده گرفتن تشخیص UUID ", -"UUID Attribute:" => "صفت UUID:", "Username-LDAP User Mapping" => "نام کاربری - نگاشت کاربر LDAP ", "Clear Username-LDAP User Mapping" => "پاک کردن نام کاربری- LDAP نگاشت کاربر ", -"Clear Groupname-LDAP Group Mapping" => "پاک کردن نام گروه -LDAP گروه نقشه برداری", -"Test Configuration" => "امتحان پیکربندی", -"Help" => "راهنما" +"Clear Groupname-LDAP Group Mapping" => "پاک کردن نام گروه -LDAP گروه نقشه برداری" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/user_ldap/l10n/fi_FI.php b/apps/user_ldap/l10n/fi_FI.php index 341ffe8f627..ac1dfcc5ab8 100644 --- a/apps/user_ldap/l10n/fi_FI.php +++ b/apps/user_ldap/l10n/fi_FI.php @@ -5,24 +5,26 @@ $TRANSLATIONS = array( "Cannot add server configuration" => "Palvelinasetusten lisäys epäonnistui", "Success" => "Onnistui!", "Error" => "Virhe", +"Select groups" => "Valitse ryhmät", "Connection test succeeded" => "Yhteystesti onnistui", "Connection test failed" => "Yhteystesti epäonnistui", "Confirm Deletion" => "Vahvista poisto", +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("",""), +"Save" => "Tallenna", +"Help" => "Ohje", "Host" => "Isäntä", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Voit jättää protokollan määrittämättä, paitsi kun vaadit SSL:ää. Aloita silloin ldaps://", -"Base DN" => "Oletus DN", -"You can specify Base DN for users and groups in the Advanced tab" => "Voit määrittää käyttäjien ja ryhmien oletus DN:n (distinguished name) 'tarkemmat asetukset'-välilehdeltä ", +"Port" => "Portti", "User DN" => "Käyttäjän DN", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "Asiakasohjelman DN, jolla yhdistäminen tehdään, ts. uid=agent,dc=example,dc=com. Mahdollistaaksesi anonyymin yhteyden, jätä DN ja salasana tyhjäksi.", "Password" => "Salasana", "For anonymous access, leave DN and Password empty." => "Jos haluat mahdollistaa anonyymin pääsyn, jätä DN ja Salasana tyhjäksi ", -"User Login Filter" => "Login suodatus", -"User List Filter" => "Käyttäjien suodatus", -"Group Filter" => "Ryhmien suodatus", +"You can specify Base DN for users and groups in the Advanced tab" => "Voit määrittää käyttäjien ja ryhmien oletus DN:n (distinguished name) 'tarkemmat asetukset'-välilehdeltä ", +"Back" => "Takaisin", +"Continue" => "Jatka", "Connection Settings" => "Yhteysasetukset", -"Port" => "Portti", "Disable Main Server" => "Poista pääpalvelin käytöstä", -"Use TLS" => "Käytä TLS:ää", "Case insensitve LDAP server (Windows)" => "Kirjainkoosta piittamaton LDAP-palvelin (Windows)", "Turn off SSL certificate validation." => "Poista käytöstä SSL-varmenteen vahvistus", "in seconds. A change empties the cache." => "sekunneissa. Muutos tyhjentää välimuistin.", @@ -34,7 +36,6 @@ $TRANSLATIONS = array( "Group-Member association" => "Ryhmän ja jäsenen assosiaatio (yhteys)", "in bytes" => "tavuissa", "Email Field" => "Sähköpostikenttä", -"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "Jätä tyhjäksi käyttäjänimi (oletusasetus). Muutoin anna LDAP/AD-atribuutti.", -"Help" => "Ohje" +"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "Jätä tyhjäksi käyttäjänimi (oletusasetus). Muutoin anna LDAP/AD-atribuutti." ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/fr.php b/apps/user_ldap/l10n/fr.php index 8b6027b81e6..a5429130d61 100644 --- a/apps/user_ldap/l10n/fr.php +++ b/apps/user_ldap/l10n/fr.php @@ -4,7 +4,11 @@ $TRANSLATIONS = array( "Failed to delete the server configuration" => "Échec de la suppression de la configuration du serveur", "The configuration is valid and the connection could be established!" => "La configuration est valide et la connexion peut être établie !", "The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "La configuration est valide, mais le lien ne peut être établi. Veuillez vérifier les paramètres du serveur ainsi que vos identifiants de connexion.", -"The configuration is invalid. Please look in the ownCloud log for further details." => "La configuration est invalide. Veuillez vous référer aux fichiers de journaux ownCloud pour plus d'information.", +"The configuration is invalid. Please have a look at the logs for further details." => "La configuration est invalide. Veuillez consulter les logs pour plus de détails.", +"No action specified" => "Aucune action spécifiée", +"No configuration specified" => "Aucune configuration spécifiée", +"No data specified" => "Aucune donnée spécifiée", +" Could not set configuration %s" => "Impossible de spécifier la configuration %s", "Deletion failed" => "La suppression a échoué", "Take over settings from recent server configuration?" => "Récupérer les paramètres depuis une configuration récente du serveur ?", "Keep settings?" => "Garder ces paramètres ?", @@ -12,40 +16,60 @@ $TRANSLATIONS = array( "mappings cleared" => "associations supprimées", "Success" => "Succès", "Error" => "Erreur", +"Configuration OK" => "Configuration OK", +"Configuration incorrect" => "Configuration incorrecte", +"Configuration incomplete" => "Configuration incomplète", +"Select groups" => "Sélectionnez les groupes", +"Select object classes" => "Sélectionner les classes d'objet", +"Select attributes" => "Sélectionner les attributs", "Connection test succeeded" => "Test de connexion réussi", "Connection test failed" => "Test de connexion échoué", "Do you really want to delete the current Server Configuration?" => "Êtes-vous vraiment sûr de vouloir effacer la configuration actuelle du serveur ?", "Confirm Deletion" => "Confirmer la suppression", -"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Avertissement :</b> Les applications user_ldap et user_webdavauth sont incompatibles. Des dysfonctionnements peuvent survenir. Contactez votre administrateur système pour qu'il désactive l'une d'elles.", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Attention :</b> Le module php LDAP n'est pas installé, par conséquent cette extension ne pourra fonctionner. Veuillez contacter votre administrateur système afin qu'il l'installe.", -"Server configuration" => "Configuration du serveur", +"_%s group found_::_%s groups found_" => array("%s groupe trouvé","%s groupes trouvés"), +"_%s user found_::_%s users found_" => array("%s utilisateur trouvé","%s utilisateurs trouvés"), +"Invalid Host" => "Hôte invalide", +"Could not find the desired feature" => "Impossible de trouver la fonction souhaitée", +"Save" => "Sauvegarder", +"Test Configuration" => "Tester la configuration", +"Help" => "Aide", +"Limit the access to %s to groups meeting this criteria:" => "Limiter l'accès à %s aux groupes respectant ce critère :", +"only those object classes:" => "seulement ces classes d'objet :", +"only from those groups:" => "seulement de ces groupes :", +"Edit raw filter instead" => "Éditer le filtre raw à la place", +"Raw LDAP filter" => "Filtre Raw LDAP", +"The filter specifies which LDAP groups shall have access to the %s instance." => "Le filtre spécifie quels groupes LDAP doivent avoir accès à l'instance %s.", +"groups found" => "groupes trouvés", +"What attribute shall be used as login name:" => "Quel attribut doit être utilisé comme nom de login:", +"LDAP Username:" => "Nom d'utilisateur LDAP :", +"LDAP Email Address:" => "Adresse email LDAP :", +"Other Attributes:" => "Autres attributs :", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Définit le filtre à appliquer lors d'une tentative de connexion. %%uid remplace le nom d'utilisateur lors de la connexion. Exemple : \"uid=%%uid\"", "Add Server Configuration" => "Ajouter une configuration du serveur", "Host" => "Hôte", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Vous pouvez omettre le protocole, sauf si vous avez besoin de SSL. Dans ce cas préfixez avec ldaps://", -"Base DN" => "DN racine", -"One Base DN per line" => "Un DN racine par ligne", -"You can specify Base DN for users and groups in the Advanced tab" => "Vous pouvez spécifier les DN Racines de vos utilisateurs et groupes via l'onglet Avancé", +"Port" => "Port", "User DN" => "DN Utilisateur (Autorisé à consulter l'annuaire)", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "DN de l'utilisateur client pour lequel la liaison doit se faire, par exemple uid=agent,dc=example,dc=com. Pour un accès anonyme, laisser le DN et le mot de passe vides.", "Password" => "Mot de passe", "For anonymous access, leave DN and Password empty." => "Pour un accès anonyme, laisser le DN utilisateur et le mot de passe vides.", -"User Login Filter" => "Modèle d'authentification utilisateurs", -"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Définit le filtre à appliquer lors d'une tentative de connexion. %%uid remplace le nom d'utilisateur lors de la connexion. Exemple : \"uid=%%uid\"", -"User List Filter" => "Filtre d'utilisateurs", -"Defines the filter to apply, when retrieving users (no placeholders). Example: \"objectClass=person\"" => "Définit le filtre à appliquer lors de la récupération des utilisateurs. Exemple : \"objectClass=person\"", -"Group Filter" => "Filtre de groupes", -"Defines the filter to apply, when retrieving groups (no placeholders). Example: \"objectClass=posixGroup\"" => "Définit le filtre à appliquer lors de la récupération des groupes. Exemple : \"objectClass=posixGroup\"", +"One Base DN per line" => "Un DN racine par ligne", +"You can specify Base DN for users and groups in the Advanced tab" => "Vous pouvez spécifier les DN Racines de vos utilisateurs et groupes via l'onglet Avancé", +"Limit the access to %s to users meeting this criteria:" => "Limiter l'accès à %s aux utilisateurs respectant ce critère :", +"The filter specifies which LDAP users shall have access to the %s instance." => "Le filtre spécifie quels utilisateurs LDAP doivent avoir accès à l'instance %s.", +"users found" => "utilisateurs trouvés", +"Back" => "Retour", +"Continue" => "Poursuivre", +"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Avertissement :</b> Les applications user_ldap et user_webdavauth sont incompatibles. Des dysfonctionnements peuvent survenir. Contactez votre administrateur système pour qu'il désactive l'une d'elles.", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Attention :</b> Le module php LDAP n'est pas installé, par conséquent cette extension ne pourra fonctionner. Veuillez contacter votre administrateur système afin qu'il l'installe.", "Connection Settings" => "Paramètres de connexion", "Configuration Active" => "Configuration active", "When unchecked, this configuration will be skipped." => "Lorsque non cochée, la configuration sera ignorée.", -"Port" => "Port", "Backup (Replica) Host" => "Serveur de backup (réplique)", "Give an optional backup host. It must be a replica of the main LDAP/AD server." => "Fournir un serveur de backup optionnel. Il doit s'agir d'une réplique du serveur LDAP/AD principal.", "Backup (Replica) Port" => "Port du serveur de backup (réplique)", "Disable Main Server" => "Désactiver le serveur principal", "Only connect to the replica server." => "Se connecter uniquement au serveur de replica.", -"Use TLS" => "Utiliser TLS", -"Do not use it additionally for LDAPS connections, it will fail." => "À ne pas utiliser pour les connexions LDAPS (cela échouera).", "Case insensitve LDAP server (Windows)" => "Serveur LDAP insensible à la casse (Windows)", "Turn off SSL certificate validation." => "Désactiver la validation du certificat SSL.", "Not recommended, use it for testing only! If connection only works with this option, import the LDAP server's SSL certificate in your %s server." => "Non recommandé, à utiliser à des fins de tests uniquement. Si la connexion ne fonctionne qu'avec cette option, importez le certificat SSL du serveur LDAP dans le serveur %s.", @@ -76,12 +100,11 @@ $TRANSLATIONS = array( "Internal Username Attribute:" => "Nom d'utilisateur interne:", "Override UUID detection" => "Surcharger la détection d'UUID", "By default, the UUID attribute is automatically detected. The UUID attribute is used to doubtlessly identify LDAP users and groups. Also, the internal username will be created based on the UUID, if not specified otherwise above. You can override the setting and pass an attribute of your choice. You must make sure that the attribute of your choice can be fetched for both users and groups and it is unique. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users and groups." => "Par défaut, l'attribut UUID est automatiquement détecté. Cet attribut est utilisé pour identifier les utilisateurs et groupes de façon fiable. Un nom d'utilisateur interne basé sur l'UUID sera automatiquement créé, sauf s'il est spécifié autrement ci-dessus. Vous pouvez modifier ce comportement et définir l'attribut de votre choix. Vous devez alors vous assurer que l'attribut de votre choix peut être récupéré pour les utilisateurs ainsi que pour les groupes et qu'il soit unique. Laisser à blanc pour le comportement par défaut. Les modifications seront effectives uniquement pour les nouveaux (ajoutés) utilisateurs et groupes LDAP.", -"UUID Attribute:" => "Attribut UUID :", +"UUID Attribute for Users:" => "Attribut UUID pour les utilisateurs :", +"UUID Attribute for Groups:" => "Attribut UUID pour les groupes :", "Username-LDAP User Mapping" => "Association Nom d'utilisateur-Utilisateur LDAP", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have a internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." => "Les noms d'utilisateurs sont utilisés pour le stockage et l'assignation de (meta) données. Pour identifier et reconnaitre précisément les utilisateurs, chaque utilisateur LDAP aura un nom interne spécifique. Cela requiert l'association d'un nom d'utilisateur ownCloud à un nom d'utilisateur LDAP. Le nom d'utilisateur créé est associé à l'attribut UUID de l'utilisateur LDAP. Par ailleurs, le DN est mémorisé en cache pour limiter les interactions LDAP mais il n'est pas utilisé pour l'identification. Si le DN est modifié, ces modifications seront retrouvées. Seul le nom interne à ownCloud est utilisé au sein du produit. Supprimer les associations créera des orphelins et l'action affectera toutes les configurations LDAP. NE JAMAIS SUPPRIMER LES ASSOCIATIONS EN ENVIRONNEMENT DE PRODUCTION, mais uniquement sur des environnements de tests et d'expérimentation.", "Clear Username-LDAP User Mapping" => "Supprimer l'association utilisateur interne-utilisateur LDAP", -"Clear Groupname-LDAP Group Mapping" => "Supprimer l'association nom de groupe-groupe LDAP", -"Test Configuration" => "Tester la configuration", -"Help" => "Aide" +"Clear Groupname-LDAP Group Mapping" => "Supprimer l'association nom de groupe-groupe LDAP" ); $PLURAL_FORMS = "nplurals=2; plural=(n > 1);"; diff --git a/apps/user_ldap/l10n/fr_CA.php b/apps/user_ldap/l10n/fr_CA.php new file mode 100644 index 00000000000..2371ee70593 --- /dev/null +++ b/apps/user_ldap/l10n/fr_CA.php @@ -0,0 +1,6 @@ +<?php +$TRANSLATIONS = array( +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("","") +); +$PLURAL_FORMS = "nplurals=2; plural=(n > 1);"; diff --git a/apps/user_ldap/l10n/gl.php b/apps/user_ldap/l10n/gl.php index 911e481ca76..34e818ef951 100644 --- a/apps/user_ldap/l10n/gl.php +++ b/apps/user_ldap/l10n/gl.php @@ -4,7 +4,11 @@ $TRANSLATIONS = array( "Failed to delete the server configuration" => "Non foi posíbel eliminar a configuración do servidor", "The configuration is valid and the connection could be established!" => "A configuración é correcta e pode estabelecerse a conexión.", "The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "A configuración é correcta, mais a ligazón non. Comprobe a configuración do servidor e as credenciais.", -"The configuration is invalid. Please look in the ownCloud log for further details." => "A configuración non é correcta. Vexa o rexistro de ownCloud para máis detalles", +"The configuration is invalid. Please have a look at the logs for further details." => "A configuración non é correcta. Vexa o rexistro de ownCloud para máis detalles", +"No action specified" => "Non se especificou unha acción", +"No configuration specified" => "Non se especificou unha configuración", +"No data specified" => "Non se especificaron datos", +" Could not set configuration %s" => "Non foi posíbel estabelecer a configuración %s", "Deletion failed" => "Produciuse un fallo ao eliminar", "Take over settings from recent server configuration?" => "Tomar os recentes axustes de configuración do servidor?", "Keep settings?" => "Manter os axustes?", @@ -12,40 +16,60 @@ $TRANSLATIONS = array( "mappings cleared" => "limpadas as asignacións", "Success" => "Correcto", "Error" => "Erro", +"Configuration OK" => "Configuración correcta", +"Configuration incorrect" => "Configuración incorrecta", +"Configuration incomplete" => "Configuración incompleta", +"Select groups" => "Seleccionar grupos", +"Select object classes" => "Seleccione as clases de obxectos", +"Select attributes" => "Seleccione os atributos", "Connection test succeeded" => "A proba de conexión foi satisfactoria", "Connection test failed" => "A proba de conexión fracasou", "Do you really want to delete the current Server Configuration?" => "Confirma que quere eliminar a configuración actual do servidor?", "Confirm Deletion" => "Confirmar a eliminación", -"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Aviso:</b> Os aplicativos user_ldap e user_webdavauth son incompatíbeis. Pode acontecer un comportamento estraño. Consulte co administrador do sistema para desactivar un deles.", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Aviso:</b> O módulo PHP LDAP non está instalado, o servidor non funcionará. Consulte co administrador do sistema para instalalo.", -"Server configuration" => "Configuración do servidor", +"_%s group found_::_%s groups found_" => array("Atopouse %s grupo","Atopáronse %s grupos"), +"_%s user found_::_%s users found_" => array("Atopouse %s usuario","Atopáronse %s usuarios"), +"Invalid Host" => "Máquina incorrecta", +"Could not find the desired feature" => "Non foi posíbel atopar a función desexada", +"Save" => "Gardar", +"Test Configuration" => "Probar a configuración", +"Help" => "Axuda", +"Limit the access to %s to groups meeting this criteria:" => "Limitar o acceso a %s aos grupos que coincidan con estes criterios:", +"only those object classes:" => "só as clases de obxecto:", +"only from those groups:" => "só dos grupos:", +"Edit raw filter instead" => "Editar, no seu canto, o filtro en bruto", +"Raw LDAP filter" => "Filtro LDAP en bruto", +"The filter specifies which LDAP groups shall have access to the %s instance." => "O filtro especifica que grupos LDAP teñen acceso á instancia %s.", +"groups found" => "atopáronse grupos", +"What attribute shall be used as login name:" => "Atributo que utilizar como nome de usuario:", +"LDAP Username:" => "Nome de usuario LDAP:", +"LDAP Email Address:" => "Enderezo de correo LDAP:", +"Other Attributes:" => "Outros atributos:", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Define o filtro que se aplica cando se intenta o acceso. %%uid substitúe o nome de usuario e a acción de acceso. Exemplo: «uid=%%uid»", "Add Server Configuration" => "Engadir a configuración do servidor", "Host" => "Servidor", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Pode omitir o protocolo agás que precise de SSL. Nese caso comece con ldaps://", -"Base DN" => "DN base", -"One Base DN per line" => "Un DN base por liña", -"You can specify Base DN for users and groups in the Advanced tab" => "Pode especificar a DN base para usuarios e grupos na lapela de «Avanzado»", +"Port" => "Porto", "User DN" => "DN do usuario", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "O DN do cliente do usuario co que hai que estabelecer unha conexión, p.ex uid=axente, dc=exemplo, dc=com. Para o acceso anónimo deixe o DN e o contrasinal baleiros.", "Password" => "Contrasinal", "For anonymous access, leave DN and Password empty." => "Para o acceso anónimo deixe o DN e o contrasinal baleiros.", -"User Login Filter" => "Filtro de acceso de usuarios", -"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Define o filtro que se aplica cando se intenta o acceso. %%uid substitúe o nome de usuario e a acción de acceso. Exemplo: «uid=%%uid»", -"User List Filter" => "Filtro da lista de usuarios", -"Defines the filter to apply, when retrieving users (no placeholders). Example: \"objectClass=person\"" => "Define o filtro a aplicar cando de recuperan os usuarios (sen comodíns). Exemplo: «objectClass=person»", -"Group Filter" => "Filtro de grupo", -"Defines the filter to apply, when retrieving groups (no placeholders). Example: \"objectClass=posixGroup\"" => "Define o filtro a aplicar cando de recuperan os usuarios (sen comodíns). Exemplo: «objectClass=posixGroup»", +"One Base DN per line" => "Un DN base por liña", +"You can specify Base DN for users and groups in the Advanced tab" => "Pode especificar a DN base para usuarios e grupos na lapela de «Avanzado»", +"Limit the access to %s to users meeting this criteria:" => "Limitar o acceso a %s aos usuarios que coincidan con estes criterios:", +"The filter specifies which LDAP users shall have access to the %s instance." => "O filtro especifica que usuarios LDAP teñen acceso á instancia %s.", +"users found" => "atopáronse usuarios", +"Back" => "Atrás", +"Continue" => "Continuar", +"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Aviso:</b> Os aplicativos user_ldap e user_webdavauth son incompatíbeis. Pode acontecer un comportamento estraño. Consulte co administrador do sistema para desactivar un deles.", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Aviso:</b> O módulo PHP LDAP non está instalado, o servidor non funcionará. Consulte co administrador do sistema para instalalo.", "Connection Settings" => "Axustes da conexión", "Configuration Active" => "Configuración activa", "When unchecked, this configuration will be skipped." => "Se está sen marcar, omítese esta configuración.", -"Port" => "Porto", "Backup (Replica) Host" => "Servidor da copia de seguranza (Réplica)", "Give an optional backup host. It must be a replica of the main LDAP/AD server." => "Indicar un servidor de copia de seguranza opcional. Debe ser unha réplica do servidor principal LDAP/AD.", "Backup (Replica) Port" => "Porto da copia de seguranza (Réplica)", "Disable Main Server" => "Desactivar o servidor principal", "Only connect to the replica server." => "Conectar só co servidor de réplica.", -"Use TLS" => "Usar TLS", -"Do not use it additionally for LDAPS connections, it will fail." => "Non utilizalo ademais para conexións LDAPS xa que fallará.", "Case insensitve LDAP server (Windows)" => "Servidor LDAP que non distingue entre maiúsculas e minúsculas (Windows)", "Turn off SSL certificate validation." => "Desactiva a validación do certificado SSL.", "Not recommended, use it for testing only! If connection only works with this option, import the LDAP server's SSL certificate in your %s server." => "Non recomendado, utilizar só para probas! Se a conexión só funciona con esta opción importa o certificado SSL do servidor LDAP no seu servidor %s.", @@ -76,12 +100,11 @@ $TRANSLATIONS = array( "Internal Username Attribute:" => "Atributo do nome de usuario interno:", "Override UUID detection" => "Ignorar a detección do UUID", "By default, the UUID attribute is automatically detected. The UUID attribute is used to doubtlessly identify LDAP users and groups. Also, the internal username will be created based on the UUID, if not specified otherwise above. You can override the setting and pass an attribute of your choice. You must make sure that the attribute of your choice can be fetched for both users and groups and it is unique. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users and groups." => "De xeito predeterminado, o atributo UUID é detectado automaticamente. O atributo UUID utilizase para identificar, sen dúbida, aos usuarios e grupos LDAP. Ademais, crearase o usuario interno baseado no UUID, se non se especifica anteriormente o contrario. Pode anular a configuración e pasar un atributo da súa escolla. Vostede debe asegurarse de que o atributo da súa escolla pode ser recuperado polos usuarios e grupos e de que é único. Déixeo baleiro para o comportamento predeterminado. Os cambios terán efecto só nas novas asignacións (engadidos) de usuarios de LDAP.", -"UUID Attribute:" => "Atributo do UUID:", +"UUID Attribute for Users:" => "Atributo do UUID para usuarios:", +"UUID Attribute for Groups:" => "Atributo do UUID para grupos:", "Username-LDAP User Mapping" => "Asignación do usuario ao «nome de usuario LDAP»", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have a internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." => "Os nomes de usuario empreganse para almacenar e asignar (meta) datos. Coa fin de identificar con precisión e recoñecer aos usuarios, cada usuario LDAP terá un nome de usuario interno. Isto require unha asignación de ownCloud nome de usuario a usuario LDAP. O nome de usuario creado asignase ao UUID do usuario LDAP. Ademais o DN almacenase na caché, para así reducir a interacción do LDAP, mais non se utiliza para a identificación. Se o DN cambia, os cambios poden ser atopados polo ownCloud. O nome interno no ownCloud utilizase en todo o ownCloud. A limpeza das asignacións deixará rastros en todas partes. A limpeza das asignacións non é sensíbel á configuración, afecta a todas as configuracións de LDAP! Non limpar nunca as asignacións nun entorno de produción. Limpar as asignacións só en fases de proba ou experimentais.", "Clear Username-LDAP User Mapping" => "Limpar a asignación do usuario ao «nome de usuario LDAP»", -"Clear Groupname-LDAP Group Mapping" => "Limpar a asignación do grupo ao «nome de grupo LDAP»", -"Test Configuration" => "Probar a configuración", -"Help" => "Axuda" +"Clear Groupname-LDAP Group Mapping" => "Limpar a asignación do grupo ao «nome de grupo LDAP»" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/he.php b/apps/user_ldap/l10n/he.php index b39a4277078..0dcf8527849 100644 --- a/apps/user_ldap/l10n/he.php +++ b/apps/user_ldap/l10n/he.php @@ -8,18 +8,18 @@ $TRANSLATIONS = array( "Connection test failed" => "בדיקת החיבור נכשלה", "Do you really want to delete the current Server Configuration?" => "האם אכן למחוק את הגדרות השרת הנוכחיות?", "Confirm Deletion" => "אישור המחיקה", -"Server configuration" => "הגדרות השרת", +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("",""), +"Save" => "שמירה", +"Help" => "עזרה", "Add Server Configuration" => "הוספת הגדרות השרת", "Host" => "מארח", +"Port" => "פורט", "User DN" => "DN משתמש", "Password" => "סיסמא", "For anonymous access, leave DN and Password empty." => "לגישה אנונימית, השאר את הDM והסיסמא ריקים.", -"User Login Filter" => "סנן כניסת משתמש", -"User List Filter" => "סנן רשימת משתמשים", -"Group Filter" => "סנן קבוצה", -"Port" => "פורט", +"Back" => "אחורה", "in seconds. A change empties the cache." => "בשניות. שינוי מרוקן את המטמון.", -"in bytes" => "בבתים", -"Help" => "עזרה" +"in bytes" => "בבתים" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/hi.php b/apps/user_ldap/l10n/hi.php index 24ae7a02176..386134547eb 100644 --- a/apps/user_ldap/l10n/hi.php +++ b/apps/user_ldap/l10n/hi.php @@ -1,7 +1,10 @@ <?php $TRANSLATIONS = array( "Error" => "त्रुटि", -"Password" => "पासवर्ड", -"Help" => "सहयोग" +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("",""), +"Save" => "सहेजें", +"Help" => "सहयोग", +"Password" => "पासवर्ड" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/hr.php b/apps/user_ldap/l10n/hr.php index c9445de0dfc..b28175994eb 100644 --- a/apps/user_ldap/l10n/hr.php +++ b/apps/user_ldap/l10n/hr.php @@ -1,7 +1,11 @@ <?php $TRANSLATIONS = array( "Error" => "Greška", +"_%s group found_::_%s groups found_" => array("","",""), +"_%s user found_::_%s users found_" => array("","",""), +"Save" => "Snimi", +"Help" => "Pomoć", "Password" => "Lozinka", -"Help" => "Pomoć" +"Back" => "Natrag" ); $PLURAL_FORMS = "nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;"; diff --git a/apps/user_ldap/l10n/hu_HU.php b/apps/user_ldap/l10n/hu_HU.php index b43dcbc2c87..2799d0407c4 100644 --- a/apps/user_ldap/l10n/hu_HU.php +++ b/apps/user_ldap/l10n/hu_HU.php @@ -4,7 +4,11 @@ $TRANSLATIONS = array( "Failed to delete the server configuration" => "Nem sikerült törölni a kiszolgáló konfigurációját", "The configuration is valid and the connection could be established!" => "A konfiguráció érvényes, és a kapcsolat létrehozható!", "The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "A konfiguráció érvényes, de a kapcsolat nem hozható létre. Kérem ellenőrizze a kiszolgáló beállításait, és az elérési adatokat.", -"The configuration is invalid. Please look in the ownCloud log for further details." => "Érvénytelen konfiguráció. További információkért nézze meg az ownCloud naplófájlját.", +"The configuration is invalid. Please have a look at the logs for further details." => "Érvénytelen konfiguráció. További információkért nézze meg a naplófájlokat!", +"No action specified" => "Nincs megadva parancs", +"No configuration specified" => "Nincs megadva konfiguráció", +"No data specified" => "Nincs adat megadva", +" Could not set configuration %s" => "A(z) %s konfiguráció nem állítható be", "Deletion failed" => "A törlés nem sikerült", "Take over settings from recent server configuration?" => "Vegyük át a beállításokat az előző konfigurációból?", "Keep settings?" => "Tartsuk meg a beállításokat?", @@ -12,40 +16,60 @@ $TRANSLATIONS = array( "mappings cleared" => "Töröltük a hozzárendeléseket", "Success" => "Sikeres végrehajtás", "Error" => "Hiba", +"Configuration OK" => "Konfiguráció OK", +"Configuration incorrect" => "Konfiguráió hibás", +"Configuration incomplete" => "Konfiguráció nincs befejezve", +"Select groups" => "Csoportok kiválasztása", +"Select object classes" => "Objektumosztályok kiválasztása", +"Select attributes" => "Attribútumok kiválasztása", "Connection test succeeded" => "A kapcsolatellenőrzés eredménye: sikerült", "Connection test failed" => "A kapcsolatellenőrzés eredménye: nem sikerült", "Do you really want to delete the current Server Configuration?" => "Tényleg törölni szeretné a kiszolgáló beállításait?", "Confirm Deletion" => "A törlés megerősítése", -"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Figyelem:</b> a user_ldap és user_webdavauth alkalmazások nem kompatibilisek. Együttes használatuk váratlan eredményekhez vezethet. Kérje meg a rendszergazdát, hogy a kettő közül kapcsolja ki az egyiket.", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Figyelmeztetés:</b> Az LDAP PHP modul nincs telepítve, ezért ez az alrendszer nem fog működni. Kérje meg a rendszergazdát, hogy telepítse!", -"Server configuration" => "A kiszolgálók beállításai", +"_%s group found_::_%s groups found_" => array("%s csoport van","%s csoport van"), +"_%s user found_::_%s users found_" => array("%s felhasználó van","%s felhasználó van"), +"Invalid Host" => "Érvénytelen gépnév", +"Could not find the desired feature" => "A kívánt funkció nem található", +"Save" => "Mentés", +"Test Configuration" => "A beállítások tesztelése", +"Help" => "Súgó", +"Limit the access to %s to groups meeting this criteria:" => "Korlátozzuk %s elérését a következő feltételeknek megfelelő csoportokra:", +"only those object classes:" => "csak ezek az objektumosztályok:", +"only from those groups:" => "csak ezek a csoportok:", +"Edit raw filter instead" => "Inkább közvetlenül megadom a szűrési kifejezést:", +"Raw LDAP filter" => "Az LDAP szűrőkifejezés", +"The filter specifies which LDAP groups shall have access to the %s instance." => "A szűrő meghatározza, hogy mely LDAP csoportok lesznek jogosultak %s elérésére.", +"groups found" => "csoport van", +"What attribute shall be used as login name:" => "Melyik attribútumot használjuk login névként:", +"LDAP Username:" => "LDAP felhasználónév:", +"LDAP Email Address:" => "LDAP e-mail cím:", +"Other Attributes:" => "Más attribútumok:", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Ez a szűrő érvényes a bejelentkezés megkísérlésekor. Ekkor az %%uid változó helyére a bejelentkezési név kerül. Például: \"uid=%%uid\"", "Add Server Configuration" => "Új kiszolgáló beállításának hozzáadása", "Host" => "Kiszolgáló", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "A protokoll előtag elhagyható, kivéve, ha SSL-t kíván használni. Ebben az esetben kezdje így: ldaps://", -"Base DN" => "DN-gyökér", -"One Base DN per line" => "Soronként egy DN-gyökér", -"You can specify Base DN for users and groups in the Advanced tab" => "A Haladó fülre kattintva külön DN-gyökér állítható be a felhasználók és a csoportok számára", +"Port" => "Port", "User DN" => "A kapcsolódó felhasználó DN-je", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "Annak a felhasználónak a DN-je, akinek a nevében bejelentkezve kapcsolódunk a kiszolgálóhoz, pl. uid=agent,dc=example,dc=com. Bejelentkezés nélküli eléréshez ne töltse ki a DN és Jelszó mezőket!", "Password" => "Jelszó", "For anonymous access, leave DN and Password empty." => "Bejelentkezés nélküli eléréshez ne töltse ki a DN és Jelszó mezőket!", -"User Login Filter" => "Szűrő a bejelentkezéshez", -"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Ez a szűrő érvényes a bejelentkezés megkísérlésekor. Ekkor az %%uid változó helyére a bejelentkezési név kerül. Például: \"uid=%%uid\"", -"User List Filter" => "A felhasználók szűrője", -"Defines the filter to apply, when retrieving users (no placeholders). Example: \"objectClass=person\"" => "Ez a szűrő érvényes a felhasználók listázásakor (nincs helyettesíthető változó). Például: \"objectClass=person\"", -"Group Filter" => "A csoportok szűrője", -"Defines the filter to apply, when retrieving groups (no placeholders). Example: \"objectClass=posixGroup\"" => "Ez a szűrő érvényes a csoportok listázásakor (nincs helyettesíthető változó). Például: \"objectClass=posixGroup\"", +"One Base DN per line" => "Soronként egy DN-gyökér", +"You can specify Base DN for users and groups in the Advanced tab" => "A Haladó fülre kattintva külön DN-gyökér állítható be a felhasználók és a csoportok számára", +"Limit the access to %s to users meeting this criteria:" => "Korlátozzuk %s elérését a következő feltételeknek megfelelő felhasználókra:", +"The filter specifies which LDAP users shall have access to the %s instance." => "A szűrő meghatározza, hogy mely LDAP felhasználók lesznek jogosultak %s elérésére.", +"users found" => "felhasználó van", +"Back" => "Vissza", +"Continue" => "Folytatás", +"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Figyelem:</b> a user_ldap és user_webdavauth alkalmazások nem kompatibilisek. Együttes használatuk váratlan eredményekhez vezethet. Kérje meg a rendszergazdát, hogy a kettő közül kapcsolja ki az egyiket.", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Figyelmeztetés:</b> Az LDAP PHP modul nincs telepítve, ezért ez az alrendszer nem fog működni. Kérje meg a rendszergazdát, hogy telepítse!", "Connection Settings" => "Kapcsolati beállítások", "Configuration Active" => "A beállítás aktív", "When unchecked, this configuration will be skipped." => "Ha nincs kipipálva, ez a beállítás kihagyódik.", -"Port" => "Port", "Backup (Replica) Host" => "Másodkiszolgáló (replika)", "Give an optional backup host. It must be a replica of the main LDAP/AD server." => "Adjon meg egy opcionális másodkiszolgálót. Ez a fő LDAP/AD kiszolgáló szinkron másolata (replikája) kell legyen.", "Backup (Replica) Port" => "A másodkiszolgáló (replika) portszáma", "Disable Main Server" => "A fő szerver kihagyása", "Only connect to the replica server." => "Csak a másodlagos (másolati) kiszolgálóhoz kapcsolódjunk.", -"Use TLS" => "Használjunk TLS-t", -"Do not use it additionally for LDAPS connections, it will fail." => "LDAPS kapcsolatok esetén ne kapcsoljuk be, mert nem fog működni.", "Case insensitve LDAP server (Windows)" => "Az LDAP-kiszolgáló nem tesz különbséget a kis- és nagybetűk között (Windows)", "Turn off SSL certificate validation." => "Ne ellenőrizzük az SSL-tanúsítvány érvényességét", "Not recommended, use it for testing only! If connection only works with this option, import the LDAP server's SSL certificate in your %s server." => "Használata nem javasolt (kivéve tesztelési céllal). Ha a kapcsolat csak ezzel a beállítással működik, akkor importálja az LDAP-kiszolgáló SSL tanúsítványát a(z) %s kiszolgálóra!", @@ -75,11 +99,12 @@ $TRANSLATIONS = array( "By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. To achieve a similar behavior as before ownCloud 5 enter the user display name attribute in the following field. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users." => "Alapértelmezetten a belső felhasználónév az UUID tulajdonságból jön létre. Ez biztosítja a felhasználónév egyediségét és hogy a nem kell konvertálni a karaktereket benne. A belső felhasználónévnél a megkötés az, hogy csak a következő karakterek engdélyezettek benne: [ a-zA-Z0-9_.@- ]. Ezeken a karaktereken kivül minden karakter le lesz cserélve az adott karakter ASCII kódtáblában használható párjára vagy ha ilyen nincs akkor egyszerűen ki lesz hagyva. Ha így mégis ütköznének a nevek akkor hozzá lesz füzve egy folyamatosan növekvő számláló rész. A belső felhasználónevet lehet használni a felhasználó azonosítására a programon belül. Illetve ez lesz az alapáértelmezett neve a felhasználó kezdő könyvtárának az ownCloud-ban. Illetve...............................", "Internal Username Attribute:" => "A belső felhasználónév attribútuma:", "Override UUID detection" => "Az UUID-felismerés felülbírálása", -"UUID Attribute:" => "UUID attribútum:", +"By default, the UUID attribute is automatically detected. The UUID attribute is used to doubtlessly identify LDAP users and groups. Also, the internal username will be created based on the UUID, if not specified otherwise above. You can override the setting and pass an attribute of your choice. You must make sure that the attribute of your choice can be fetched for both users and groups and it is unique. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users and groups." => "Az UUID attribútum alapértelmezetten felismerésre kerül. Az UUID attribútum segítségével az LDAP felhasználók és csoportok egyértelműen azonosíthatók. A belső felhasználónév is azonos lesz az UUID-vel, ha fentebb nincs másként definiálva. Ezt a beállítást felülbírálhatja és bármely attribútummal helyettesítheti. Ekkor azonban gondoskodnia kell arról, hogy a kiválasztott attribútum minden felhasználó és csoport esetén lekérdezhető és egyedi értékkel bír. Ha a mezőt üresen hagyja, akkor az alapértelmezett attribútum lesz érvényes. Egy esetleges módosítás csak az újonnan hozzárendelt (ill. létrehozott) felhasználókra és csoportokra lesz érvényes.", +"UUID Attribute for Users:" => "A felhasználók UUID attribútuma:", +"UUID Attribute for Groups:" => "A csoportok UUID attribútuma:", "Username-LDAP User Mapping" => "Felhasználó - LDAP felhasználó hozzárendelés", +"Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have a internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." => "A felhasználónevek segítségével történik a (meta)adatok tárolása és hozzárendelése. A felhasználók pontos azonosítása céljából minden LDAP felhasználóhoz egy belső felhasználónevet rendelünk. Ezt a felhasználónevet az LDAP felhasználó UUID attribútumához rendeljük hozzá. Ezen túlmenően a DN is tárolásra kerül a gyorsítótárban, hogy csökkentsük az LDAP lekérdezések számát, de a DN-t nem használjuk azonosításra. Ha a DN megváltozik, akkor a rendszer ezt észleli. A belső felhasználóneveket a rendszer igen sok helyen használja, ezért a hozzárendelések törlése sok érvénytelen adatrekordot eredményez az adatbázisban. A hozzárendelések törlése nem függ a konfigurációtól, minden LDAP konfigurációt érint! Ténylegesen működő szolgáltatás esetén sose törölje a hozzárendeléseket, csak tesztelési vagy kísérleti célú szerveren!", "Clear Username-LDAP User Mapping" => "A felhasználó - LDAP felhasználó hozzárendelés törlése", -"Clear Groupname-LDAP Group Mapping" => "A csoport - LDAP csoport hozzárendelés törlése", -"Test Configuration" => "A beállítások tesztelése", -"Help" => "Súgó" +"Clear Groupname-LDAP Group Mapping" => "A csoport - LDAP csoport hozzárendelés törlése" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/hy.php b/apps/user_ldap/l10n/hy.php new file mode 100644 index 00000000000..805020b059c --- /dev/null +++ b/apps/user_ldap/l10n/hy.php @@ -0,0 +1,7 @@ +<?php +$TRANSLATIONS = array( +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("",""), +"Save" => "Պահպանել" +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/ia.php b/apps/user_ldap/l10n/ia.php index 9de7344f15f..e138fd835f1 100644 --- a/apps/user_ldap/l10n/ia.php +++ b/apps/user_ldap/l10n/ia.php @@ -1,7 +1,12 @@ <?php $TRANSLATIONS = array( +"Deletion failed" => "Il falleva deler", "Error" => "Error", +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("",""), +"Save" => "Salveguardar", +"Help" => "Adjuta", "Password" => "Contrasigno", -"Help" => "Adjuta" +"Back" => "Retro" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/id.php b/apps/user_ldap/l10n/id.php index 9580725616d..03071bb1d0f 100644 --- a/apps/user_ldap/l10n/id.php +++ b/apps/user_ldap/l10n/id.php @@ -3,42 +3,42 @@ $TRANSLATIONS = array( "Failed to delete the server configuration" => "Gagal menghapus konfigurasi server", "The configuration is valid and the connection could be established!" => "Konfigurasi valid dan koneksi dapat dilakukan!", "The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "Konfigurasi valid, tetapi Bind gagal. Silakan cek pengaturan server dan keamanan.", -"The configuration is invalid. Please look in the ownCloud log for further details." => "Konfigurasi salah. Silakan lihat log ownCloud untuk lengkapnya.", "Deletion failed" => "Penghapusan gagal", "Take over settings from recent server configuration?" => "Ambil alih pengaturan dari konfigurasi server saat ini?", "Keep settings?" => "Biarkan pengaturan?", "Cannot add server configuration" => "Gagal menambah konfigurasi server", "Success" => "Sukses", "Error" => "Galat", +"Select groups" => "Pilih grup", "Connection test succeeded" => "Tes koneksi sukses", "Connection test failed" => "Tes koneksi gagal", "Do you really want to delete the current Server Configuration?" => "Anda ingin menghapus Konfigurasi Server saat ini?", "Confirm Deletion" => "Konfirmasi Penghapusan", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Peringatan:</b> Modul LDAP PHP tidak terpasang, perangkat tidak akan bekerja. Silakan minta administrator sistem untuk memasangnya.", -"Server configuration" => "Konfigurasi server", +"_%s group found_::_%s groups found_" => array(""), +"_%s user found_::_%s users found_" => array(""), +"Save" => "Simpan", +"Test Configuration" => "Uji Konfigurasi", +"Help" => "Bantuan", "Add Server Configuration" => "Tambah Konfigurasi Server", "Host" => "Host", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Protokol dapat tidak ditulis, kecuali anda menggunakan SSL. Lalu jalankan dengan ldaps://", -"Base DN" => "Base DN", -"One Base DN per line" => "Satu Base DN per baris", -"You can specify Base DN for users and groups in the Advanced tab" => "Anda dapat menetapkan Base DN untuk pengguna dan grup dalam tab Lanjutan", +"Port" => "port", "User DN" => "User DN", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "DN dari klien pengguna yang dengannya tautan akan diterapkan, mis. uid=agen,dc=contoh,dc=com. Untuk akses anonim, biarkan DN dan kata sandi kosong.", "Password" => "Sandi", "For anonymous access, leave DN and Password empty." => "Untuk akses anonim, biarkan DN dan Kata sandi kosong.", -"User Login Filter" => "gunakan saringan login", -"User List Filter" => "Daftar Filter Pengguna", -"Group Filter" => "saringan grup", +"One Base DN per line" => "Satu Base DN per baris", +"You can specify Base DN for users and groups in the Advanced tab" => "Anda dapat menetapkan Base DN untuk pengguna dan grup dalam tab Lanjutan", +"Back" => "Kembali", +"Continue" => "Lanjutkan", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Peringatan:</b> Modul LDAP PHP tidak terpasang, perangkat tidak akan bekerja. Silakan minta administrator sistem untuk memasangnya.", "Connection Settings" => "Pengaturan Koneksi", "Configuration Active" => "Konfigurasi Aktif", "When unchecked, this configuration will be skipped." => "Jika tidak dicentang, konfigurasi ini dilewati.", -"Port" => "port", "Backup (Replica) Host" => "Host Cadangan (Replika)", "Give an optional backup host. It must be a replica of the main LDAP/AD server." => "Berikan pilihan host cadangan. Harus merupakan replika dari server LDAP/AD utama.", "Backup (Replica) Port" => "Port Cadangan (Replika)", "Disable Main Server" => "Nonaktifkan Server Utama", -"Use TLS" => "gunakan TLS", -"Do not use it additionally for LDAPS connections, it will fail." => "Jangan gunakan utamanya untuk koneksi LDAPS, koneksi akan gagal.", "Case insensitve LDAP server (Windows)" => "Server LDAP dengan kapitalisasi tidak sensitif (Windows)", "Turn off SSL certificate validation." => "matikan validasi sertivikat SSL", "Cache Time-To-Live" => "Gunakan Tembolok untuk Time-To-Live", @@ -60,8 +60,6 @@ $TRANSLATIONS = array( "in bytes" => "dalam bytes", "Email Field" => "Bidang Email", "User Home Folder Naming Rule" => "Aturan Penamaan Folder Home Pengguna", -"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "Biarkan nama pengguna kosong (default). Atau tetapkan atribut LDAP/AD.", -"Test Configuration" => "Uji Konfigurasi", -"Help" => "Bantuan" +"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "Biarkan nama pengguna kosong (default). Atau tetapkan atribut LDAP/AD." ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/user_ldap/l10n/is.php b/apps/user_ldap/l10n/is.php index 70c6bb61570..e146c93cb81 100644 --- a/apps/user_ldap/l10n/is.php +++ b/apps/user_ldap/l10n/is.php @@ -2,9 +2,12 @@ $TRANSLATIONS = array( "Keep settings?" => "Geyma stillingar ?", "Error" => "Villa", -"Host" => "Netþjónn", -"Password" => "Lykilorð", +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("",""), +"Save" => "Vista", "Test Configuration" => "Prúfa uppsetningu", -"Help" => "Hjálp" +"Help" => "Hjálp", +"Host" => "Netþjónn", +"Password" => "Lykilorð" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/it.php b/apps/user_ldap/l10n/it.php index 4b47846f227..f5e53bdbe90 100644 --- a/apps/user_ldap/l10n/it.php +++ b/apps/user_ldap/l10n/it.php @@ -4,7 +4,11 @@ $TRANSLATIONS = array( "Failed to delete the server configuration" => "Eliminazione della configurazione del server non riuscita", "The configuration is valid and the connection could be established!" => "La configurazione è valida e la connessione può essere stabilita.", "The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "La configurazione è valida, ma il Bind non è riuscito. Controlla le impostazioni del server e le credenziali.", -"The configuration is invalid. Please look in the ownCloud log for further details." => "La configurazione non è valida. Controlla il log di ownCloud per ulteriori dettagli.", +"The configuration is invalid. Please have a look at the logs for further details." => "La configurazione non è valida. Controlla i log per ulteriori dettagli.", +"No action specified" => "Nessuna azione specificata", +"No configuration specified" => "Nessuna configurazione specificata", +"No data specified" => "Nessun dato specificato", +" Could not set configuration %s" => "Impossibile impostare la configurazione %s", "Deletion failed" => "Eliminazione non riuscita", "Take over settings from recent server configuration?" => "Vuoi recuperare le impostazioni dalla configurazione recente del server?", "Keep settings?" => "Vuoi mantenere le impostazioni?", @@ -12,40 +16,60 @@ $TRANSLATIONS = array( "mappings cleared" => "associazioni cancellate", "Success" => "Riuscito", "Error" => "Errore", +"Configuration OK" => "Configurazione corretta", +"Configuration incorrect" => "Configurazione non corretta", +"Configuration incomplete" => "Configurazione incompleta", +"Select groups" => "Seleziona i gruppi", +"Select object classes" => "Seleziona le classi di oggetti", +"Select attributes" => "Seleziona gli attributi", "Connection test succeeded" => "Prova di connessione riuscita", "Connection test failed" => "Prova di connessione non riuscita", "Do you really want to delete the current Server Configuration?" => "Vuoi davvero eliminare la configurazione attuale del server?", "Confirm Deletion" => "Conferma l'eliminazione", -"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Avviso:</b> le applicazioni user_ldap e user_webdavauth sono incompatibili. Potresti riscontrare un comportamento inatteso. Chiedi al tuo amministratore di sistema di disabilitarne una.", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Avviso:</b> il modulo PHP LDAP non è installato, il motore non funzionerà. Chiedi al tuo amministratore di sistema di installarlo.", -"Server configuration" => "Configurazione del server", +"_%s group found_::_%s groups found_" => array("%s gruppo trovato","%s gruppi trovati"), +"_%s user found_::_%s users found_" => array("%s utente trovato","%s utenti trovati"), +"Invalid Host" => "Host non valido", +"Could not find the desired feature" => "Impossibile trovare la funzionalità desiderata", +"Save" => "Salva", +"Test Configuration" => "Prova configurazione", +"Help" => "Aiuto", +"Limit the access to %s to groups meeting this criteria:" => "Limita l'accesso a %s ai gruppi che verificano questi criteri:", +"only those object classes:" => "solo queste classi di oggetti:", +"only from those groups:" => "solo da questi gruppi:", +"Edit raw filter instead" => "Modifica invece il filtro grezzo", +"Raw LDAP filter" => "Filtro LDAP grezzo", +"The filter specifies which LDAP groups shall have access to the %s instance." => "Il filtro specifica quali gruppi LDAP devono avere accesso all'istanza %s.", +"groups found" => "gruppi trovati", +"What attribute shall be used as login name:" => "Quale attributo deve essere usato come nome di accesso:", +"LDAP Username:" => "Nome utente LDAP:", +"LDAP Email Address:" => "Indirizzo email LDAP:", +"Other Attributes:" => "Altri attributi:", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Specifica quale filtro utilizzare quando si tenta l'accesso. %%uid sostituisce il nome utente all'atto dell'accesso. Esempio: \"uid=%%uid\"", "Add Server Configuration" => "Aggiungi configurazione del server", "Host" => "Host", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "È possibile omettere il protocollo, ad eccezione se è necessario SSL. Quindi inizia con ldaps://", -"Base DN" => "DN base", -"One Base DN per line" => "Un DN base per riga", -"You can specify Base DN for users and groups in the Advanced tab" => "Puoi specificare una DN base per gli utenti ed i gruppi nella scheda Avanzate", +"Port" => "Porta", "User DN" => "DN utente", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "Il DN per il client dell'utente con cui deve essere associato, ad esempio uid=agent,dc=example,dc=com. Per l'accesso anonimo, lasciare vuoti i campi DN e Password", "Password" => "Password", "For anonymous access, leave DN and Password empty." => "Per l'accesso anonimo, lasciare vuoti i campi DN e Password", -"User Login Filter" => "Filtro per l'accesso utente", -"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Specifica quale filtro utilizzare quando si tenta l'accesso. %%uid sostituisce il nome utente all'atto dell'accesso. Esempio: \"uid=%%uid\"", -"User List Filter" => "Filtro per l'elenco utenti", -"Defines the filter to apply, when retrieving users (no placeholders). Example: \"objectClass=person\"" => "Specifica quale filtro utilizzare durante il recupero degli utenti (nessun segnaposto). Esempio: \"objectClass=person\"", -"Group Filter" => "Filtro per il gruppo", -"Defines the filter to apply, when retrieving groups (no placeholders). Example: \"objectClass=posixGroup\"" => "Specifica quale filtro utilizzare durante il recupero dei gruppi (nessun segnaposto). Esempio: \"objectClass=posixGroup\"", +"One Base DN per line" => "Un DN base per riga", +"You can specify Base DN for users and groups in the Advanced tab" => "Puoi specificare una DN base per gli utenti ed i gruppi nella scheda Avanzate", +"Limit the access to %s to users meeting this criteria:" => "Limita l'accesso a %s ai gruppi che verificano questi criteri:", +"The filter specifies which LDAP users shall have access to the %s instance." => "Il filtro specifica quali utenti LDAP devono avere accesso all'istanza %s.", +"users found" => "utenti trovati", +"Back" => "Indietro", +"Continue" => "Continua", +"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Avviso:</b> le applicazioni user_ldap e user_webdavauth sono incompatibili. Potresti riscontrare un comportamento inatteso. Chiedi al tuo amministratore di sistema di disabilitarne una.", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Avviso:</b> il modulo PHP LDAP non è installato, il motore non funzionerà. Chiedi al tuo amministratore di sistema di installarlo.", "Connection Settings" => "Impostazioni di connessione", "Configuration Active" => "Configurazione attiva", "When unchecked, this configuration will be skipped." => "Se deselezionata, questa configurazione sarà saltata.", -"Port" => "Porta", "Backup (Replica) Host" => "Host di backup (Replica)", "Give an optional backup host. It must be a replica of the main LDAP/AD server." => "Fornisci un host di backup opzionale. Deve essere una replica del server AD/LDAP principale.", "Backup (Replica) Port" => "Porta di backup (Replica)", "Disable Main Server" => "Disabilita server principale", "Only connect to the replica server." => "Collegati solo al server di replica.", -"Use TLS" => "Usa TLS", -"Do not use it additionally for LDAPS connections, it will fail." => "Da non utilizzare per le connessioni LDAPS, non funzionerà.", "Case insensitve LDAP server (Windows)" => "Case insensitve LDAP server (Windows)", "Turn off SSL certificate validation." => "Disattiva il controllo del certificato SSL.", "Not recommended, use it for testing only! If connection only works with this option, import the LDAP server's SSL certificate in your %s server." => "Non consigliata, da utilizzare solo per test! Se la connessione funziona solo con questa opzione, importa il certificate SSL del server LDAP sul tuo server %s.", @@ -76,12 +100,11 @@ $TRANSLATIONS = array( "Internal Username Attribute:" => "Attributo nome utente interno:", "Override UUID detection" => "Ignora rilevamento UUID", "By default, the UUID attribute is automatically detected. The UUID attribute is used to doubtlessly identify LDAP users and groups. Also, the internal username will be created based on the UUID, if not specified otherwise above. You can override the setting and pass an attribute of your choice. You must make sure that the attribute of your choice can be fetched for both users and groups and it is unique. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users and groups." => "In modo predefinito, l'attributo UUID viene rilevato automaticamente. L'attributo UUID è utilizzato per identificare senza alcun dubbio gli utenti e i gruppi LDAP. Inoltre, il nome utente interno sarà creato sulla base dell'UUID, se non è specificato in precedenza. Puoi ignorare l'impostazione e fornire un attributo di tua scelta. Assicurati che l'attributo scelto possa essere ottenuto sia per gli utenti che per i gruppi e che sia univoco. Lascialo vuoto per ottenere il comportamento predefinito. Le modifiche avranno effetto solo sui nuovi utenti e gruppi LDAP associati (aggiunti).", -"UUID Attribute:" => "Attributo UUID:", +"UUID Attribute for Users:" => "Attributo UUID per gli utenti:", +"UUID Attribute for Groups:" => "Attributo UUID per i gruppi:", "Username-LDAP User Mapping" => "Associazione Nome utente-Utente LDAP", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have a internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." => "I nomi utente sono utilizzati per archiviare e assegnare i (meta) dati. Per identificare con precisione e riconoscere gli utenti, ogni utente LDAP avrà un nome utente interno. Ciò richiede un'associazione tra il nome utente e l'utente LDAP. In aggiunta, il DN viene mantenuto in cache per ridurre l'interazione con LDAP, ma non è utilizzato per l'identificazione. Se il DN cambia, le modifiche saranno rilevate. Il nome utente interno è utilizzato dappertutto. La cancellazione delle associazioni lascerà tracce residue ovunque e interesserà esclusivamente la configurazione LDAP. Non cancellare mai le associazioni in un ambiente di produzione, ma solo in una fase sperimentale o di test.", "Clear Username-LDAP User Mapping" => "Cancella associazione Nome utente-Utente LDAP", -"Clear Groupname-LDAP Group Mapping" => "Cancella associazione Nome gruppo-Gruppo LDAP", -"Test Configuration" => "Prova configurazione", -"Help" => "Aiuto" +"Clear Groupname-LDAP Group Mapping" => "Cancella associazione Nome gruppo-Gruppo LDAP" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/ja_JP.php b/apps/user_ldap/l10n/ja_JP.php index e9ef2165bb3..8e98e80370d 100644 --- a/apps/user_ldap/l10n/ja_JP.php +++ b/apps/user_ldap/l10n/ja_JP.php @@ -4,7 +4,11 @@ $TRANSLATIONS = array( "Failed to delete the server configuration" => "サーバ設定の削除に失敗しました", "The configuration is valid and the connection could be established!" => "設定は有効であり、接続を確立しました!", "The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "設定は有効ですが、接続に失敗しました。サーバ設定と資格情報を確認して下さい。", -"The configuration is invalid. Please look in the ownCloud log for further details." => "設定は無効です。詳細は ownCloud のログを見て下さい。", +"The configuration is invalid. Please have a look at the logs for further details." => "設定が無効です。詳細はログを確認してください。", +"No action specified" => "アクションが指定されていません", +"No configuration specified" => "構成が指定されていません", +"No data specified" => "データが指定されていません", +" Could not set configuration %s" => "構成 %s を設定できませんでした", "Deletion failed" => "削除に失敗しました", "Take over settings from recent server configuration?" => "最近のサーバ設定から設定を引き継ぎますか?", "Keep settings?" => "設定を保持しますか?", @@ -12,40 +16,60 @@ $TRANSLATIONS = array( "mappings cleared" => "マッピングをクリアしました", "Success" => "成功", "Error" => "エラー", +"Configuration OK" => "設定OK", +"Configuration incorrect" => "設定に誤りがあります", +"Configuration incomplete" => "設定が不完全です", +"Select groups" => "グループを選択", +"Select object classes" => "オブジェクトクラスを選択", +"Select attributes" => "属性を選択", "Connection test succeeded" => "接続テストに成功しました", "Connection test failed" => "接続テストに失敗しました", "Do you really want to delete the current Server Configuration?" => "現在のサーバ設定を本当に削除してもよろしいですか?", "Confirm Deletion" => "削除の確認", -"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>警告:</b> user_ldap と user_webdavauth のアプリには互換性がありません。予期せぬ動作をする可能性があります。システム管理者にどちらかを無効にするよう問い合わせてください。", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>警告:</b> PHP LDAP モジュールがインストールされていません。バックエンドが正しく動作しません。システム管理者にインストールするよう問い合わせてください。", -"Server configuration" => "サーバ設定", +"_%s group found_::_%s groups found_" => array("%s グループが見つかりました"), +"_%s user found_::_%s users found_" => array("%s ユーザが見つかりました"), +"Invalid Host" => "無効なホスト", +"Could not find the desired feature" => "望ましい機能は見つかりませんでした", +"Save" => "保存", +"Test Configuration" => "設定をテスト", +"Help" => "ヘルプ", +"Limit the access to %s to groups meeting this criteria:" => "この基準に合致するグループに %s へのアクセスを制限:", +"only those object classes:" => "それらのオブジェクトクラスのみ:", +"only from those groups:" => "それらのグループからのみ:", +"Edit raw filter instead" => "フィルタを編集", +"Raw LDAP filter" => "LDAP フィルタ", +"The filter specifies which LDAP groups shall have access to the %s instance." => "フィルタは、どの LDAP グループが %s にアクセスするかを指定します。", +"groups found" => "グループが見つかりました", +"What attribute shall be used as login name:" => "ログイン名として利用する属性:", +"LDAP Username:" => "LDAP ユーザ名:", +"LDAP Email Address:" => "LDAP メールアドレス:", +"Other Attributes:" => "他の属性:", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "ログイン実行時に適用するフィルタを定義します。%%uid にはログイン操作におけるユーザ名が入ります。例: \"uid=%%uid\"", "Add Server Configuration" => "サーバ設定を追加", "Host" => "ホスト", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "SSL通信しない場合には、プロトコル名を省略することができます。そうでない場合には、ldaps:// から始めてください。", -"Base DN" => "ベースDN", -"One Base DN per line" => "1行に1つのベースDN", -"You can specify Base DN for users and groups in the Advanced tab" => "拡張タブでユーザとグループのベースDNを指定することができます。", +"Port" => "ポート", "User DN" => "ユーザDN", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "クライアントユーザーのDNは、特定のものに結びつけることはしません。 例えば uid=agent,dc=example,dc=com. だと匿名アクセスの場合、DNとパスワードは空のままです。", "Password" => "パスワード", "For anonymous access, leave DN and Password empty." => "匿名アクセスの場合は、DNとパスワードを空にしてください。", -"User Login Filter" => "ユーザログインフィルタ", -"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "ログイン実行時に適用するフィルタを定義します。%%uid にはログイン操作におけるユーザ名が入ります。例: \"uid=%%uid\"", -"User List Filter" => "ユーザリストフィルタ", -"Defines the filter to apply, when retrieving users (no placeholders). Example: \"objectClass=person\"" => "ユーザ取得時に適用するフィルタを定義します(プレースホルダ無し)。例: \"objectClass=person\"", -"Group Filter" => "グループフィルタ", -"Defines the filter to apply, when retrieving groups (no placeholders). Example: \"objectClass=posixGroup\"" => "グループ取得時に適用するフィルタを定義します(プレースホルダ無し)。例: \"objectClass=posixGroup\"", +"One Base DN per line" => "1行に1つのベースDN", +"You can specify Base DN for users and groups in the Advanced tab" => "拡張タブでユーザとグループのベースDNを指定することができます。", +"Limit the access to %s to users meeting this criteria:" => "この基準に合致するユーザに %s へのアクセスを制限:", +"The filter specifies which LDAP users shall have access to the %s instance." => "フィルタは、どの LDAP ユーザが %s にアクセスするかを指定します。", +"users found" => "ユーザが見つかりました", +"Back" => "戻る", +"Continue" => "続ける", +"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>警告:</b> user_ldap と user_webdavauth のアプリには互換性がありません。予期せぬ動作をする可能性があります。システム管理者にどちらかを無効にするよう問い合わせてください。", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>警告:</b> PHP LDAP モジュールがインストールされていません。バックエンドが正しく動作しません。システム管理者にインストールするよう問い合わせてください。", "Connection Settings" => "接続設定", "Configuration Active" => "設定はアクティブです", "When unchecked, this configuration will be skipped." => "チェックを外すと、この設定はスキップされます。", -"Port" => "ポート", "Backup (Replica) Host" => "バックアップ(レプリカ)ホスト", "Give an optional backup host. It must be a replica of the main LDAP/AD server." => "バックアップホストをオプションで指定することができます。メインのLDAP/ADサーバのレプリカである必要があります。", "Backup (Replica) Port" => "バックアップ(レプリカ)ポート", "Disable Main Server" => "メインサーバを無効にする", "Only connect to the replica server." => "レプリカサーバーにのみ接続します。", -"Use TLS" => "TLSを利用", -"Do not use it additionally for LDAPS connections, it will fail." => "LDAPS接続のために追加でそれを利用しないで下さい。失敗します。", "Case insensitve LDAP server (Windows)" => "大文字/小文字を区別しないLDAPサーバ(Windows)", "Turn off SSL certificate validation." => "SSL証明書の確認を無効にする。", "Not recommended, use it for testing only! If connection only works with this option, import the LDAP server's SSL certificate in your %s server." => "推奨されません、テストにおいてのみ使用してください!このオプションでのみ接続が動作する場合は、LDAP サーバのSSL証明書を %s サーバにインポートしてください。", @@ -76,12 +100,11 @@ $TRANSLATIONS = array( "Internal Username Attribute:" => "内部ユーザ名属性:", "Override UUID detection" => "UUID検出を再定義する", "By default, the UUID attribute is automatically detected. The UUID attribute is used to doubtlessly identify LDAP users and groups. Also, the internal username will be created based on the UUID, if not specified otherwise above. You can override the setting and pass an attribute of your choice. You must make sure that the attribute of your choice can be fetched for both users and groups and it is unique. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users and groups." => "デフォルトでは、UUID 属性は自動的に検出されます。UUID属性は、LDAPユーザとLDAPグループを間違いなく識別するために利用されます。また、もしこれを指定しない場合は、内部ユーザ名はUUIDに基づいて作成されます。この設定は再定義することができ、あなたの選択した属性を用いることができます。選択した属性がユーザとグループの両方に対して適用でき、かつユニークであることを確認してください。空であればデフォルトの振る舞いとなります。変更は、新しくマッピング(追加)されたLDAPユーザとLDAPグループに対してのみ有効となります。", -"UUID Attribute:" => "UUID属性:", +"UUID Attribute for Users:" => "ユーザの UUID 属性:", +"UUID Attribute for Groups:" => "グループの UUID 属性:", "Username-LDAP User Mapping" => "ユーザ名とLDAPユーザのマッピング", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have a internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." => "ユーザ名は(メタ)データの保存と割り当てに使用されます。ユーザを正確に識別して認識するために、個々のLDAPユーザは内部ユーザ名を持っています。これは、ユーザ名からLDAPユーザへのマッピングが必要であることを意味しています。この生成されたユーザ名は、LDAPユーザのUUIDにマッピングされます。加えて、DNがLDAPとのインタラクションを削減するためにキャッシュされますが、識別には利用されません。DNが変わった場合は、変更が検出されます。内部ユーザ名は全体に亘って利用されます。マッピングをクリアすると、いたるところに使われないままの物が残るでしょう。マッピングのクリアは設定に敏感ではありませんが、全てのLDAPの設定に影響を与えます!本番の環境では決してマッピングをクリアしないでください。テストもしくは実験の段階でのみマッピングのクリアを行なってください。", "Clear Username-LDAP User Mapping" => "ユーザ名とLDAPユーザのマッピングをクリアする", -"Clear Groupname-LDAP Group Mapping" => "グループ名とLDAPグループのマッピングをクリアする", -"Test Configuration" => "設定をテスト", -"Help" => "ヘルプ" +"Clear Groupname-LDAP Group Mapping" => "グループ名とLDAPグループのマッピングをクリアする" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/user_ldap/l10n/ka.php b/apps/user_ldap/l10n/ka.php index 3de4d3c722a..23b6c93df86 100644 --- a/apps/user_ldap/l10n/ka.php +++ b/apps/user_ldap/l10n/ka.php @@ -1,6 +1,8 @@ <?php $TRANSLATIONS = array( -"Password" => "პაროლი", -"Help" => "შველა" +"_%s group found_::_%s groups found_" => array(""), +"_%s user found_::_%s users found_" => array(""), +"Help" => "შველა", +"Password" => "პაროლი" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/user_ldap/l10n/ka_GE.php b/apps/user_ldap/l10n/ka_GE.php index 860e8933b0d..ffdf7655517 100644 --- a/apps/user_ldap/l10n/ka_GE.php +++ b/apps/user_ldap/l10n/ka_GE.php @@ -3,42 +3,40 @@ $TRANSLATIONS = array( "Failed to delete the server configuration" => "შეცდომა სერვერის კონფიგურაციის წაშლისას", "The configuration is valid and the connection could be established!" => "კონფიგურაცია მართებულია და კავშირი დამყარდება!", "The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "კონფიგურაცია მართებულია, მაგრამ მიერთება ვერ მოხერხდა. გთხოვთ შეამოწმოთ სერვერის პარამეტრები და აუთენთიკაციის პარამეტრები.", -"The configuration is invalid. Please look in the ownCloud log for further details." => "კონფიგურაცია არ არის მართებული. გთხოვთ ჩაიხედოთ დეტალური ინფორმაციისთვის ownCloud –ის ლოგში.", "Deletion failed" => "წაშლა ვერ განხორციელდა", "Take over settings from recent server configuration?" => "დაბრუნდებით სერვერის წინა კონფიგურაციაში?", "Keep settings?" => "დავტოვოთ პარამეტრები?", "Cannot add server configuration" => "სერვერის პარამეტრების დამატება ვერ მოხერხდა", "Success" => "დასრულდა", "Error" => "შეცდომა", +"Select groups" => "ჯგუფების არჩევა", "Connection test succeeded" => "კავშირის ტესტირება მოხერხდა", "Connection test failed" => "კავშირის ტესტირება ვერ მოხერხდა", "Do you really want to delete the current Server Configuration?" => "ნამდვილად გინდათ წაშალოთ სერვერის მიმდინარე პარამეტრები?", "Confirm Deletion" => "წაშლის დადასტურება", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>გაფრთხილება:</b> PHP LDAP მოდული არ არის ინსტალირებული, ბექენდი არ იმუშავებს. თხოვეთ თქვენს ადმინისტრატორს დააინსტალიროს ის.", -"Server configuration" => "სერვერის პარამეტრები", +"_%s group found_::_%s groups found_" => array(""), +"_%s user found_::_%s users found_" => array(""), +"Save" => "შენახვა", +"Test Configuration" => "კავშირის ტესტირება", +"Help" => "დახმარება", "Add Server Configuration" => "სერვერის პარამეტრების დამატება", "Host" => "ჰოსტი", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "თქვენ შეგიძლიათ გამოტოვოთ პროტოკოლი. გარდა ამისა გჭირდებათ SSL. შემდეგ დაიწყეთ ldaps://", -"Base DN" => "საწყისი DN", -"One Base DN per line" => "ერთი საწყისი DN ერთ ხაზზე", -"You can specify Base DN for users and groups in the Advanced tab" => "თქვენ შეგიძლიათ მიუთითოთ საწყისი DN მომხმარებლებისთვის და ჯგუფებისთვის Advanced ტაბში", +"Port" => "პორტი", "User DN" => "მომხმარებლის DN", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "მომხმარებლის DN რომელთანაც უნდა მოხდეს დაკავშირება მოხდება შემდეგნაირად მაგ: uid=agent,dc=example,dc=com. ხოლო ანონიმური დაშვებისთვის, დატოვეთ DN–ის და პაროლის ველები ცარიელი.", "Password" => "პაროლი", "For anonymous access, leave DN and Password empty." => "ანონიმური დაშვებისთვის, დატოვეთ DN–ის და პაროლის ველები ცარიელი.", -"User Login Filter" => "მომხმარებლის ფილტრი", -"User List Filter" => "მომხმარებლებიის სიის ფილტრი", -"Group Filter" => "ჯგუფის ფილტრი", +"One Base DN per line" => "ერთი საწყისი DN ერთ ხაზზე", +"You can specify Base DN for users and groups in the Advanced tab" => "თქვენ შეგიძლიათ მიუთითოთ საწყისი DN მომხმარებლებისთვის და ჯგუფებისთვის Advanced ტაბში", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>გაფრთხილება:</b> PHP LDAP მოდული არ არის ინსტალირებული, ბექენდი არ იმუშავებს. თხოვეთ თქვენს ადმინისტრატორს დააინსტალიროს ის.", "Connection Settings" => "კავშირის პარამეტრები", "Configuration Active" => "კონფიგურაცია აქტიურია", "When unchecked, this configuration will be skipped." => "როცა გადანიშნულია, ეს კონფიგურაცია გამოტოვებული იქნება.", -"Port" => "პორტი", "Backup (Replica) Host" => "ბექაფ (რეპლიკა) ჰოსტი", "Give an optional backup host. It must be a replica of the main LDAP/AD server." => "მიუთითეთ რაიმე ბექაფ ჰოსტი. ის უნდა იყოს ძირითადი LDAP/AD სერვერის რეპლიკა.", "Backup (Replica) Port" => "ბექაფ (რეპლიკა) პორტი", "Disable Main Server" => "გამორთეთ ძირითადი სერვერი", -"Use TLS" => "გამოიყენეთ TLS", -"Do not use it additionally for LDAPS connections, it will fail." => "არ გამოიყენოთ დამატებით LDAPS კავშირი. ის წარუმატებლად დასრულდება.", "Case insensitve LDAP server (Windows)" => "LDAP server (Windows)", "Turn off SSL certificate validation." => "გამორთეთ SSL სერთიფიკატის ვალიდაცია.", "Cache Time-To-Live" => "ქეშის სიცოცხლის ხანგრძლივობა", @@ -60,8 +58,6 @@ $TRANSLATIONS = array( "in bytes" => "ბაიტებში", "Email Field" => "იმეილის ველი", "User Home Folder Naming Rule" => "მომხმარებლის Home დირექტორიის სახელების დარქმევის წესი", -"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "დატოვეთ ცარიელი მომხმარებლის სახელი (default). სხვა დანარჩენში მიუთითეთ LDAP/AD ატრიბუტი.", -"Test Configuration" => "კავშირის ტესტირება", -"Help" => "დახმარება" +"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "დატოვეთ ცარიელი მომხმარებლის სახელი (default). სხვა დანარჩენში მიუთითეთ LDAP/AD ატრიბუტი." ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/user_ldap/l10n/km.php b/apps/user_ldap/l10n/km.php new file mode 100644 index 00000000000..bba52d53a1a --- /dev/null +++ b/apps/user_ldap/l10n/km.php @@ -0,0 +1,6 @@ +<?php +$TRANSLATIONS = array( +"_%s group found_::_%s groups found_" => array(""), +"_%s user found_::_%s users found_" => array("") +); +$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/user_ldap/l10n/kn.php b/apps/user_ldap/l10n/kn.php new file mode 100644 index 00000000000..bba52d53a1a --- /dev/null +++ b/apps/user_ldap/l10n/kn.php @@ -0,0 +1,6 @@ +<?php +$TRANSLATIONS = array( +"_%s group found_::_%s groups found_" => array(""), +"_%s user found_::_%s users found_" => array("") +); +$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/user_ldap/l10n/ko.php b/apps/user_ldap/l10n/ko.php index a5a2798165c..2d861f27ba8 100644 --- a/apps/user_ldap/l10n/ko.php +++ b/apps/user_ldap/l10n/ko.php @@ -1,45 +1,110 @@ <?php $TRANSLATIONS = array( +"Failed to clear the mappings." => "매핑을 비울 수 없습니다.", +"Failed to delete the server configuration" => "서버 설정을 삭제할 수 없습니다.", +"The configuration is valid and the connection could be established!" => "설정 정보가 올바르고 연결할 수 있습니다!", +"The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "설정 정보가 올바르지만 바인딩이 실패하였습니다. 서버 설정과 인증 정보를 확인하십시오.", +"The configuration is invalid. Please have a look at the logs for further details." => "설정이 올바르지 않습니다. 자세한 사항은 로그를 참고하십시오.", +"No action specified" => "동작이 지정되지 않음", +"No configuration specified" => "설정이 지정되지 않음", +"No data specified" => "데이터가 지정되지 않음", +" Could not set configuration %s" => " 설정 %s을(를) 지정할 수 없음", "Deletion failed" => "삭제 실패", -"Keep settings?" => "설정을 유지합니까?", +"Take over settings from recent server configuration?" => "최근 서버 설정을 다시 불러오시겠습니까?", +"Keep settings?" => "설정을 유지하겠습니까?", +"Cannot add server configuration" => "서버 설정을 추가할 수 없음", +"mappings cleared" => "매핑 삭제됨", +"Success" => "성공", "Error" => "오류", +"Configuration OK" => "설정 올바름", +"Configuration incorrect" => "설정 올바르지 않음", +"Configuration incomplete" => "설정 불완전함", +"Select groups" => "그룹 선택", +"Select object classes" => "객체 클래스 선택", +"Select attributes" => "속성 선택", "Connection test succeeded" => "연결 시험 성공", "Connection test failed" => "연결 시험 실패", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>경고:</b> PHP LDAP 모듈이 비활성화되어 있거나 설치되어 있지 않습니다. 백엔드를 사용할 수 없습니다. 시스템 관리자에게 설치를 요청하십시오.", +"Do you really want to delete the current Server Configuration?" => "현재 서버 설정을 지우시겠습니까?", +"Confirm Deletion" => "삭제 확인", +"_%s group found_::_%s groups found_" => array("그룹 %s개 찾음"), +"_%s user found_::_%s users found_" => array("사용자 %s명 찾음"), +"Invalid Host" => "잘못된 호스트", +"Could not find the desired feature" => "필요한 기능을 찾을 수 없음", +"Save" => "저장", +"Test Configuration" => "설정 시험", +"Help" => "도움말", +"Limit the access to %s to groups meeting this criteria:" => "다음 조건을 만족하는 그룹만 %s 접근 허용:", +"only those object classes:" => "다음 객체 클래스만:", +"only from those groups:" => "다음 그룹에서만:", +"Edit raw filter instead" => "필터 직접 편집", +"Raw LDAP filter" => "LDAP 필터", +"The filter specifies which LDAP groups shall have access to the %s instance." => "이 필터는 %s에 접근할 수 있는 LDAP 그룹을 설정합니다.", +"groups found" => "그룹 찾음", +"What attribute shall be used as login name:" => "로그인 이름으로 사용할 속성:", +"LDAP Username:" => "LDAP 사용자 이름:", +"LDAP Email Address:" => "LDAP 이메일 주소:", +"Other Attributes:" => "기타 속성:", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "로그인을 시도할 때 적용할 필터를 입력하십시오. %%uid는 로그인 동작의 사용자 이름으로 대체됩니다. 예: \"uid=%%uid\"", +"Add Server Configuration" => "서버 설정 추가", "Host" => "호스트", -"You can omit the protocol, except you require SSL. Then start with ldaps://" => "SSL을 사용하는 경우가 아니라면 프로토콜을 입력하지 않아도 됩니다. SSL을 사용하려면 ldaps://를 입력하십시오.", -"Base DN" => "기본 DN", -"One Base DN per line" => "기본 DN을 한 줄에 하나씩 입력하십시오", -"You can specify Base DN for users and groups in the Advanced tab" => "고급 탭에서 사용자 및 그룹에 대한 기본 DN을 지정할 수 있습니다.", +"You can omit the protocol, except you require SSL. Then start with ldaps://" => "SSL을 사용하지 않으면 프로토콜을 입력하지 않아도 됩니다. SSL을 사용하려면 ldaps://를 입력하십시오.", +"Port" => "포트", "User DN" => "사용자 DN", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "바인딩 작업을 수행할 클라이언트 사용자 DN입니다. 예를 들어서 uid=agent,dc=example,dc=com입니다. 익명 접근을 허용하려면 DN과 암호를 비워 두십시오.", "Password" => "암호", "For anonymous access, leave DN and Password empty." => "익명 접근을 허용하려면 DN과 암호를 비워 두십시오.", -"User Login Filter" => "사용자 로그인 필터", -"User List Filter" => "사용자 목록 필터", -"Group Filter" => "그룹 필터", +"One Base DN per line" => "기본 DN을 한 줄에 하나씩 입력하십시오", +"You can specify Base DN for users and groups in the Advanced tab" => "고급 탭에서 사용자 및 그룹에 대한 기본 DN을 지정할 수 있습니다.", +"Limit the access to %s to users meeting this criteria:" => "다음 조건을 만족하는 사용자만 %s 접근 허용:", +"The filter specifies which LDAP users shall have access to the %s instance." => "이 필터는 %s에 접근할 수 있는 LDAP 사용자를 설정합니다.", +"users found" => "사용자 찾음", +"Back" => "뒤로", +"Continue" => "계속", +"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>경고:</b> user_ldap, user_webdavauth 앱은 서로 호환되지 않습니다. 예상하지 못한 행동을 할 수도 있습니다. 시스템 관리자에게 연락하여 둘 중 하나의 앱의 사용을 중단하십시오.", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>경고:</b> PHP LDAP 모듈이 비활성화되어 있거나 설치되어 있지 않습니다. 백엔드를 사용할 수 없습니다. 시스템 관리자에게 설치를 요청하십시오.", "Connection Settings" => "연결 설정", -"Configuration Active" => "구성 활성화", -"Port" => "포트", -"Backup (Replica) Host" => "백업 (복제) 포트", +"Configuration Active" => "구성 활성", +"When unchecked, this configuration will be skipped." => "선택하지 않으면 이 설정을 무시합니다.", +"Backup (Replica) Host" => "백업 (복제) 호스트", +"Give an optional backup host. It must be a replica of the main LDAP/AD server." => "추가적인 백업 호스트를 지정합니다. 기본 LDAP/AD 서버의 복사본이어야 합니다.", "Backup (Replica) Port" => "백업 (복제) 포트", "Disable Main Server" => "주 서버 비활성화", -"Use TLS" => "TLS 사용", +"Only connect to the replica server." => "복제 서버에만 연결합니다.", "Case insensitve LDAP server (Windows)" => "서버에서 대소문자를 구분하지 않음 (Windows)", "Turn off SSL certificate validation." => "SSL 인증서 유효성 검사를 해제합니다.", -"in seconds. A change empties the cache." => "초. 항목 변경 시 캐시가 갱신됩니다.", -"Directory Settings" => "디렉토리 설정", +"Not recommended, use it for testing only! If connection only works with this option, import the LDAP server's SSL certificate in your %s server." => "테스트 목적으로만 사용하십시오! 이 옵션을 사용해야만 연결할 수 있으면 %s 서버에 LDAP 서버의 SSL 인증서를 설치하십시오.", +"Cache Time-To-Live" => "캐시 유지 시간", +"in seconds. A change empties the cache." => "초 단위입니다. 항목 변경 시 캐시가 갱신됩니다.", +"Directory Settings" => "디렉터리 설정", "User Display Name Field" => "사용자의 표시 이름 필드", +"The LDAP attribute to use to generate the user's display name." => "사용자 표시 이름을 생성할 때 사용할 LDAP 속성입니다.", "Base User Tree" => "기본 사용자 트리", "One User Base DN per line" => "사용자 DN을 한 줄에 하나씩 입력하십시오", "User Search Attributes" => "사용자 검색 속성", +"Optional; one attribute per line" => "추가적, 한 줄에 하나의 속성을 입력하십시오", "Group Display Name Field" => "그룹의 표시 이름 필드", +"The LDAP attribute to use to generate the groups's display name." => "그룹 표시 이름을 생성할 때 사용할 LDAP 속성입니다.", "Base Group Tree" => "기본 그룹 트리", "One Group Base DN per line" => "그룹 기본 DN을 한 줄에 하나씩 입력하십시오", "Group Search Attributes" => "그룹 검색 속성", "Group-Member association" => "그룹-회원 연결", -"in bytes" => "바이트", +"Special Attributes" => "특수 속성", +"Quota Field" => "할당량 필드", +"Quota Default" => "기본 할당량", +"in bytes" => "바이트 단위", +"Email Field" => "이메일 필드", +"User Home Folder Naming Rule" => "사용자 홈 폴더 이름 규칙", "Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "사용자 이름을 사용하려면 비워 두십시오(기본값). 기타 경우 LDAP/AD 속성을 지정하십시오.", -"Help" => "도움말" +"Internal Username" => "내부 사용자 이름", +"By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. To achieve a similar behavior as before ownCloud 5 enter the user display name attribute in the following field. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users." => "기본적으로 내부 사용자 이름은 UUID 속성에서 생성됩니다. 사용자 이름이 중복되지 않고 문자열을 변환할 필요가 없도록 합니다. 내부 사용자 이름에는 다음과 같은 문자열만 사용할 수 있습니다: [a-zA-Z0-9_.@-] 다른 문자열은 ASCII에 해당하는 문자열로 변경되거나 없는 글자로 취급됩니다. 충돌하는 경우 숫자가 붙거나 증가합니다. 내부 사용자 이름은 내부적으로 사용자를 식별하는 데 사용되며, 사용자 홈 폴더의 기본 이름입니다. 또한 *DAV와 같은 외부 URL의 일부로 사용됩니다. 이 설정을 사용하면 기본 설정을 재정의할 수 있습니다. ownCloud 5 이전의 행동을 사용하려면 아래 필드에 사용자의 표시 이름 속성을 입력하십시오. 비워 두면 기본 설정을 사용합니다. 새로 추가되거나 매핑된 LDAP 사용자에게만 적용됩니다.", +"Internal Username Attribute:" => "내부 사용자 이름 속성:", +"Override UUID detection" => "UUID 확인 재정의", +"By default, the UUID attribute is automatically detected. The UUID attribute is used to doubtlessly identify LDAP users and groups. Also, the internal username will be created based on the UUID, if not specified otherwise above. You can override the setting and pass an attribute of your choice. You must make sure that the attribute of your choice can be fetched for both users and groups and it is unique. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users and groups." => "기본적으로 UUID 속성은 자동적으로 감지됩니다. UUID 속성은 LDAP 사용자와 그룹을 정확히 식별하는 데 사용됩니다. 지정하지 않은 경우 내부 사용자 이름은 UUID를 기반으로 생성됩니다. 이 설정을 다시 정의하고 임의의 속성을 지정할 수 있습니다. 사용자와 그룹 모두에게 속성을 적용할 수 있고 중복된 값이 없는지 확인하십시오. 비워 두면 기본 설정을 사용합니다. 새로 추가되거나 매핑된 LDAP 사용자와 그룹에만 적용됩니다.", +"UUID Attribute for Users:" => "사용자 UUID 속성:", +"UUID Attribute for Groups:" => "그룹 UUID 속성:", +"Username-LDAP User Mapping" => "사용자 이름-LDAP 사용자 매핑", +"Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have a internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." => "사용자 이름은 (메타) 데이터를 저장하고 할당하는 데 사용됩니다. 사용자를 정확하게 식별하기 위하여 각각 LDAP 사용자는 내부 사용자 이름을 갖습니다. 이는 사용자 이름과 LDAP 사용자 간의 매핑이 필요합니다. 생성된 사용자 이름은 LDAP 사용자의 UUID로 매핑됩니다. 추가적으로 LDAP 통신을 줄이기 위해서 DN이 캐시에 저장되지만 식별에 사용되지는 않습니다. DN이 변경되면 변경 사항이 기록됩니다. 내부 사용자 이름은 계속 사용됩니다. 매핑을 비우면 흔적이 남아 있게 됩니다. 매핑을 비우는 작업은 모든 LDAP 설정에 영향을 줍니다! 테스트 및 실험 단계에만 사용하고, 사용 중인 서버에서는 시도하지 마십시오.", +"Clear Username-LDAP User Mapping" => "사용자 이름-LDAP 사용자 매핑 비우기", +"Clear Groupname-LDAP Group Mapping" => "그룹 이름-LDAP 그룹 매핑 비우기" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/user_ldap/l10n/ku_IQ.php b/apps/user_ldap/l10n/ku_IQ.php index d211e9554a8..7d3b22f8494 100644 --- a/apps/user_ldap/l10n/ku_IQ.php +++ b/apps/user_ldap/l10n/ku_IQ.php @@ -2,7 +2,10 @@ $TRANSLATIONS = array( "Success" => "سهرکهوتن", "Error" => "ههڵه", -"Password" => "وشەی تێپەربو", -"Help" => "یارمەتی" +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("",""), +"Save" => "پاشکهوتکردن", +"Help" => "یارمەتی", +"Password" => "وشەی تێپەربو" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/lb.php b/apps/user_ldap/l10n/lb.php index 0a268bbb391..c6fdc003548 100644 --- a/apps/user_ldap/l10n/lb.php +++ b/apps/user_ldap/l10n/lb.php @@ -2,7 +2,13 @@ $TRANSLATIONS = array( "Deletion failed" => "Konnt net läschen", "Error" => "Fehler", +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("",""), +"Save" => "Späicheren", +"Help" => "Hëllef", +"Host" => "Host", "Password" => "Passwuert", -"Help" => "Hëllef" +"Back" => "Zeréck", +"Continue" => "Weider" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/lt_LT.php b/apps/user_ldap/l10n/lt_LT.php index f0522016825..c20bf679d0f 100644 --- a/apps/user_ldap/l10n/lt_LT.php +++ b/apps/user_ldap/l10n/lt_LT.php @@ -2,35 +2,39 @@ $TRANSLATIONS = array( "Failed to clear the mappings." => "Nepavyko išvalyti sąsajų.", "Failed to delete the server configuration" => "Nepavyko pašalinti serverio konfigūracijos", +"The configuration is valid and the connection could be established!" => "Konfigūracija yra tinkama bei prisijungta sėkmingai!", "Deletion failed" => "Ištrinti nepavyko", "Keep settings?" => "Išlaikyti nustatymus?", +"Cannot add server configuration" => "Negalima pridėti serverio konfigūracijos", "mappings cleared" => "susiejimai išvalyti", "Success" => "Sėkmingai", "Error" => "Klaida", +"Select groups" => "Pasirinkti grupes", "Connection test succeeded" => "Ryšio patikrinimas pavyko", "Connection test failed" => "Ryšio patikrinimas nepavyko", "Do you really want to delete the current Server Configuration?" => "Ar tikrai norite ištrinti dabartinę serverio konfigūraciją?", "Confirm Deletion" => "Patvirtinkite trynimą", -"Server configuration" => "Serverio konfigūravimas", +"_%s group found_::_%s groups found_" => array("","",""), +"_%s user found_::_%s users found_" => array("","",""), +"Save" => "Išsaugoti", +"Test Configuration" => "Bandyti konfigūraciją", +"Help" => "Pagalba", "Add Server Configuration" => "Pridėti serverio konfigūraciją", "Host" => "Mazgas", -"Base DN" => "Bazinis DN", -"One Base DN per line" => "Vienas bazinis DN eilutėje", +"Port" => "Prievadas", "User DN" => "Naudotojas DN", "Password" => "Slaptažodis", "For anonymous access, leave DN and Password empty." => "Anoniminiam prisijungimui, palikite DN ir Slaptažodis laukus tuščius.", -"User Login Filter" => "Naudotojo prisijungimo filtras", -"User List Filter" => "Naudotojo sąrašo filtras", -"Group Filter" => "Grupės filtras", +"One Base DN per line" => "Vienas bazinis DN eilutėje", +"Back" => "Atgal", +"Continue" => "Tęsti", "Connection Settings" => "Ryšio nustatymai", "Configuration Active" => "Konfigūracija aktyvi", "When unchecked, this configuration will be skipped." => "Kai nepažymėta, ši konfigūracija bus praleista.", -"Port" => "Prievadas", "Backup (Replica) Host" => "Atsarginės kopijos (Replica) mazgas", "Backup (Replica) Port" => "Atsarginės kopijos (Replica) prievadas", "Disable Main Server" => "Išjungti pagrindinį serverį", "Only connect to the replica server." => "Tik prisijungti prie reprodukcinio (replica) serverio.", -"Use TLS" => "Naudoti TLS", "Turn off SSL certificate validation." => "Išjungti SSL sertifikato tikrinimą.", "Directory Settings" => "Katalogo nustatymai", "Base User Tree" => "Bazinis naudotojo medis", @@ -47,11 +51,8 @@ $TRANSLATIONS = array( "Internal Username" => "Vidinis naudotojo vardas", "Internal Username Attribute:" => "Vidinis naudotojo vardo atributas:", "Override UUID detection" => "Perrašyti UUID aptikimą", -"UUID Attribute:" => "UUID atributas:", "Username-LDAP User Mapping" => "Naudotojo vardo - LDAP naudotojo sąsaja", "Clear Username-LDAP User Mapping" => "Išvalyti naudotojo vardo - LDAP naudotojo sąsają", -"Clear Groupname-LDAP Group Mapping" => "Išvalyti grupės pavadinimo - LDAP naudotojo sąsają", -"Test Configuration" => "Bandyti konfigūraciją", -"Help" => "Pagalba" +"Clear Groupname-LDAP Group Mapping" => "Išvalyti grupės pavadinimo - LDAP naudotojo sąsają" ); $PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);"; diff --git a/apps/user_ldap/l10n/lv.php b/apps/user_ldap/l10n/lv.php index 11a68fffeb4..769f17e6338 100644 --- a/apps/user_ldap/l10n/lv.php +++ b/apps/user_ldap/l10n/lv.php @@ -3,41 +3,39 @@ $TRANSLATIONS = array( "Failed to delete the server configuration" => "Neizdevās izdzēst servera konfigurāciju", "The configuration is valid and the connection could be established!" => "Konfigurācija ir derīga un varēja izveidot savienojumu!", "The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "Konfigurācija ir derīga, bet sasaiste neizdevās. Lūdzu, pārbaudiet servera iestatījumus un akreditācijas datus.", -"The configuration is invalid. Please look in the ownCloud log for further details." => "Konfigurācija ir nederīga. Lūdzu, apskatiet ownCloud žurnālu, lai uzzinātu vairāk.", "Deletion failed" => "Neizdevās izdzēst", "Take over settings from recent server configuration?" => "Paņemt iestatījumus no nesenas servera konfigurācijas?", "Keep settings?" => "Paturēt iestatījumus?", "Cannot add server configuration" => "Nevar pievienot servera konfigurāciju", "Error" => "Kļūda", +"Select groups" => "Izvēlieties grupas", "Connection test succeeded" => "Savienojuma tests ir veiksmīgs", "Connection test failed" => "Savienojuma tests cieta neveiksmi", "Do you really want to delete the current Server Configuration?" => "Vai tiešām vēlaties dzēst pašreizējo servera konfigurāciju?", "Confirm Deletion" => "Apstiprināt dzēšanu", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Brīdinājums:</b> PHP LDAP modulis nav uzinstalēts, aizmugure nedarbosies. Lūdzu, prasiet savam sistēmas administratoram kādu no tām deaktivēt.", -"Server configuration" => "Servera konfigurācija", +"_%s group found_::_%s groups found_" => array("","",""), +"_%s user found_::_%s users found_" => array("","",""), +"Save" => "Saglabāt", +"Test Configuration" => "Testa konfigurācija", +"Help" => "Palīdzība", "Add Server Configuration" => "Pievienot servera konfigurāciju", "Host" => "Resursdators", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Var neiekļaut protokolu, izņemot, ja vajag SSL. Tad sākums ir ldaps://", -"Base DN" => "Bāzes DN", -"One Base DN per line" => "Viena bāzes DN rindā", -"You can specify Base DN for users and groups in the Advanced tab" => "Lietotājiem un grupām bāzes DN var norādīt cilnē “Paplašināti”", +"Port" => "Ports", "User DN" => "Lietotāja DN", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "Klienta lietotāja DN, ar ko veiks sasaisti, piemēram, uid=agent,dc=example,dc=com. Lai piekļūtu anonīmi, atstājiet DN un paroli tukšu.", "Password" => "Parole", "For anonymous access, leave DN and Password empty." => "Lai piekļūtu anonīmi, atstājiet DN un paroli tukšu.", -"User Login Filter" => "Lietotāja ierakstīšanās filtrs", -"User List Filter" => "Lietotāju saraksta filtrs", -"Group Filter" => "Grupu filtrs", +"One Base DN per line" => "Viena bāzes DN rindā", +"You can specify Base DN for users and groups in the Advanced tab" => "Lietotājiem un grupām bāzes DN var norādīt cilnē “Paplašināti”", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Brīdinājums:</b> PHP LDAP modulis nav uzinstalēts, aizmugure nedarbosies. Lūdzu, prasiet savam sistēmas administratoram kādu no tām deaktivēt.", "Connection Settings" => "Savienojuma iestatījumi", "Configuration Active" => "Konfigurācija ir aktīva", "When unchecked, this configuration will be skipped." => "Ja nav atzīmēts, šī konfigurācija tiks izlaista.", -"Port" => "Ports", "Backup (Replica) Host" => "Rezerves (kopija) serveris", "Give an optional backup host. It must be a replica of the main LDAP/AD server." => "Norādi rezerves serveri (nav obligāti). Tam ir jābūt galvenā LDAP/AD servera kopijai.", "Backup (Replica) Port" => "Rezerves (kopijas) ports", "Disable Main Server" => "Deaktivēt galveno serveri", -"Use TLS" => "Lietot TLS", -"Do not use it additionally for LDAPS connections, it will fail." => "Neizmanto papildu LDAPS savienojumus! Tas nestrādās.", "Case insensitve LDAP server (Windows)" => "Reģistrnejutīgs LDAP serveris (Windows)", "Turn off SSL certificate validation." => "Izslēgt SSL sertifikātu validēšanu.", "Cache Time-To-Live" => "Kešatmiņas dzīvlaiks", @@ -59,8 +57,6 @@ $TRANSLATIONS = array( "in bytes" => "baitos", "Email Field" => "E-pasta lauks", "User Home Folder Naming Rule" => "Lietotāja mājas mapes nosaukšanas kārtula", -"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "Atstāt tukšu lietotāja vārdam (noklusējuma). Citādi, norādi LDAP/AD atribūtu.", -"Test Configuration" => "Testa konfigurācija", -"Help" => "Palīdzība" +"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "Atstāt tukšu lietotāja vārdam (noklusējuma). Citādi, norādi LDAP/AD atribūtu." ); $PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);"; diff --git a/apps/user_ldap/l10n/mk.php b/apps/user_ldap/l10n/mk.php index 3d261c3d80c..fcbc01f137b 100644 --- a/apps/user_ldap/l10n/mk.php +++ b/apps/user_ldap/l10n/mk.php @@ -1,10 +1,21 @@ <?php $TRANSLATIONS = array( "Deletion failed" => "Бришењето е неуспешно", +"Keep settings?" => "Да ги сочувам нагодувањата?", +"Cannot add server configuration" => "Не можам да ја додадам конфигурацијата на серверот", "Error" => "Грешка", +"Connection test succeeded" => "Тестот за поврзување е успешен", +"Connection test failed" => "Тестот за поврзување не е успешен", +"Confirm Deletion" => "Потврдете го бришењето", +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("",""), +"Save" => "Сними", +"Help" => "Помош", "Host" => "Домаќин", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Може да го скокнете протколот освен ако не ви треба SSL. Тогаш ставете ldaps://", +"Port" => "Порта", "Password" => "Лозинка", -"Help" => "Помош" +"Back" => "Назад", +"Continue" => "Продолжи" ); $PLURAL_FORMS = "nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;"; diff --git a/apps/user_ldap/l10n/ml_IN.php b/apps/user_ldap/l10n/ml_IN.php new file mode 100644 index 00000000000..3a1e002311c --- /dev/null +++ b/apps/user_ldap/l10n/ml_IN.php @@ -0,0 +1,6 @@ +<?php +$TRANSLATIONS = array( +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("","") +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/ms_MY.php b/apps/user_ldap/l10n/ms_MY.php index 5d3f8019ceb..7010e8a8f50 100644 --- a/apps/user_ldap/l10n/ms_MY.php +++ b/apps/user_ldap/l10n/ms_MY.php @@ -2,7 +2,11 @@ $TRANSLATIONS = array( "Deletion failed" => "Pemadaman gagal", "Error" => "Ralat", +"_%s group found_::_%s groups found_" => array(""), +"_%s user found_::_%s users found_" => array(""), +"Save" => "Simpan", +"Help" => "Bantuan", "Password" => "Kata laluan", -"Help" => "Bantuan" +"Back" => "Kembali" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/user_ldap/l10n/my_MM.php b/apps/user_ldap/l10n/my_MM.php index 3d9c248f66a..ea1881f114f 100644 --- a/apps/user_ldap/l10n/my_MM.php +++ b/apps/user_ldap/l10n/my_MM.php @@ -1,6 +1,8 @@ <?php $TRANSLATIONS = array( -"Password" => "စကားဝှက်", -"Help" => "အကူအညီ" +"_%s group found_::_%s groups found_" => array(""), +"_%s user found_::_%s users found_" => array(""), +"Help" => "အကူအညီ", +"Password" => "စကားဝှက်" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/user_ldap/l10n/nb_NO.php b/apps/user_ldap/l10n/nb_NO.php index 8c482ed2a55..625ec79d76b 100644 --- a/apps/user_ldap/l10n/nb_NO.php +++ b/apps/user_ldap/l10n/nb_NO.php @@ -3,37 +3,37 @@ $TRANSLATIONS = array( "Failed to delete the server configuration" => "Klarte ikke å slette tjener-konfigurasjonen.", "The configuration is valid and the connection could be established!" => "Konfigurasjonen er i orden og tilkoblingen skal være etablert!", "The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "Konfigurasjonen er i orden, men Bind mislyktes. Vennligst sjekk tjener-konfigurasjonen og påloggingsinformasjonen.", -"The configuration is invalid. Please look in the ownCloud log for further details." => "Konfigurasjonen er ikke i orden. Vennligst se ownClouds logfil for flere detaljer.", "Deletion failed" => "Sletting mislyktes", "Take over settings from recent server configuration?" => "Hent innstillinger fra tidligere tjener-konfigurasjon?", "Keep settings?" => "Behold innstillinger?", "Cannot add server configuration" => "Kan ikke legge til tjener-konfigurasjon", "Success" => "Suksess", "Error" => "Feil", +"Select groups" => "Velg grupper", "Connection test succeeded" => "Tilkoblingstest lyktes", "Connection test failed" => "Tilkoblingstest mislyktes", "Do you really want to delete the current Server Configuration?" => "Er du sikker på at du vil slette aktiv tjener-konfigurasjon?", "Confirm Deletion" => "Bekreft sletting", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Warning:</b> PHP LDAP modulen er ikke installert, hjelperen vil ikke virke. Vennligst be din system-administrator om å installere den.", -"Server configuration" => "Tjener-konfigurasjon", +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("",""), +"Save" => "Lagre", +"Help" => "Hjelp", "Add Server Configuration" => "Legg til tjener-konfigurasjon", "Host" => "Tjener", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Du kan utelate protokollen, men du er påkrevd å bruke SSL. Deretter starte med ldaps://", -"Base DN" => "Base DN", -"One Base DN per line" => "En hoved DN pr. linje", -"You can specify Base DN for users and groups in the Advanced tab" => "Du kan spesifisere Base DN for brukere og grupper under Avansert fanen", +"Port" => "Port", "User DN" => "Bruker DN", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "DN nummeret til klienten som skal bindes til, f.eks. uid=agent,dc=example,dc=com. For anonym tilgang, la DN- og passord-feltet stå tomt.", "Password" => "Passord", "For anonymous access, leave DN and Password empty." => "For anonym tilgang, la DN- og passord-feltet stå tomt.", -"User Login Filter" => "Brukerpålogging filter", -"User List Filter" => "Brukerliste filter", -"Group Filter" => "Gruppefilter", +"One Base DN per line" => "En hoved DN pr. linje", +"You can specify Base DN for users and groups in the Advanced tab" => "Du kan spesifisere Base DN for brukere og grupper under Avansert fanen", +"Back" => "Tilbake", +"Continue" => "Fortsett", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Warning:</b> PHP LDAP modulen er ikke installert, hjelperen vil ikke virke. Vennligst be din system-administrator om å installere den.", "Configuration Active" => "Konfigurasjon aktiv", "When unchecked, this configuration will be skipped." => "Når ikke huket av så vil denne konfigurasjonen bli hoppet over.", -"Port" => "Port", "Backup (Replica) Host" => "Sikkerhetskopierings (Replica) vert", -"Use TLS" => "Bruk TLS", "Case insensitve LDAP server (Windows)" => "Case-insensitiv LDAP tjener (Windows)", "Turn off SSL certificate validation." => "Slå av SSL-sertifikat validering", "in seconds. A change empties the cache." => "i sekunder. En endring tømmer bufferen.", @@ -45,7 +45,6 @@ $TRANSLATIONS = array( "One Group Base DN per line" => "En gruppe hoved-DN pr. linje", "Group-Member association" => "gruppe-medlem assosiasjon", "in bytes" => "i bytes", -"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "La stå tom for brukernavn (standard). Ellers, spesifiser en LDAP/AD attributt.", -"Help" => "Hjelp" +"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "La stå tom for brukernavn (standard). Ellers, spesifiser en LDAP/AD attributt." ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/nds.php b/apps/user_ldap/l10n/nds.php new file mode 100644 index 00000000000..3a1e002311c --- /dev/null +++ b/apps/user_ldap/l10n/nds.php @@ -0,0 +1,6 @@ +<?php +$TRANSLATIONS = array( +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("","") +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/ne.php b/apps/user_ldap/l10n/ne.php new file mode 100644 index 00000000000..3a1e002311c --- /dev/null +++ b/apps/user_ldap/l10n/ne.php @@ -0,0 +1,6 @@ +<?php +$TRANSLATIONS = array( +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("","") +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/nl.php b/apps/user_ldap/l10n/nl.php index b56dcf15791..bfe96f4268c 100644 --- a/apps/user_ldap/l10n/nl.php +++ b/apps/user_ldap/l10n/nl.php @@ -4,7 +4,11 @@ $TRANSLATIONS = array( "Failed to delete the server configuration" => "Verwijderen serverconfiguratie mislukt", "The configuration is valid and the connection could be established!" => "De configuratie is geldig en de verbinding is geslaagd!", "The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "De configuratie is geldig, maar Bind mislukte. Controleer de serverinstellingen en inloggegevens.", -"The configuration is invalid. Please look in the ownCloud log for further details." => "De configuratie is ongeldig. Controleer de ownCloud log voor meer details.", +"The configuration is invalid. Please have a look at the logs for further details." => "De configuratie is ongeldig. Bekijk de logbestanden voor meer details.", +"No action specified" => "Geen actie opgegeven", +"No configuration specified" => "Geen configuratie opgegeven", +"No data specified" => "Geen gegevens verstrekt", +" Could not set configuration %s" => "Kon configuratie %s niet instellen", "Deletion failed" => "Verwijderen mislukt", "Take over settings from recent server configuration?" => "Overnemen instellingen van de recente serverconfiguratie?", "Keep settings?" => "Instellingen bewaren?", @@ -12,40 +16,60 @@ $TRANSLATIONS = array( "mappings cleared" => "vertaaltabel leeggemaakt", "Success" => "Succes", "Error" => "Fout", +"Configuration OK" => "Configuratie OK", +"Configuration incorrect" => "Configuratie onjuist", +"Configuration incomplete" => "Configuratie incompleet", +"Select groups" => "Selecteer groepen", +"Select object classes" => "Selecteer objectklasse", +"Select attributes" => "Selecteer attributen", "Connection test succeeded" => "Verbindingstest geslaagd", "Connection test failed" => "Verbindingstest mislukt", "Do you really want to delete the current Server Configuration?" => "Wilt u werkelijk de huidige Serverconfiguratie verwijderen?", "Confirm Deletion" => "Bevestig verwijderen", -"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Waarschuwing:</b> De Apps user_ldap en user_webdavauth zijn incompatible. U kunt onverwacht gedrag ervaren. Vraag uw beheerder om een van beide apps de deactiveren.", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Waarschuwing:</b> De PHP LDAP module is niet geïnstalleerd, het backend zal niet werken. Vraag uw systeembeheerder om de module te installeren.", -"Server configuration" => "Serverconfiguratie", +"_%s group found_::_%s groups found_" => array("%s groep gevonden","%s groepen gevonden"), +"_%s user found_::_%s users found_" => array("%s gebruiker gevonden","%s gebruikers gevonden"), +"Invalid Host" => "Ongeldige server", +"Could not find the desired feature" => "Kon de gewenste functie niet vinden", +"Save" => "Bewaren", +"Test Configuration" => "Test configuratie", +"Help" => "Help", +"Limit the access to %s to groups meeting this criteria:" => "Beperk toegang tot %s tot groepen die voldoen aan deze criteria:", +"only those object classes:" => "alleen deze objectklassen", +"only from those groups:" => "alleen van deze groepen:", +"Edit raw filter instead" => "Bewerk raw filter", +"Raw LDAP filter" => "Raw LDAP filter", +"The filter specifies which LDAP groups shall have access to the %s instance." => "Dit filter geeft aan welke LDAP groepen toegang hebben tot %s.", +"groups found" => "groepen gevonden", +"What attribute shall be used as login name:" => "Welk attribuut moet worden gebruikt als inlognaam:", +"LDAP Username:" => "LDAP Username:", +"LDAP Email Address:" => "LDAP e-mailadres:", +"Other Attributes:" => "Overige attributen:", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Definiëert het toe te passen filter als er geprobeerd wordt in te loggen. %%uid vervangt de gebruikersnaam bij het inloggen. Bijvoorbeeld: \"uid=%%uid\"", "Add Server Configuration" => "Toevoegen serverconfiguratie", "Host" => "Host", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Je kunt het protocol weglaten, tenzij je SSL vereist. Start in dat geval met ldaps://", -"Base DN" => "Base DN", -"One Base DN per line" => "Een Base DN per regel", -"You can specify Base DN for users and groups in the Advanced tab" => "Je kunt het Base DN voor gebruikers en groepen specificeren in het tab Geavanceerd.", +"Port" => "Poort", "User DN" => "User DN", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "De DN van de client gebruiker waarmee de verbinding zal worden gemaakt, bijv. uid=agent,dc=example,dc=com. Voor anonieme toegang laat je het DN en het wachtwoord leeg.", "Password" => "Wachtwoord", "For anonymous access, leave DN and Password empty." => "Voor anonieme toegang, laat de DN en het wachtwoord leeg.", -"User Login Filter" => "Gebruikers Login Filter", -"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Definiëert het toe te passen filter als er geprobeerd wordt in te loggen. %%uid vervangt de gebruikersnaam bij het inloggen. Bijvoorbeeld: \"uid=%%uid\"", -"User List Filter" => "Gebruikers Lijst Filter", -"Defines the filter to apply, when retrieving users (no placeholders). Example: \"objectClass=person\"" => "Definieert het toe te passen filter bij het ophalen van gebruikers (geen tijdelijke aanduidingen). Bijvoorbeeld: \"objectClass=person\"", -"Group Filter" => "Groep Filter", -"Defines the filter to apply, when retrieving groups (no placeholders). Example: \"objectClass=posixGroup\"" => "Definieert het toe te passen filter bij het ophalen van groepen (geen tijdelijke aanduidingen). Bijvoorbeeld: \"objectClass=posixGroup\"", +"One Base DN per line" => "Een Base DN per regel", +"You can specify Base DN for users and groups in the Advanced tab" => "Je kunt het Base DN voor gebruikers en groepen specificeren in het tab Geavanceerd.", +"Limit the access to %s to users meeting this criteria:" => "Beperk toegang tot %s tot gebruikers die voldoen aan deze criteria:", +"The filter specifies which LDAP users shall have access to the %s instance." => "Dit filter geeft aan welke LDAP gebruikers toegang hebben tot %s.", +"users found" => "gebruikers gevonden", +"Back" => "Terug", +"Continue" => "Verder", +"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Waarschuwing:</b> De Apps user_ldap en user_webdavauth zijn incompatible. U kunt onverwacht gedrag ervaren. Vraag uw beheerder om een van beide apps de deactiveren.", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Waarschuwing:</b> De PHP LDAP module is niet geïnstalleerd, het backend zal niet werken. Vraag uw systeembeheerder om de module te installeren.", "Connection Settings" => "Verbindingsinstellingen", "Configuration Active" => "Configuratie actief", "When unchecked, this configuration will be skipped." => "Als dit niet is ingeschakeld wordt deze configuratie overgeslagen.", -"Port" => "Poort", "Backup (Replica) Host" => "Backup (Replica) Host", "Give an optional backup host. It must be a replica of the main LDAP/AD server." => "Opgeven optionele backup host. Het moet een replica van de hoofd LDAP/AD server.", "Backup (Replica) Port" => "Backup (Replica) Poort", "Disable Main Server" => "Deactiveren hoofdserver", "Only connect to the replica server." => "Maak alleen een verbinding met de replica server.", -"Use TLS" => "Gebruik TLS", -"Do not use it additionally for LDAPS connections, it will fail." => "Gebruik het niet voor LDAPS verbindingen, dat gaat niet lukken.", "Case insensitve LDAP server (Windows)" => "Niet-hoofdlettergevoelige LDAP server (Windows)", "Turn off SSL certificate validation." => "Schakel SSL certificaat validatie uit.", "Not recommended, use it for testing only! If connection only works with this option, import the LDAP server's SSL certificate in your %s server." => "Niet aanbevolen, gebruik alleen om te testen! Als de connectie alleen werkt met deze optie, importeer dan het SSL-certificaat van de LDAP-server naar uw %s server.", @@ -76,12 +100,11 @@ $TRANSLATIONS = array( "Internal Username Attribute:" => "Interne gebruikersnaam attribuut:", "Override UUID detection" => "Negeren UUID detectie", "By default, the UUID attribute is automatically detected. The UUID attribute is used to doubtlessly identify LDAP users and groups. Also, the internal username will be created based on the UUID, if not specified otherwise above. You can override the setting and pass an attribute of your choice. You must make sure that the attribute of your choice can be fetched for both users and groups and it is unique. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users and groups." => "Standaard herkent ownCloud het UUID-attribuut automatisch. Het UUID attribuut wordt gebruikt om LDAP-gebruikers en -groepen uniek te identificeren. Ook zal de interne gebruikersnaam worden aangemaakt op basis van het UUID, tenzij deze hierboven anders is aangegeven. U kunt de instelling overschrijven en zelf een waarde voor het attribuut opgeven. U moet ervoor zorgen dat het ingestelde attribuut kan worden opgehaald voor zowel gebruikers als groepen en dat het uniek is. Laat het leeg voor standaard gedrag. Veranderingen worden alleen doorgevoerd op nieuw gekoppelde (toegevoegde) LDAP-gebruikers en-groepen.", -"UUID Attribute:" => "UUID Attribuut:", +"UUID Attribute for Users:" => "UUID attribuut voor gebruikers:", +"UUID Attribute for Groups:" => "UUID attribuut voor groepen:", "Username-LDAP User Mapping" => "Gebruikersnaam-LDAP gebruikers vertaling", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have a internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." => "ownCloud maakt gebruik van gebruikersnamen om (meta) data op te slaan en toe te wijzen. Om gebruikers uniek te identificeren, krijgt elke LDAP-gebruiker ook een interne gebruikersnaam. Dit vereist een koppeling van de ownCloud gebruikersnaam aan een LDAP-gebruiker. De gecreëerde gebruikersnaam is gekoppeld aan de UUID van de LDAP-gebruiker. Aanvullend wordt ook de 'DN' gecached om het aantal LDAP-interacties te verminderen, maar dit wordt niet gebruikt voor identificatie. Als de DN verandert, zullen de veranderingen worden gevonden. De interne naam wordt overal gebruikt. Het wissen van de koppeling zal overal resten achterlaten. Het wissen van koppelingen is niet configuratiegevoelig, maar het raakt wel alle LDAP instellingen! Zorg ervoor dat deze koppelingen nooit in een productieomgeving gewist worden. Maak ze alleen leeg in een test- of ontwikkelomgeving.", "Clear Username-LDAP User Mapping" => "Leegmaken Gebruikersnaam-LDAP gebruikers vertaling", -"Clear Groupname-LDAP Group Mapping" => "Leegmaken Groepsnaam-LDAP groep vertaling", -"Test Configuration" => "Test configuratie", -"Help" => "Help" +"Clear Groupname-LDAP Group Mapping" => "Leegmaken Groepsnaam-LDAP groep vertaling" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/nn_NO.php b/apps/user_ldap/l10n/nn_NO.php index 470114d9359..c8b7ec091b6 100644 --- a/apps/user_ldap/l10n/nn_NO.php +++ b/apps/user_ldap/l10n/nn_NO.php @@ -2,8 +2,14 @@ $TRANSLATIONS = array( "Deletion failed" => "Feil ved sletting", "Error" => "Feil", +"Select groups" => "Vel grupper", +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("",""), +"Save" => "Lagra", +"Help" => "Hjelp", "Host" => "Tenar", "Password" => "Passord", -"Help" => "Hjelp" +"Back" => "Tilbake", +"Continue" => "Gå vidare" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/nqo.php b/apps/user_ldap/l10n/nqo.php new file mode 100644 index 00000000000..bba52d53a1a --- /dev/null +++ b/apps/user_ldap/l10n/nqo.php @@ -0,0 +1,6 @@ +<?php +$TRANSLATIONS = array( +"_%s group found_::_%s groups found_" => array(""), +"_%s user found_::_%s users found_" => array("") +); +$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/user_ldap/l10n/oc.php b/apps/user_ldap/l10n/oc.php index 81df26117f1..3b3e8365a65 100644 --- a/apps/user_ldap/l10n/oc.php +++ b/apps/user_ldap/l10n/oc.php @@ -2,7 +2,10 @@ $TRANSLATIONS = array( "Deletion failed" => "Fracàs d'escafatge", "Error" => "Error", -"Password" => "Senhal", -"Help" => "Ajuda" +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("",""), +"Save" => "Enregistra", +"Help" => "Ajuda", +"Password" => "Senhal" ); $PLURAL_FORMS = "nplurals=2; plural=(n > 1);"; diff --git a/apps/user_ldap/l10n/pa.php b/apps/user_ldap/l10n/pa.php index ac486a8ca2f..b52a4a88005 100644 --- a/apps/user_ldap/l10n/pa.php +++ b/apps/user_ldap/l10n/pa.php @@ -1,6 +1,8 @@ <?php $TRANSLATIONS = array( "Error" => "ਗਲਤੀ", +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("",""), "Password" => "ਪਾਸਵਰ" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/pl.php b/apps/user_ldap/l10n/pl.php index 7801f73dc12..056718a027d 100644 --- a/apps/user_ldap/l10n/pl.php +++ b/apps/user_ldap/l10n/pl.php @@ -4,7 +4,6 @@ $TRANSLATIONS = array( "Failed to delete the server configuration" => "Nie można usunąć konfiguracji serwera", "The configuration is valid and the connection could be established!" => "Konfiguracja jest prawidłowa i można ustanowić połączenie!", "The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "Konfiguracja jest prawidłowa, ale Bind nie. Sprawdź ustawienia serwera i poświadczenia.", -"The configuration is invalid. Please look in the ownCloud log for further details." => "Konfiguracja jest nieprawidłowa. Proszę przejrzeć logi dziennika ownCloud ", "Deletion failed" => "Usunięcie nie powiodło się", "Take over settings from recent server configuration?" => "Przejmij ustawienia z ostatnich konfiguracji serwera?", "Keep settings?" => "Zachować ustawienia?", @@ -12,35 +11,37 @@ $TRANSLATIONS = array( "mappings cleared" => "Mapoanie wyczyszczone", "Success" => "Sukces", "Error" => "Błąd", +"Select groups" => "Wybierz grupy", "Connection test succeeded" => "Test połączenia udany", "Connection test failed" => "Test połączenia nie udany", "Do you really want to delete the current Server Configuration?" => "Czy chcesz usunąć bieżącą konfigurację serwera?", "Confirm Deletion" => "Potwierdź usunięcie", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Ostrzeżenie:</b> Moduł PHP LDAP nie jest zainstalowany i nie będzie działał. Poproś administratora o włączenie go.", -"Server configuration" => "Konfiguracja servera", +"_%s group found_::_%s groups found_" => array("","",""), +"_%s user found_::_%s users found_" => array("","",""), +"Save" => "Zapisz", +"Test Configuration" => "Konfiguracja testowa", +"Help" => "Pomoc", "Add Server Configuration" => "Dodaj konfigurację servera", "Host" => "Host", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Można pominąć protokół, z wyjątkiem wymaganego protokołu SSL. Następnie uruchom z ldaps://", -"Base DN" => "Baza DN", -"One Base DN per line" => "Jedna baza DN na linię", -"You can specify Base DN for users and groups in the Advanced tab" => "Bazę DN można określić dla użytkowników i grup w karcie Zaawansowane", +"Port" => "Port", "User DN" => "Użytkownik DN", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "DN użytkownika klienta, z którym powiązanie wykonuje się, np. uid=agent,dc=example,dc=com. Dla dostępu anonimowego pozostawić DN i hasło puste", "Password" => "Hasło", "For anonymous access, leave DN and Password empty." => "Dla dostępu anonimowego pozostawić DN i hasło puste.", -"User Login Filter" => "Filtr logowania użytkownika", -"User List Filter" => "Lista filtrów użytkownika", -"Group Filter" => "Grupa filtrów", +"One Base DN per line" => "Jedna baza DN na linię", +"You can specify Base DN for users and groups in the Advanced tab" => "Bazę DN można określić dla użytkowników i grup w karcie Zaawansowane", +"Back" => "Wróć", +"Continue" => "Kontynuuj ", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Ostrzeżenie:</b> Moduł PHP LDAP nie jest zainstalowany i nie będzie działał. Poproś administratora o włączenie go.", "Connection Settings" => "Konfiguracja połączeń", "Configuration Active" => "Konfiguracja archiwum", "When unchecked, this configuration will be skipped." => "Gdy niezaznaczone, ta konfiguracja zostanie pominięta.", -"Port" => "Port", "Backup (Replica) Host" => "Kopia zapasowa (repliki) host", "Give an optional backup host. It must be a replica of the main LDAP/AD server." => "Dać opcjonalnie hosta kopii zapasowej . To musi być repliką głównego serwera LDAP/AD.", "Backup (Replica) Port" => "Kopia zapasowa (repliki) Port", "Disable Main Server" => "Wyłącz serwer główny", -"Use TLS" => "Użyj TLS", -"Do not use it additionally for LDAPS connections, it will fail." => "Nie używaj go dodatkowo dla połączeń protokołu LDAPS, zakończy się niepowodzeniem.", +"Only connect to the replica server." => "Połącz tylko do repliki serwera.", "Case insensitve LDAP server (Windows)" => "Wielkość liter serwera LDAP (Windows)", "Turn off SSL certificate validation." => "Wyłączyć sprawdzanie poprawności certyfikatu SSL.", "Cache Time-To-Live" => "Przechowuj czas życia", @@ -66,11 +67,10 @@ $TRANSLATIONS = array( "Internal Username" => "Wewnętrzna nazwa użytkownika", "Internal Username Attribute:" => "Wewnętrzny atrybut nazwy uzżytkownika:", "Override UUID detection" => "Zastąp wykrywanie UUID", -"UUID Attribute:" => "Atrybuty UUID:", +"UUID Attribute for Users:" => "Atrybuty UUID dla użytkowników:", +"UUID Attribute for Groups:" => "Atrybuty UUID dla grup:", "Username-LDAP User Mapping" => "Mapowanie użytkownika LDAP", "Clear Username-LDAP User Mapping" => "Czyść Mapowanie użytkownika LDAP", -"Clear Groupname-LDAP Group Mapping" => "Czyść Mapowanie nazwy grupy LDAP", -"Test Configuration" => "Konfiguracja testowa", -"Help" => "Pomoc" +"Clear Groupname-LDAP Group Mapping" => "Czyść Mapowanie nazwy grupy LDAP" ); $PLURAL_FORMS = "nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"; diff --git a/apps/user_ldap/l10n/pt_BR.php b/apps/user_ldap/l10n/pt_BR.php index 9469146d359..559dc949bd5 100644 --- a/apps/user_ldap/l10n/pt_BR.php +++ b/apps/user_ldap/l10n/pt_BR.php @@ -4,7 +4,11 @@ $TRANSLATIONS = array( "Failed to delete the server configuration" => "Falha ao deletar a configuração do servidor", "The configuration is valid and the connection could be established!" => "A configuração é válida e a conexão foi estabelecida!", "The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "A configuração é válida, mas o Bind falhou. Confira as configurações do servidor e as credenciais.", -"The configuration is invalid. Please look in the ownCloud log for further details." => "A configuração é inválida. Leia o log do ownCloud para mais detalhes.", +"The configuration is invalid. Please have a look at the logs for further details." => "Configuração inválida. Por favor, dê uma olhada nos logs para mais detalhes.", +"No action specified" => "Nenhuma ação especificada", +"No configuration specified" => "Nenhuma configuração especificada", +"No data specified" => "Não há dados especificados", +" Could not set configuration %s" => "Não foi possível definir a configuração %s", "Deletion failed" => "Remoção falhou", "Take over settings from recent server configuration?" => "Tomar parámetros de recente configuração de servidor?", "Keep settings?" => "Manter ajustes?", @@ -12,40 +16,60 @@ $TRANSLATIONS = array( "mappings cleared" => "mapeamentos limpos", "Success" => "Sucesso", "Error" => "Erro", +"Configuration OK" => "Configuração OK", +"Configuration incorrect" => "Configuração incorreta", +"Configuration incomplete" => "Configuração incompleta", +"Select groups" => "Selecionar grupos", +"Select object classes" => "Selecione classes de objetos", +"Select attributes" => "Selecione os atributos", "Connection test succeeded" => "Teste de conexão bem sucedida", "Connection test failed" => "Teste de conexão falhou", "Do you really want to delete the current Server Configuration?" => "Você quer realmente deletar as atuais Configurações de Servidor?", "Confirm Deletion" => "Confirmar Exclusão", -"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Aviso:</b> Os aplicativos user_ldap e user_webdavauth são incompatíveis. Você pode experimentar comportamento inesperado. Por favor, peça ao seu administrador do sistema para desabilitar um deles.", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Aviso:</b> O módulo PHP LDAP não está instalado, o backend não funcionará. Por favor, peça ao seu administrador do sistema para instalá-lo.", -"Server configuration" => "Configuração de servidor", +"_%s group found_::_%s groups found_" => array("grupo% s encontrado","grupos% s encontrado"), +"_%s user found_::_%s users found_" => array("usuário %s encontrado","usuários %s encontrados"), +"Invalid Host" => "Host inválido", +"Could not find the desired feature" => "Não foi possível encontrar a função desejada", +"Save" => "Guardar", +"Test Configuration" => "Teste de Configuração", +"Help" => "Ajuda", +"Limit the access to %s to groups meeting this criteria:" => "Limitar o acesso a %s para grupos que coincidam com estes critérios:", +"only those object classes:" => "apenas essas classes de objetos:", +"only from those groups:" => "apenas a partir dos grupos:", +"Edit raw filter instead" => "Editar filtro raw ao invéz", +"Raw LDAP filter" => "Filtro LDAP Raw", +"The filter specifies which LDAP groups shall have access to the %s instance." => "O filtro especifica quais grupos LDAP devem ter acesso à instância do %s.", +"groups found" => "grupos encontrados", +"What attribute shall be used as login name:" => "O atributo deve ser usado como nome de login:", +"LDAP Username:" => "Usuário LDAP:", +"LDAP Email Address:" => "LDAP Endereço de E-mail:", +"Other Attributes:" => "Outros atributos:", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Define o filtro a ser aplicado, o login é feito. %%uid substitui o nome do usuário na ação de login. Exemplo: \"uid=%%uid\"", "Add Server Configuration" => "Adicionar Configuração de Servidor", "Host" => "Servidor", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Você pode omitir o protocolo, exceto quando requerer SSL. Então inicie com ldaps://", -"Base DN" => "DN Base", -"One Base DN per line" => "Uma base DN por linha", -"You can specify Base DN for users and groups in the Advanced tab" => "Você pode especificar DN Base para usuários e grupos na guia Avançada", +"Port" => "Porta", "User DN" => "DN Usuário", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "O DN do cliente usuário com qual a ligação deverá ser feita, ex. uid=agent,dc=example,dc=com. Para acesso anônimo, deixe DN e Senha vazios.", "Password" => "Senha", "For anonymous access, leave DN and Password empty." => "Para acesso anônimo, deixe DN e Senha vazios.", -"User Login Filter" => "Filtro de Login de Usuário", -"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Define o filtro a ser aplicado, o login é feito. %%uid substitui o nome do usuário na ação de login. Exemplo: \"uid=%%uid\"", -"User List Filter" => "Filtro de Lista de Usuário", -"Defines the filter to apply, when retrieving users (no placeholders). Example: \"objectClass=person\"" => "Define o filtro a ser aplicado, ao recuperar usuários (sem espaços reservados). Exemplo: \"objectClass=person\"", -"Group Filter" => "Filtro de Grupo", -"Defines the filter to apply, when retrieving groups (no placeholders). Example: \"objectClass=posixGroup\"" => "Define o filtro a ser aplicado, ao recuperar grupos (sem espaços reservados). Exemplo: \"objectClass=posixGroup\"", +"One Base DN per line" => "Uma base DN por linha", +"You can specify Base DN for users and groups in the Advanced tab" => "Você pode especificar DN Base para usuários e grupos na guia Avançada", +"Limit the access to %s to users meeting this criteria:" => "Limitar o acesso a %s para usuários que coincidam com estes critérios:", +"The filter specifies which LDAP users shall have access to the %s instance." => "O filtro especifica quais usuários LDAP devem ter acesso à instância do %s.", +"users found" => "usuários encontrados", +"Back" => "Voltar", +"Continue" => "Continuar", +"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Aviso:</b> Os aplicativos user_ldap e user_webdavauth são incompatíveis. Você pode experimentar comportamento inesperado. Por favor, peça ao seu administrador do sistema para desabilitar um deles.", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Aviso:</b> O módulo PHP LDAP não está instalado, o backend não funcionará. Por favor, peça ao seu administrador do sistema para instalá-lo.", "Connection Settings" => "Configurações de Conexão", "Configuration Active" => "Configuração ativa", "When unchecked, this configuration will be skipped." => "Quando não marcada, esta configuração será ignorada.", -"Port" => "Porta", "Backup (Replica) Host" => "Servidor de Backup (Réplica)", "Give an optional backup host. It must be a replica of the main LDAP/AD server." => "Defina um servidor de backup opcional. Ele deverá ser uma réplica do servidor LDAP/AD principal.", "Backup (Replica) Port" => "Porta do Backup (Réplica)", "Disable Main Server" => "Desativar Servidor Principal", "Only connect to the replica server." => "Conectar-se somente ao servidor de réplica.", -"Use TLS" => "Usar TLS", -"Do not use it additionally for LDAPS connections, it will fail." => "Não use adicionalmente para conexões LDAPS, pois falhará.", "Case insensitve LDAP server (Windows)" => "Servidor LDAP sensível à caixa alta (Windows)", "Turn off SSL certificate validation." => "Desligar validação de certificado SSL.", "Not recommended, use it for testing only! If connection only works with this option, import the LDAP server's SSL certificate in your %s server." => "Não recomendado, use-o somente para teste! Se a conexão só funciona com esta opção, importar o certificado SSL do servidor LDAP em seu servidor %s.", @@ -76,12 +100,11 @@ $TRANSLATIONS = array( "Internal Username Attribute:" => "Atributo Interno de Nome de Usuário:", "Override UUID detection" => "Substituir detecção UUID", "By default, the UUID attribute is automatically detected. The UUID attribute is used to doubtlessly identify LDAP users and groups. Also, the internal username will be created based on the UUID, if not specified otherwise above. You can override the setting and pass an attribute of your choice. You must make sure that the attribute of your choice can be fetched for both users and groups and it is unique. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users and groups." => "Por padrão, o atributo UUID é detectado automaticamente. O atributo UUID é usado para identificar, sem dúvidas, os usuários e grupos LDAP. Além disso, o nome de usuário interno será criado com base no UUID, se não especificado acima. Você pode substituir a configuração e passar um atributo de sua escolha. Você deve certificar-se de que o atributo de sua escolha pode ser lido tanto para usuários como para grupos, e que seja único. Deixe-o vazio para o comportamento padrão. As alterações terão efeito apenas para usuários e grupos LDAP recém mapeados (adicionados).", -"UUID Attribute:" => "Atributo UUID:", +"UUID Attribute for Users:" => "UUID Atributos para Usuários:", +"UUID Attribute for Groups:" => "UUID Atributos para Grupos:", "Username-LDAP User Mapping" => "Usuário-LDAP Mapeamento de Usuário", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have a internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." => "Nomes de usuários sãi usados para armazenar e atribuir (meta) dados. A fim de identificar com precisão e reconhecer usuários, cada usuário LDAP terá um nome de usuário interno. Isso requer um mapeamento nome de usuário para usuário LDAP. O nome de usuário criado é mapeado para o UUID do usuário LDAP. Adicionalmente, o DN fica em cache, assim como para reduzir a interação LDAP, mas não é utilizado para a identificação. Se o DN muda, as mudanças serão encontradas. O nome de usuário interno é utilizado em todo lugar. Limpar os mapeamentos não influencia a configuração. Limpar os mapeamentos deixará rastros em todo lugar. Limpar os mapeamentos não influencia a configuração, mas afeta as configurações LDAP! Somente limpe os mapeamentos em embiente de testes ou em estágio experimental.", "Clear Username-LDAP User Mapping" => "Limpar Mapeamento de Usuário Nome de Usuário-LDAP", -"Clear Groupname-LDAP Group Mapping" => "Limpar NomedoGrupo-LDAP Mapeamento do Grupo", -"Test Configuration" => "Teste de Configuração", -"Help" => "Ajuda" +"Clear Groupname-LDAP Group Mapping" => "Limpar NomedoGrupo-LDAP Mapeamento do Grupo" ); $PLURAL_FORMS = "nplurals=2; plural=(n > 1);"; diff --git a/apps/user_ldap/l10n/pt_PT.php b/apps/user_ldap/l10n/pt_PT.php index b88ad18f0f6..89c37358b67 100644 --- a/apps/user_ldap/l10n/pt_PT.php +++ b/apps/user_ldap/l10n/pt_PT.php @@ -4,7 +4,6 @@ $TRANSLATIONS = array( "Failed to delete the server configuration" => "Erro ao eliminar as configurações do servidor", "The configuration is valid and the connection could be established!" => "A configuração está correcta e foi possível estabelecer a ligação!", "The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "A configuração está correcta, mas não foi possível estabelecer o \"laço\", por favor, verifique as configurações do servidor e as credenciais.", -"The configuration is invalid. Please look in the ownCloud log for further details." => "A configuração é inválida. Por favor, veja o log do ownCloud para mais detalhes.", "Deletion failed" => "Erro ao apagar", "Take over settings from recent server configuration?" => "Assumir as configurações da configuração do servidor mais recente?", "Keep settings?" => "Manter as definições?", @@ -12,35 +11,36 @@ $TRANSLATIONS = array( "mappings cleared" => "Mapas limpos", "Success" => "Sucesso", "Error" => "Erro", +"Select groups" => "Seleccionar grupos", "Connection test succeeded" => "Teste de conecção passado com sucesso.", "Connection test failed" => "Erro no teste de conecção.", "Do you really want to delete the current Server Configuration?" => "Deseja realmente apagar as configurações de servidor actuais?", "Confirm Deletion" => "Confirmar a operação de apagar", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Aviso:</b> O módulo PHP LDAP não está instalado, logo não irá funcionar. Por favor peça ao administrador para o instalar.", -"Server configuration" => "Configurações do servidor", +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("",""), +"Save" => "Guardar", +"Test Configuration" => "Testar a configuração", +"Help" => "Ajuda", "Add Server Configuration" => "Adicionar configurações do servidor", "Host" => "Anfitrião", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Pode omitir o protocolo, excepto se necessitar de SSL. Neste caso, comece com ldaps://", -"Base DN" => "DN base", -"One Base DN per line" => "Uma base DN por linho", -"You can specify Base DN for users and groups in the Advanced tab" => "Pode especificar o ND Base para utilizadores e grupos no separador Avançado", +"Port" => "Porto", "User DN" => "DN do utilizador", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "O DN to cliente ", "Password" => "Password", "For anonymous access, leave DN and Password empty." => "Para acesso anónimo, deixe DN e a Palavra-passe vazios.", -"User Login Filter" => "Filtro de login de utilizador", -"User List Filter" => "Utilizar filtro", -"Group Filter" => "Filtrar por grupo", +"One Base DN per line" => "Uma base DN por linho", +"You can specify Base DN for users and groups in the Advanced tab" => "Pode especificar o ND Base para utilizadores e grupos no separador Avançado", +"Back" => "Voltar", +"Continue" => "Continuar", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Aviso:</b> O módulo PHP LDAP não está instalado, logo não irá funcionar. Por favor peça ao administrador para o instalar.", "Connection Settings" => "Definições de ligação", "Configuration Active" => "Configuração activa", "When unchecked, this configuration will be skipped." => "Se não estiver marcada, esta definição não será tida em conta.", -"Port" => "Porto", "Backup (Replica) Host" => "Servidor de Backup (Réplica)", "Give an optional backup host. It must be a replica of the main LDAP/AD server." => "Forneça um servidor (anfitrião) de backup. Deve ser uma réplica do servidor principal de LDAP/AD ", "Backup (Replica) Port" => "Porta do servidor de backup (Replica)", "Disable Main Server" => "Desactivar servidor principal", -"Use TLS" => "Usar TLS", -"Do not use it additionally for LDAPS connections, it will fail." => "Não utilize para adicionar ligações LDAP, irá falhar!", "Case insensitve LDAP server (Windows)" => "Servidor LDAP (Windows) não sensível a maiúsculas.", "Turn off SSL certificate validation." => "Desligar a validação de certificado SSL.", "Cache Time-To-Live" => "Cache do tempo de vida dos objetos no servidor", @@ -66,11 +66,8 @@ $TRANSLATIONS = array( "Internal Username" => "Nome de utilizador interno", "Internal Username Attribute:" => "Atributo do nome de utilizador interno", "Override UUID detection" => "Passar a detecção do UUID", -"UUID Attribute:" => "Atributo UUID:", "Username-LDAP User Mapping" => "Mapeamento do utilizador LDAP", "Clear Username-LDAP User Mapping" => "Limpar mapeamento do utilizador-LDAP", -"Clear Groupname-LDAP Group Mapping" => "Limpar o mapeamento do nome de grupo LDAP", -"Test Configuration" => "Testar a configuração", -"Help" => "Ajuda" +"Clear Groupname-LDAP Group Mapping" => "Limpar o mapeamento do nome de grupo LDAP" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/ro.php b/apps/user_ldap/l10n/ro.php index a0bacccb707..0214be3f787 100644 --- a/apps/user_ldap/l10n/ro.php +++ b/apps/user_ldap/l10n/ro.php @@ -3,21 +3,22 @@ $TRANSLATIONS = array( "Deletion failed" => "Ștergerea a eșuat", "Success" => "Succes", "Error" => "Eroare", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Atenție</b> Modulul PHP LDAP nu este instalat, infrastructura nu va funcționa. Contactează administratorul sistemului pentru al instala.", +"_%s group found_::_%s groups found_" => array("","",""), +"_%s user found_::_%s users found_" => array("","",""), +"Save" => "Salvează", +"Help" => "Ajutor", "Host" => "Gazdă", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Puteți omite protocolul, decât dacă folosiți SSL. Atunci se începe cu ldaps://", -"Base DN" => "DN de bază", -"One Base DN per line" => "Un Base DN pe linie", -"You can specify Base DN for users and groups in the Advanced tab" => "Puteți să specificați DN de bază pentru utilizatori și grupuri în fila Avansat", +"Port" => "Portul", "User DN" => "DN al utilizatorului", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "DN-ul clientului utilizator cu care se va efectua conectarea, d.e. uid=agent,dc=example,dc=com. Pentru acces anonim, lăsăți DN și Parolă libere.", "Password" => "Parolă", "For anonymous access, leave DN and Password empty." => "Pentru acces anonim, lăsați DN și Parolă libere.", -"User Login Filter" => "Filtrare după Nume Utilizator", -"User List Filter" => "Filtrarea după lista utilizatorilor", -"Group Filter" => "Fitrare Grup", -"Port" => "Portul", -"Use TLS" => "Utilizează TLS", +"One Base DN per line" => "Un Base DN pe linie", +"You can specify Base DN for users and groups in the Advanced tab" => "Puteți să specificați DN de bază pentru utilizatori și grupuri în fila Avansat", +"Back" => "Înapoi", +"Continue" => "Continuă", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Atenție</b> Modulul PHP LDAP nu este instalat, infrastructura nu va funcționa. Contactează administratorul sistemului pentru al instala.", "Case insensitve LDAP server (Windows)" => "Server LDAP insensibil la majuscule (Windows)", "Turn off SSL certificate validation." => "Oprește validarea certificatelor SSL ", "in seconds. A change empties the cache." => "în secunde. O schimbare curăță memoria tampon.", @@ -29,7 +30,6 @@ $TRANSLATIONS = array( "One Group Base DN per line" => "Un Group Base DN pe linie", "Group-Member association" => "Asocierea Grup-Membru", "in bytes" => "în octeți", -"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "Lăsați gol pentru numele de utilizator (implicit). În caz contrar, specificați un atribut LDAP / AD.", -"Help" => "Ajutor" +"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "Lăsați gol pentru numele de utilizator (implicit). În caz contrar, specificați un atribut LDAP / AD." ); $PLURAL_FORMS = "nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));"; diff --git a/apps/user_ldap/l10n/ru.php b/apps/user_ldap/l10n/ru.php index f1cf51dc51b..7b9cf8ceb56 100644 --- a/apps/user_ldap/l10n/ru.php +++ b/apps/user_ldap/l10n/ru.php @@ -1,10 +1,14 @@ <?php $TRANSLATIONS = array( -"Failed to clear the mappings." => "Не удалось очистить соотвествия.", +"Failed to clear the mappings." => "Не удалось очистить соответствия.", "Failed to delete the server configuration" => "Не удалось удалить конфигурацию сервера", "The configuration is valid and the connection could be established!" => "Конфигурация правильная и подключение может быть установлено!", "The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "Конфигурация верна, но операция подключения завершилась неудачно. Пожалуйста, проверьте настройки сервера и учетные данные.", -"The configuration is invalid. Please look in the ownCloud log for further details." => "Конфигурация не верна. Пожалуйста, посмотрите в журнале ownCloud детали.", +"The configuration is invalid. Please have a look at the logs for further details." => "Конфигурация недействительна. Пожалуйста, просмотрите логи для уточнения деталей.", +"No action specified" => "Действие не указано", +"No configuration specified" => "Конфигурация не создана", +"No data specified" => "Нет данных", +" Could not set configuration %s" => "Невозможно создать конфигурацию %s", "Deletion failed" => "Удаление не удалось", "Take over settings from recent server configuration?" => "Принять настройки из последней конфигурации сервера?", "Keep settings?" => "Сохранить настройки?", @@ -12,43 +16,63 @@ $TRANSLATIONS = array( "mappings cleared" => "Соответствия очищены", "Success" => "Успешно", "Error" => "Ошибка", +"Configuration OK" => "Конфигурация в порядке", +"Configuration incorrect" => "Конфигурация неправильна", +"Configuration incomplete" => "Конфигурация не завершена", +"Select groups" => "Выберите группы", +"Select object classes" => "Выберите объектные классы", +"Select attributes" => "Выберите атрибуты", "Connection test succeeded" => "Проверка соединения удалась", "Connection test failed" => "Проверка соединения не удалась", "Do you really want to delete the current Server Configuration?" => "Вы действительно хотите удалить существующую конфигурацию сервера?", "Confirm Deletion" => "Подтверждение удаления", -"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Предупреждение:</b> Приложения user_ldap и user_webdavauth не совместимы. Вы можете наблюдать некорректное поведение. Пожалуйста попросите Вашего системного администратора отключить одно из них.", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Внимание:</b> Модуль LDAP для PHP не установлен, бэкенд не будет работать. Пожалуйста, попросите вашего системного администратора его установить. ", -"Server configuration" => "Конфигурация сервера", +"_%s group found_::_%s groups found_" => array("%s группа найдена","%s группы найдены","%s групп найдено"), +"_%s user found_::_%s users found_" => array("%s пользователь найден","%s пользователя найдено","%s пользователей найдено"), +"Invalid Host" => "Неверный сервер", +"Could not find the desired feature" => "Не могу найти требуемой функциональности", +"Save" => "Сохранить", +"Test Configuration" => "Проверить конфигурацию", +"Help" => "Помощь", +"Limit the access to %s to groups meeting this criteria:" => "Ограничить доступ к %s группам, удовлетворяющим этому критерию:", +"only those object classes:" => "только эти объектные классы", +"only from those groups:" => "только из этих групп", +"Edit raw filter instead" => "Редактировать исходный фильтр", +"Raw LDAP filter" => "Исходный LDAP фильтр", +"The filter specifies which LDAP groups shall have access to the %s instance." => "Этот фильтр определяет, какие LDAP группы должны иметь доступ к %s.", +"groups found" => "групп найдено", +"What attribute shall be used as login name:" => "Какой атрибут должен быть использован для логина:", +"LDAP Username:" => "Имя пользователя LDAP", +"LDAP Email Address:" => "LDAP адрес электронной почты:", +"Other Attributes:" => "Другие атрибуты:", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Определяет фильтр для применения при попытке входа. %%uid заменяет имя пользователя при входе в систему. Например: \"uid=%%uid\"", "Add Server Configuration" => "Добавить конфигурацию сервера", "Host" => "Сервер", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Можно опустить протокол, за исключением того, когда вам требуется SSL. Тогда начните с ldaps :/ /", -"Base DN" => "Базовый DN", -"One Base DN per line" => "По одному базовому DN в строке.", -"You can specify Base DN for users and groups in the Advanced tab" => "Вы можете задать Base DN для пользователей и групп на вкладке \"Расширенное\"", +"Port" => "Порт", "User DN" => "DN пользователя", -"The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "DN-клиента пользователя, с которым связывают должно быть заполнено, например, uid=агент, dc=пример, dc=com. Для анонимного доступа, оставьте DN и пароль пустыми.", +"The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "DN пользователя, под которым выполняется подключение, например, uid=agent,dc=example,dc=com. Для анонимного доступа оставьте DN и пароль пустыми.", "Password" => "Пароль", "For anonymous access, leave DN and Password empty." => "Для анонимного доступа оставьте DN и пароль пустыми.", -"User Login Filter" => "Фильтр входа пользователей", -"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Определяет фильтр для применения при попытке входа. %%uid заменяет имя пользователя при входе в систему. Например: \"uid=%%uid\"", -"User List Filter" => "Фильтр списка пользователей", -"Defines the filter to apply, when retrieving users (no placeholders). Example: \"objectClass=person\"" => "Определяет фильтр, использующийся при получении пользователей (без подмены переменных). Например: \"objectClass=person\"", -"Group Filter" => "Фильтр группы", -"Defines the filter to apply, when retrieving groups (no placeholders). Example: \"objectClass=posixGroup\"" => "Определяет фильтр, использующийся при получении групп (без подмены переменных). Например: \"objectClass=posixGroup\"", +"One Base DN per line" => "По одной базе поиска (Base DN) в строке.", +"You can specify Base DN for users and groups in the Advanced tab" => "Вы можете задать Base DN для пользователей и групп на вкладке \"Расширенное\"", +"Limit the access to %s to users meeting this criteria:" => "Ограничить доступ к %s пользователям, удовлетворяющим этому критерию:", +"The filter specifies which LDAP users shall have access to the %s instance." => "Этот фильтр указывает, какие пользователи LDAP должны иметь доступ к %s.", +"users found" => "пользователей найдено", +"Back" => "Назад", +"Continue" => "Продолжить", +"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Предупреждение:</b> Приложения user_ldap и user_webdavauth несовместимы. Вы можете наблюдать некорректное поведение. Пожалуйста, попросите вашего системного администратора отключить одно из них.", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Внимание:</b> Модуль LDAP для PHP не установлен, бэкенд не будет работать. Пожалуйста, попросите вашего системного администратора его установить. ", "Connection Settings" => "Настройки подключения", "Configuration Active" => "Конфигурация активна", "When unchecked, this configuration will be skipped." => "Когда галочка снята, эта конфигурация будет пропущена.", -"Port" => "Порт", "Backup (Replica) Host" => "Адрес резервного сервера", "Give an optional backup host. It must be a replica of the main LDAP/AD server." => "Укажите дополнительный резервный сервер. Он должен быть репликой главного LDAP/AD сервера.", "Backup (Replica) Port" => "Порт резервного сервера", -"Disable Main Server" => "Отключение главного сервера", -"Only connect to the replica server." => "Только подключение к серверу реплик.", -"Use TLS" => "Использовать TLS", -"Do not use it additionally for LDAPS connections, it will fail." => "Не используйте совместно с безопасными подключениями (LDAPS), это не сработает.", +"Disable Main Server" => "Отключить главный сервер", +"Only connect to the replica server." => "Подключаться только к серверу-реплике.", "Case insensitve LDAP server (Windows)" => "Нечувствительный к регистру сервер LDAP (Windows)", "Turn off SSL certificate validation." => "Отключить проверку сертификата SSL.", -"Not recommended, use it for testing only! If connection only works with this option, import the LDAP server's SSL certificate in your %s server." => "Не рекомендуется, используйте только в режиме тестирования! Если соединение работает только с этой опцией, импортируйте на ваш %s сервер сертификат SSL сервера LDAP.", +"Not recommended, use it for testing only! If connection only works with this option, import the LDAP server's SSL certificate in your %s server." => "Не рекомендуется, используйте только в режиме тестирования! Если соединение работает только с этой опцией, импортируйте на ваш %s сервер SSL-сертификат сервера LDAP.", "Cache Time-To-Live" => "Кэш времени жизни", "in seconds. A change empties the cache." => "в секундах. Изменение очистит кэш.", "Directory Settings" => "Настройки каталога", @@ -56,8 +80,8 @@ $TRANSLATIONS = array( "The LDAP attribute to use to generate the user's display name." => "Атрибут LDAP, который используется для генерации отображаемого имени пользователя.", "Base User Tree" => "База пользовательского дерева", "One User Base DN per line" => "По одной базовому DN пользователей в строке.", -"User Search Attributes" => "Поисковые атрибуты пользователя", -"Optional; one attribute per line" => "Опционально; один атрибут на линию", +"User Search Attributes" => "Атрибуты поиска пользоватетелей", +"Optional; one attribute per line" => "Опционально; один атрибут в строке", "Group Display Name Field" => "Поле отображаемого имени группы", "The LDAP attribute to use to generate the groups's display name." => "Атрибут LDAP, который используется для генерации отображаемого имени группы.", "Base Group Tree" => "База группового дерева", @@ -65,23 +89,22 @@ $TRANSLATIONS = array( "Group Search Attributes" => "Атрибуты поиска для группы", "Group-Member association" => "Ассоциация Группа-Участник", "Special Attributes" => "Специальные атрибуты", -"Quota Field" => "Поле квота", +"Quota Field" => "Поле квоты", "Quota Default" => "Квота по умолчанию", "in bytes" => "в байтах", -"Email Field" => "Поле адресса эллектронной почты", -"User Home Folder Naming Rule" => "Правило именования Домашней Папки Пользователя", -"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "Оставьте имя пользователя пустым (по умолчанию). Иначе укажите атрибут LDAP/AD.", +"Email Field" => "Поле адреса электронной почты", +"User Home Folder Naming Rule" => "Правило именования домашней папки пользователя", +"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "Оставьте пустым для использования имени пользователя (по умолчанию). Иначе укажите атрибут LDAP/AD.", "Internal Username" => "Внутреннее имя пользователя", -"By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. To achieve a similar behavior as before ownCloud 5 enter the user display name attribute in the following field. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users." => "По-умолчанию внутреннее имя пользователя будет создано из атрибута UUID. Таким образом имя пользователя становится уникальным и не требует конвертации символов. Внутреннее имя пользователя может состоять только из следующих символов: [ a-zA-Z0-9_.@- ]. Остальные символы замещаются соответствиями из таблицы ASCII или же просто пропускаются. При совпадении к имени будет добавлено число. Внутреннее имя пользователя используется для внутренней идентификации пользователя. Также оно является именем по-умолчанию для папки пользователя в ownCloud. Оно также портом для удаленных ссылок, к примеру, для всех сервисов *DAV. С помощию данной настройки можно изменить поведение по-умолчанию. Чтобы достичь поведения, как было настроено до изменения, ownCloud 5 выводит атрибут имени пользователя в этом поле. Оставьте его пустым для режима по-умолчанию. Изменения будут иметь эффект только для новых подключенных (добавленных) пользователей LDAP.", -"Internal Username Attribute:" => "Аттрибут для внутреннего имени:", +"By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. To achieve a similar behavior as before ownCloud 5 enter the user display name attribute in the following field. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users." => "По умолчанию внутреннее имя пользователя будет создано из атрибута UUID. Таким образом имя пользователя становится уникальным и не требует конвертации символов. Внутреннее имя пользователя может состоять только из следующих символов: [ a-zA-Z0-9_.@- ]. Остальные символы замещаются соответствиями из таблицы ASCII или же просто пропускаются. При совпадении к имени будет добавлено или увеличено число. Внутреннее имя пользователя используется для внутренней идентификации пользователя. Также оно является именем по умолчанию для папки пользователя в ownCloud. Оно также является частью URL, к примеру, для всех сервисов *DAV. С помощью данной настройки можно изменить поведение по умолчанию. Чтобы достичь поведения, как было до ownCloud 5, введите атрибут отображаемого имени пользователя в этом поле. Оставьте его пустым для режима по умолчанию. Изменения будут иметь эффект только для новых подключенных (добавленных) пользователей LDAP.", +"Internal Username Attribute:" => "Атрибут для внутреннего имени:", "Override UUID detection" => "Переопределить нахождение UUID", -"By default, the UUID attribute is automatically detected. The UUID attribute is used to doubtlessly identify LDAP users and groups. Also, the internal username will be created based on the UUID, if not specified otherwise above. You can override the setting and pass an attribute of your choice. You must make sure that the attribute of your choice can be fetched for both users and groups and it is unique. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users and groups." => "По-умолчанию, ownCloud определяет атрибут UUID автоматически. Этот атрибут используется для того, чтобы достоверно индентифицировать пользователей и группы LDAP. Также, на основании атрибута UUID создается внутреннее имя пользователя, если выше не указано иначе. Вы можете переопределить эту настройку и указать свой атрибут по выбору. Вы должны удостовериться, что выбранный вами атрибут может быть выбран для пользователей и групп, а также то, что он уникальный. Оставьте поле пустым для поведения по-умолчанию. Изменения вступят в силу только для новых подключенных (добавленных) пользователей и групп LDAP.", -"UUID Attribute:" => "Аттрибут для UUID:", +"By default, the UUID attribute is automatically detected. The UUID attribute is used to doubtlessly identify LDAP users and groups. Also, the internal username will be created based on the UUID, if not specified otherwise above. You can override the setting and pass an attribute of your choice. You must make sure that the attribute of your choice can be fetched for both users and groups and it is unique. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users and groups." => "По умолчанию ownCloud определяет атрибут UUID автоматически. Этот атрибут используется для того, чтобы достоверно индентифицировать пользователей и группы LDAP. Также на основании атрибута UUID создается внутреннее имя пользователя, если выше не указано иначе. Вы можете переопределить эту настройку и указать свой атрибут по выбору. Вы должны удостовериться, что выбранный вами атрибут может быть выбран для пользователей и групп, а также то, что он уникальный. Оставьте поле пустым для поведения по умолчанию. Изменения вступят в силу только для новых подключенных (добавленных) пользователей и групп LDAP.", +"UUID Attribute for Users:" => "UUID-атрибуты для пользователей:", +"UUID Attribute for Groups:" => "UUID-атрибуты для групп:", "Username-LDAP User Mapping" => "Соответствия Имя-Пользователь LDAP", -"Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have a internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." => "ownCloud использует имена пользователей для хранения и назначения метаданных. Для точной идентификации и распознавания пользователей, каждый пользователь LDAP будет иметь свое внутреннее имя пользователя. Это требует привязки имени пользователя ownCloud к пользователю LDAP. При создании имя пользователя назначается идентификатору UUID пользователя LDAP. Помимо этого кешируется доменное имя (DN) для уменьшения числа обращений к LDAP, однако оно не используется для идентификации. Если доменное имя было изменено, об этом станет известно ownCloud. Внутреннее имя ownCloud используется повсеместно в ownCloud. После сброса привязок в базе могут сохраниться остатки старой информации. Сброс привязок не привязан к конфигурации, он повлияет на все LDAP подключения! Ни в коем случае не рекомендуется сбрасывать привязки если система уже находится в эксплуатации, только на этапе тестирования.", +"Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have a internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." => "ownCloud использует имена пользователей для хранения и назначения метаданных. Для точной идентификации и распознавания пользователей, каждый пользователь LDAP будет иметь свое внутреннее имя пользователя. Это требует привязки имени пользователя ownCloud к пользователю LDAP. При создании имя пользователя назначается идентификатору UUID пользователя LDAP. Помимо этого кешируется различающееся имя (DN) для уменьшения числа обращений к LDAP, однако оно не используется для идентификации. Если различающееся имя было изменено, об этом станет известно ownCloud. Внутреннее имя ownCloud используется повсеместно в ownCloud. После сброса привязок в базе могут сохраниться остатки старой информации. Сброс привязок не привязан к конфигурации, он повлияет на все LDAP-подключения! Ни в коем случае не рекомендуется сбрасывать привязки, если система уже находится в эксплуатации, только на этапе тестирования.", "Clear Username-LDAP User Mapping" => "Очистить соответствия Имя-Пользователь LDAP", -"Clear Groupname-LDAP Group Mapping" => "Очистить соответствия Группа-Группа LDAP", -"Test Configuration" => "Тестовая конфигурация", -"Help" => "Помощь" +"Clear Groupname-LDAP Group Mapping" => "Очистить соответствия Группа-Группа LDAP" ); $PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"; diff --git a/apps/user_ldap/l10n/si_LK.php b/apps/user_ldap/l10n/si_LK.php index 5d2db636cf0..5c02f028655 100644 --- a/apps/user_ldap/l10n/si_LK.php +++ b/apps/user_ldap/l10n/si_LK.php @@ -3,14 +3,13 @@ $TRANSLATIONS = array( "Deletion failed" => "මකාදැමීම අසාර්ථකයි", "Success" => "සාර්ථකයි", "Error" => "දෝෂයක්", +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("",""), +"Save" => "සුරකින්න", +"Help" => "උදව්", "Host" => "සත්කාරකය", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "SSL අවශ්යය වන විට පමණක් හැර, අන් අවස්ථාවන්හිදී ප්රොටොකෝලය අත් හැරිය හැක. භාවිතා කරන විට ldaps:// ලෙස ආරම්භ කරන්න", -"Password" => "මුර පදය", -"User Login Filter" => "පරිශීලක පිවිසුම් පෙරහන", -"User List Filter" => "පරිශීලක ලැයිස්තු පෙරහන", -"Group Filter" => "කණ්ඩායම් පෙරහන", "Port" => "තොට", -"Use TLS" => "TLS භාවිතා කරන්න", -"Help" => "උදව්" +"Password" => "මුර පදය" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/sk.php b/apps/user_ldap/l10n/sk.php new file mode 100644 index 00000000000..2578bb55649 --- /dev/null +++ b/apps/user_ldap/l10n/sk.php @@ -0,0 +1,7 @@ +<?php +$TRANSLATIONS = array( +"_%s group found_::_%s groups found_" => array("","",""), +"_%s user found_::_%s users found_" => array("","",""), +"Save" => "Uložiť" +); +$PLURAL_FORMS = "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"; diff --git a/apps/user_ldap/l10n/sk_SK.php b/apps/user_ldap/l10n/sk_SK.php index df71a71e933..850fce24c48 100644 --- a/apps/user_ldap/l10n/sk_SK.php +++ b/apps/user_ldap/l10n/sk_SK.php @@ -4,7 +4,11 @@ $TRANSLATIONS = array( "Failed to delete the server configuration" => "Zlyhalo zmazanie nastavenia servera.", "The configuration is valid and the connection could be established!" => "Nastavenie je v poriadku a pripojenie je stabilné.", "The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "Nastavenie je v poriadku, ale pripojenie zlyhalo. Skontrolujte nastavenia servera a prihlasovacie údaje.", -"The configuration is invalid. Please look in the ownCloud log for further details." => "Nastavenia sú neplatné. Podrobnosti hľadajte v logu ownCloud.", +"The configuration is invalid. Please have a look at the logs for further details." => "Konfigurácia je chybná. Prosím, pozrite sa do logov pre ďalšie podrobnosti.", +"No action specified" => "Nie je vybraná akcia", +"No configuration specified" => "Nie je určená konfigurácia", +"No data specified" => "Nie sú vybraté dáta", +" Could not set configuration %s" => "Nemôžem nastaviť konfiguráciu %s", "Deletion failed" => "Odstránenie zlyhalo", "Take over settings from recent server configuration?" => "Prebrať nastavenia z nedávneho nastavenia servera?", "Keep settings?" => "Ponechať nastavenia?", @@ -12,47 +16,67 @@ $TRANSLATIONS = array( "mappings cleared" => "mapovanie vymazané", "Success" => "Úspešné", "Error" => "Chyba", +"Configuration OK" => "Konfigurácia je vporiadku", +"Configuration incorrect" => "Nesprávna konfigurácia", +"Configuration incomplete" => "Nekompletná konfigurácia", +"Select groups" => "Vybrať skupinu", +"Select object classes" => "Vyberte triedy objektov", +"Select attributes" => "Vyberte atribúty", "Connection test succeeded" => "Test pripojenia bol úspešný", "Connection test failed" => "Test pripojenia zlyhal", "Do you really want to delete the current Server Configuration?" => "Naozaj chcete zmazať súčasné nastavenie servera?", "Confirm Deletion" => "Potvrdiť vymazanie", -"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Upozornenie:</b> Aplikácie user_ldap a user_webdavauth sú navzájom nekompatibilné. Môžete zaznamenať neočakávané správanie. Požiadajte prosím vášho systémového administrátora pre zakázanie jedného z nich.", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Upozornenie:</b> nie je nainštalovaný LDAP modul pre PHP, backend vrstva nebude fungovať. Požádejte administrátora systému aby ho nainštaloval.", -"Server configuration" => "Nastavenia servera", +"_%s group found_::_%s groups found_" => array("%s nájdená skupina","%s nájdené skupiny","%s nájdených skupín"), +"_%s user found_::_%s users found_" => array("%s nájdený používateľ","%s nájdení používatelia","%s nájdených používateľov"), +"Invalid Host" => "Neplatný hostiteľ", +"Could not find the desired feature" => "Nemožno nájsť požadovanú funkciu", +"Save" => "Uložiť", +"Test Configuration" => "Test nastavenia", +"Help" => "Pomoc", +"Limit the access to %s to groups meeting this criteria:" => "Obmedziť prístup %s do skupiny, ktoré spĺňajú tieto kritériá:", +"only those object classes:" => "len tieto triedy objektov:", +"only from those groups:" => "len z týchto skupín:", +"Edit raw filter instead" => "Miesto pre úpravu raw filtra", +"Raw LDAP filter" => "Raw LDAP filter", +"The filter specifies which LDAP groups shall have access to the %s instance." => "Tento filter LDAP určuje, ktoré skupiny budú mať prístup k %s inštancii.", +"groups found" => "nájdené skupiny", +"What attribute shall be used as login name:" => "Ako prihlasovacie meno použiť atribút:", +"LDAP Username:" => "LDAP používateľské meno:", +"LDAP Email Address:" => "LDAP emailová adresa:", +"Other Attributes:" => "Iné atribúty:", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Určuje použitý filter, pri pokuse o prihlásenie. %%uid nahradzuje používateľské meno v činnosti prihlásenia. Napríklad: \"uid=%%uid\"", "Add Server Configuration" => "Pridať nastavenia servera.", "Host" => "Hostiteľ", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Môžete vynechať protokol, s výnimkou požadovania SSL. Vtedy začnite s ldaps://", -"Base DN" => "Základné DN", -"One Base DN per line" => "Jedno základné DN na riadok", -"You can specify Base DN for users and groups in the Advanced tab" => "V rozšírenom nastavení môžete zadať základné DN pre používateľov a skupiny", +"Port" => "Port", "User DN" => "Používateľské DN", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "DN klientského používateľa, ku ktorému tvoríte väzbu, napr. uid=agent,dc=example,dc=com. Pre anonymný prístup ponechajte údaje DN a Heslo prázdne.", "Password" => "Heslo", "For anonymous access, leave DN and Password empty." => "Pre anonymný prístup ponechajte údaje DN a Heslo prázdne.", -"User Login Filter" => "Filter prihlásenia používateľov", -"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Určuje použitý filter, pri pokuse o prihlásenie. %%uid nahradzuje používateľské meno v činnosti prihlásenia. Napríklad: \"uid=%%uid\"", -"User List Filter" => "Filter zoznamov používateľov", -"Defines the filter to apply, when retrieving users (no placeholders). Example: \"objectClass=person\"" => "Definuje použitý filter, pri získavaní používateľov (bez \"placeholderov\"). Napríklad: \"objectClass=osoba\"", -"Group Filter" => "Filter skupiny", -"Defines the filter to apply, when retrieving groups (no placeholders). Example: \"objectClass=posixGroup\"" => "Definuje použitý filter, pri získavaní skupín (bez \"placeholderov\"). Napríklad: \"objectClass=posixSkupina\"", +"One Base DN per line" => "Jedno základné DN na riadok", +"You can specify Base DN for users and groups in the Advanced tab" => "V rozšírenom nastavení môžete zadať základné DN pre používateľov a skupiny", +"Limit the access to %s to users meeting this criteria:" => "Obmedziť prístup k %s na používateľov, ktorí spĺňajú tieto kritériá:", +"The filter specifies which LDAP users shall have access to the %s instance." => "Tento filter LDAP určuje, ktorí používatelia majú prístup k %s inštancii.", +"users found" => "nájdení používatelia", +"Back" => "Späť", +"Continue" => "Pokračovať", +"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Upozornenie:</b> Aplikácie user_ldap a user_webdavauth sú navzájom nekompatibilné. Môžete zaznamenať neočakávané správanie. Požiadajte prosím vášho systémového administrátora pre zakázanie jedného z nich.", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Upozornenie:</b> nie je nainštalovaný LDAP modul pre PHP, backend vrstva nebude fungovať. Požádejte administrátora systému aby ho nainštaloval.", "Connection Settings" => "Nastavenie pripojenia", "Configuration Active" => "Nastavenia sú aktívne ", "When unchecked, this configuration will be skipped." => "Ak nie je zaškrtnuté, nastavenie bude preskočené.", -"Port" => "Port", -"Backup (Replica) Host" => "Záložný server (kópia) hosť", +"Backup (Replica) Host" => "Záložný server (kópia) hostiteľa", "Give an optional backup host. It must be a replica of the main LDAP/AD server." => "Zadajte záložný LDAP/AD. Musí to byť kópia hlavného LDAP/AD servera.", "Backup (Replica) Port" => "Záložný server (kópia) port", "Disable Main Server" => "Zakázať hlavný server", "Only connect to the replica server." => "Pripojiť sa len k záložnému serveru.", -"Use TLS" => "Použi TLS", -"Do not use it additionally for LDAPS connections, it will fail." => "Nepoužívajte pre pripojenie LDAPS, zlyhá.", "Case insensitve LDAP server (Windows)" => "LDAP server nerozlišuje veľkosť znakov (Windows)", "Turn off SSL certificate validation." => "Vypnúť overovanie SSL certifikátu.", "Not recommended, use it for testing only! If connection only works with this option, import the LDAP server's SSL certificate in your %s server." => "Neodporúčané, použite iba pri testovaní! Pokiaľ spojenie funguje iba z daným nastavením, importujte SSL certifikát LDAP servera do vášho %s servera.", -"Cache Time-To-Live" => "Životnosť objektov v cache", +"Cache Time-To-Live" => "Životnosť objektov v medzipamäti", "in seconds. A change empties the cache." => "v sekundách. Zmena vyprázdni vyrovnávaciu pamäť.", "Directory Settings" => "Nastavenie priečinka", -"User Display Name Field" => "Pole pre zobrazenia mena používateľa", +"User Display Name Field" => "Pole pre zobrazenie mena používateľa", "The LDAP attribute to use to generate the user's display name." => "Atribút LDAP použitý na vygenerovanie zobrazovaného mena používateľa. ", "Base User Tree" => "Základný používateľský strom", "One User Base DN per line" => "Jedna používateľská základná DN na riadok", @@ -68,20 +92,19 @@ $TRANSLATIONS = array( "Quota Field" => "Pole kvóty", "Quota Default" => "Predvolená kvóta", "in bytes" => "v bajtoch", -"Email Field" => "Pole email", -"User Home Folder Naming Rule" => "Pravidlo pre nastavenie mena používateľského priečinka dát", +"Email Field" => "Pole emailu", +"User Home Folder Naming Rule" => "Pravidlo pre nastavenie názvu používateľského priečinka dát", "Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "Nechajte prázdne pre používateľské meno (predvolené). Inak uveďte atribút LDAP/AD.", "Internal Username" => "Interné používateľské meno", "By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. To achieve a similar behavior as before ownCloud 5 enter the user display name attribute in the following field. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users." => "V predvolenom nastavení bude interné používateľské meno vytvorené z UUID atribútu. Zabezpečí sa to, že používateľské meno bude jedinečné a znaky nemusia byť prevedené. Interné meno má obmedzenie, iba tieto znaky sú povolené: [a-zA-Z0-9_ @ -.]. Ostatné znaky sú nahradené ich ASCII alebo jednoducho vynechané. Pri kolíziách používateľských mien bude číslo pridané / odobrané. Interné používateľské meno sa používa na internú identifikáciu používateľa. Je tiež predvoleným názvom používateľského domovského priečinka v ownCloud. Je tiež súčasťou URL pre vzdialený prístup, napríklad pre všetky služby * DAV. S týmto nastavením sa dá prepísať predvolené správanie. Pre dosiahnutie podobného správania sa ako pred verziou ownCloud 5 zadajte atribút zobrazenia používateľského mena v tomto poli. Ponechajte prázdne pre predvolené správanie. Zmeny budú mať vplyv iba na novo namapovaných (pridaných) LDAP používateľov.", "Internal Username Attribute:" => "Atribút interného používateľského mena:", "Override UUID detection" => "Prepísať UUID detekciu", "By default, the UUID attribute is automatically detected. The UUID attribute is used to doubtlessly identify LDAP users and groups. Also, the internal username will be created based on the UUID, if not specified otherwise above. You can override the setting and pass an attribute of your choice. You must make sure that the attribute of your choice can be fetched for both users and groups and it is unique. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users and groups." => "V predvolenom nastavení je UUID atribút detekovaný automaticky. UUID atribút je použitý na jedinečnú identifikáciu používateľov a skupín z LDAP. Naviac je na základe UUID vytvorené tiež interné použivateľské meno, ak nie je nastavené inak. Môžete predvolené nastavenie prepísať a použiť atribút ktorý si sami zvolíte. Musíte sa ale ubezpečiť, že atribút ktorý vyberiete bude uvedený pri použivateľoch, aj pri skupinách a je jedinečný. Ponechajte prázdne pre predvolené správanie. Zmena bude mať vplyv len na novo namapovaných (pridaných) používateľov a skupiny z LDAP.", -"UUID Attribute:" => "UUID atribút:", +"UUID Attribute for Users:" => "UUID atribút pre používateľov:", +"UUID Attribute for Groups:" => "UUID atribút pre skupiny:", "Username-LDAP User Mapping" => "Mapovanie názvov LDAP používateľských mien", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have a internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." => "Použivateľské mená sa používajú pre uchovávanie a priraďovanie (meta)dát. Pre správnu identifikáciu a rozpoznanie používateľov bude mať každý používateľ z LDAP interné používateľské meno. To je nevyhnutné pre namapovanie používateľských mien na používateľov v LDAP. Vytvorené používateľské meno je namapované na UUID používateľa v LDAP. Naviac je cachovaná DN pre obmedzenie interakcie s LDAP, ale nie je používaná pre identifikáciu. Ak sa DN zmení, bude to správne rozpoznané. Interné používateľské meno sa používa všade. Vyčistenie namapování vymaže zvyšky všade. Vyčistenie naviac nie je špecifické, bude mať vplyv na všetky LDAP konfigurácie! Nikdy nečistite namapovanie v produkčnom prostredí, len v testovacej alebo experimentálnej fáze.", "Clear Username-LDAP User Mapping" => "Zrušiť mapovanie LDAP používateľských mien", -"Clear Groupname-LDAP Group Mapping" => "Zrušiť mapovanie názvov LDAP skupín", -"Test Configuration" => "Test nastavenia", -"Help" => "Pomoc" +"Clear Groupname-LDAP Group Mapping" => "Zrušiť mapovanie názvov LDAP skupín" ); $PLURAL_FORMS = "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"; diff --git a/apps/user_ldap/l10n/sl.php b/apps/user_ldap/l10n/sl.php index 703b643db58..b51c5bc7bb8 100644 --- a/apps/user_ldap/l10n/sl.php +++ b/apps/user_ldap/l10n/sl.php @@ -1,60 +1,92 @@ <?php $TRANSLATIONS = array( -"Failed to clear the mappings." => "Preslikav ni bilo mogoče izbrisati", +"Failed to clear the mappings." => "Čiščenje preslikav je spodletelo.", "Failed to delete the server configuration" => "Brisanje nastavitev strežnika je spodletelo.", "The configuration is valid and the connection could be established!" => "Nastavitev je veljavna, zato je povezavo mogoče vzpostaviti!", -"The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "Nastavitev je veljavna, vendar pa je vez Bind spodletela. Preveriti je treba nastavitve strežnika in ustreznost poveril.", -"The configuration is invalid. Please look in the ownCloud log for further details." => "Nastavitev je veljavna. Več podrobnosti je zapisanih v dnevniku ownCloud.", +"The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "Nastavitev je veljavna, vendar pa je vez spodletela. Preveriti je treba nastavitve strežnika in ustreznost poveril.", +"The configuration is invalid. Please have a look at the logs for further details." => "Nastavitev ni veljavna. Več podrobnosti o napaki je zabeleženih v dnevniku.", +"No action specified" => "Ni določenega dejanja", +"No configuration specified" => "Ni določenih nastavitev", +"No data specified" => "Ni navedenih podatkov", +" Could not set configuration %s" => "Ni mogoče uveljaviti nastavitev %s", "Deletion failed" => "Brisanje je spodletelo.", -"Take over settings from recent server configuration?" => "Ali naj se prevzame nastavitve nedavne nastavitve strežnika?", -"Keep settings?" => "Ali nas se nastavitve ohranijo?", +"Take over settings from recent server configuration?" => "Ali naj bodo prevzete nedavne nastavitve strežnika?", +"Keep settings?" => "Ali naj se nastavitve ohranijo?", "Cannot add server configuration" => "Ni mogoče dodati nastavitev strežnika", -"mappings cleared" => "Preslikave so izbrisane", +"mappings cleared" => "preslikave so izbrisane", "Success" => "Uspešno končano.", "Error" => "Napaka", +"Configuration OK" => "Nastavitev je ustrezna", +"Configuration incorrect" => "Nastavitev ni ustrezna", +"Configuration incomplete" => "Nastavitev je nepopolna", +"Select groups" => "Izberi skupine", +"Select object classes" => "Izbor razredov predmeta", +"Select attributes" => "Izbor atributov", "Connection test succeeded" => "Preizkus povezave je uspešno končan.", "Connection test failed" => "Preizkus povezave je spodletel.", "Do you really want to delete the current Server Configuration?" => "Ali res želite izbrisati trenutne nastavitve strežnika?", "Confirm Deletion" => "Potrdi brisanje", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Opozorilo:</b> modul PHP LDAP mora biti nameščen, sicer vmesnik ne bo deloval. Paket je treba namestiti.", -"Server configuration" => "Nastavitev strežnika", +"_%s group found_::_%s groups found_" => array("%s najdena skupina","%s najdeni skupini","%s najdene skupine","%s najdenih skupin"), +"_%s user found_::_%s users found_" => array("%s najden uporabnik","%s najdena uporabnika","%s najdeni uporabniki","%s najdenih uporabnikov"), +"Invalid Host" => "Neveljaven gostitelj", +"Could not find the desired feature" => "Želene zmožnosti ni mogoče najti", +"Save" => "Shrani", +"Test Configuration" => "Preizkusne nastavitve", +"Help" => "Pomoč", +"Limit the access to %s to groups meeting this criteria:" => "Omeji dostop %s do skupin glede na kriterij:", +"only those object classes:" => "le razredi predmeta:", +"only from those groups:" => "le iz skupin:", +"Edit raw filter instead" => "Uredi surov filter", +"Raw LDAP filter" => "Surovi filter LDAP", +"The filter specifies which LDAP groups shall have access to the %s instance." => "Filter določa, katere skupine LDAP bodo imele dostop do %s.", +"groups found" => "najdenih skupin", +"What attribute shall be used as login name:" => "Kateri atribut naj bo uporabljen kot prijavno ime:", +"LDAP Username:" => "Uporabniško ime LDAP:", +"LDAP Email Address:" => "Elektronski naslov LDAP:", +"Other Attributes:" => "Drugi atributi:", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Določi filter, ki bo uveljavljen ob poskusu prijave. %%uid zamenja uporabniško ime pri prijavi, na primer: \"uid=%%uid\"", "Add Server Configuration" => "Dodaj nastavitve strežnika", "Host" => "Gostitelj", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Protokol je lahko izpuščen, če ni posebej zahtevan SSL. V tem primeru se mora naslov začeti z ldaps://", -"Base DN" => "Osnovni DN", -"One Base DN per line" => "En osnovni DN na vrstico", -"You can specify Base DN for users and groups in the Advanced tab" => "Osnovni DN za uporabnike in skupine lahko določite v zavihku naprednih možnosti.", -"User DN" => "Uporabnik DN", -"The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "DN uporabnikovega odjemalca, s katerim naj se opravi vezava, npr. uid=agent,dc=example,dc=com. Za brezimni dostop sta polji DN in geslo prazni.", +"Port" => "Vrata", +"User DN" => "Uporabnikovo enolično ime", +"The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "Enolično ime uporabnikovega odjemalca, s katerim naj se opravi vezava, npr. uid=agent,dc=example,dc=com. Za brezimni dostop sta polji prikaznega imena in gesla prazni.", "Password" => "Geslo", -"For anonymous access, leave DN and Password empty." => "Za brezimni dostop sta polji DN in geslo prazni.", -"User Login Filter" => "Filter prijav uporabnikov", -"User List Filter" => "Filter seznama uporabnikov", -"Group Filter" => "Filter skupin", +"For anonymous access, leave DN and Password empty." => "Za brezimni dostop naj bosta polji imena in gesla prazni.", +"One Base DN per line" => "Eno osnovno enolično ime na vrstico", +"You can specify Base DN for users and groups in the Advanced tab" => "Osnovno enolično ime za uporabnike in skupine lahko določite v zavihku naprednih možnosti.", +"Limit the access to %s to users meeting this criteria:" => "Omeji dostop do %s uporabnikom, za katere velja kriterij:", +"The filter specifies which LDAP users shall have access to the %s instance." => "Filter določa, kateri uporabniki LDAP bodo imeli dostop do %s.", +"users found" => "najdenih uporabnikov", +"Back" => "Nazaj", +"Continue" => "Nadaljuj", +"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Opozorilo:</b> določili user_ldap in user_webdavauth sta neskladni, kar lahko vpliva na delovanje sistema. O napaki pošljite poročilo skrbniku sistema in opozorite, da je treba eno izmed možnosti onemogočiti.", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Opozorilo:</b> modul PHP LDAP mora biti nameščen, sicer vmesnik ne bo deloval. Paket je treba namestiti.", "Connection Settings" => "Nastavitve povezave", "Configuration Active" => "Dejavna nastavitev", "When unchecked, this configuration will be skipped." => "Neizbrana možnost preskoči nastavitev.", -"Port" => "Vrata", "Backup (Replica) Host" => "Varnostna kopija (replika) podatkov gostitelja", "Give an optional backup host. It must be a replica of the main LDAP/AD server." => "Podati je treba izbirno varnostno kopijo gostitelja. Ta mora biti natančna replika strežnika LDAP/AD.", -"Backup (Replica) Port" => "Varnostna kopija (replika) podatka vrat", +"Backup (Replica) Port" => "Vrata varnostne kopije (replike)", "Disable Main Server" => "Onemogoči glavni strežnik", -"Use TLS" => "Uporabi TLS", -"Do not use it additionally for LDAPS connections, it will fail." => "Strežnika ni priporočljivo uporabljati za povezave LDAPS. Povezava bo spodletela.", +"Only connect to the replica server." => "Poveži le s podvojenim strežnikom.", "Case insensitve LDAP server (Windows)" => "Strežnik LDAP ne upošteva velikosti črk (Windows)", "Turn off SSL certificate validation." => "Onemogoči določanje veljavnosti potrdila SSL.", +"Not recommended, use it for testing only! If connection only works with this option, import the LDAP server's SSL certificate in your %s server." => "Možnosti ni priporočljivo uporabiti; namenjena je zgolj preizkušanju! Če deluje povezava le s to možnostjo, je treba uvoziti potrdilo SSL strežnika LDAP na strežnik %s.", "Cache Time-To-Live" => "Predpomni podatke TTL", "in seconds. A change empties the cache." => "v sekundah. Sprememba izprazni predpomnilnik.", "Directory Settings" => "Nastavitve mape", "User Display Name Field" => "Polje za uporabnikovo prikazano ime", +"The LDAP attribute to use to generate the user's display name." => "Atribut LDAP za uporabo pri ustvarjanju prikaznega imena uporabnika.", "Base User Tree" => "Osnovno uporabniško drevo", -"One User Base DN per line" => "Eno osnovno uporabniško ime DN na vrstico", -"User Search Attributes" => "Uporabi atribute iskanja", +"One User Base DN per line" => "Eno osnovno uporabniško ime na vrstico", +"User Search Attributes" => "Uporabnikovi atributi iskanja", "Optional; one attribute per line" => "Izbirno; en atribut na vrstico", "Group Display Name Field" => "Polje za prikazano ime skupine", +"The LDAP attribute to use to generate the groups's display name." => "Atribut LDAP za uporabo pri ustvarjanju prikaznega imena skupine.", "Base Group Tree" => "Osnovno drevo skupine", -"One Group Base DN per line" => "Eno osnovno ime skupine DN na vrstico", -"Group Search Attributes" => "Atributi iskanja skupine", +"One Group Base DN per line" => "Eno osnovno ime skupine na vrstico", +"Group Search Attributes" => "Skupinski atributi iskanja", "Group-Member association" => "Povezava član-skupina", "Special Attributes" => "Posebni atributi", "Quota Field" => "Polje količinske omejitve", @@ -63,14 +95,16 @@ $TRANSLATIONS = array( "Email Field" => "Polje elektronske pošte", "User Home Folder Naming Rule" => "Pravila poimenovanja uporabniške osebne mape", "Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "Pustite prazno za uporabniško ime (privzeto), sicer navedite atribut LDAP/AD.", -"Internal Username" => "Interno uporabniško ime", -"Internal Username Attribute:" => "Atribut Interno uporabniško ime", +"Internal Username" => "Programsko uporabniško ime", +"By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. To achieve a similar behavior as before ownCloud 5 enter the user display name attribute in the following field. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users." => "Privzeto je notranje uporabniško ime ustvarjeno na osnovi atributa UUID. To omogoča določitev uporabniškega imena kot enoličnega, zato znakov ni treba pretvarjati. Notranje ime je omejeno na standardne znake: [ a-zA-Z0-9_.@- ]. Morebitni drugi znaki so zamenjani z ustreznim ASCII znakom, ali pa so enostavno izpuščeni. V primeru sporov je prišteta ali odšteta številčna vrednost. Notranje uporabniško ime je uporabljeno za določanje uporabnika in je privzeto ime uporabnikove domače mape. Hkrati je tudi del oddaljenega naslova URL, na primer za storitve *DAV. S to nastavitvijo je prepisan privzet način delovanja. Pri različicah ownCloud, nižjih od 5.0, je podoben učinek mogoče doseči z vpisom prikaznega imena oziroma z neizpolnjenim (praznim) poljem te vrednosti. Spremembe bodo uveljavljene le za nove preslikane (dodane) uporabnike LDAP.", +"Internal Username Attribute:" => "Programski atribut uporabniškega imena:", "Override UUID detection" => "Prezri zaznavo UUID", -"UUID Attribute:" => "Atribut UUID", -"Username-LDAP User Mapping" => "Preslikava uporabniško ime - LDAP-uporabnik", -"Clear Username-LDAP User Mapping" => "Izbriši preslikavo Uporabniškega imena in LDAP-uporabnika", -"Clear Groupname-LDAP Group Mapping" => "Izbriši preslikavo Skupine in LDAP-skupine", -"Test Configuration" => "Preizkusne nastavitve", -"Help" => "Pomoč" +"By default, the UUID attribute is automatically detected. The UUID attribute is used to doubtlessly identify LDAP users and groups. Also, the internal username will be created based on the UUID, if not specified otherwise above. You can override the setting and pass an attribute of your choice. You must make sure that the attribute of your choice can be fetched for both users and groups and it is unique. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users and groups." => "Privzeto je atribut UUID samodejno zaznan. Uporabljen je za določevanje uporabnikov LDAP in skupin. Notranje uporabniško ime je določeno prav na atributu UUID, če ni določeno drugače. To nastavitev je mogoče prepisati in poslati poljuben atribut. Zagotoviti je treba le, da je ta pridobljen kot enolični podatek za uporabnika ali skupino. Prazno polje določa privzeti način. Spremembe bodo vplivale na novo preslikane (dodane) uporabnike LDAP in skupine.", +"UUID Attribute for Users:" => "Atribut UUID za uporabnike:", +"UUID Attribute for Groups:" => "Atribut UUID za skupine:", +"Username-LDAP User Mapping" => "Uporabniška preslikava uporabniškega imena na LDAP", +"Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have a internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." => "Uporabniška imena so uporabljena za shranjevanje in dodeljevanje (meta) podatkov. Za natančno določanje in prepoznavanje uporabnikov je uporabljen sistem notranjega uporabniškega imena vsakega uporabnika LDAP. Ta možnost zahteva preslikavo uporabniškega imena v uporabnika LDAP in preslikano na njegov UUID. Sistem predpomni enolična imena za zmanjšanje odvisnosti LDAP, vendar pa ta podatek ni uporabljen za določevanje uporabnika. Če se enolično ime spremeni, se spremeni notranje uporabniško ime. Čiščenje preslikav pušča ostanke podatkov in vpliva na vse nastavitve LDAP! V delovnem okolju zato spreminjanje preslikav ni priporočljivo, možnost pa je na voljo za preizkušanje.", +"Clear Username-LDAP User Mapping" => "Izbriši preslikavo uporabniškega imena na LDAP", +"Clear Groupname-LDAP Group Mapping" => "Izbriši preslikavo skupine na LDAP" ); $PLURAL_FORMS = "nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);"; diff --git a/apps/user_ldap/l10n/sq.php b/apps/user_ldap/l10n/sq.php index 2de62cc009a..0f18ac02351 100644 --- a/apps/user_ldap/l10n/sq.php +++ b/apps/user_ldap/l10n/sq.php @@ -1,7 +1,70 @@ <?php $TRANSLATIONS = array( -"Error" => "Veprim i gabuar", -"Password" => "Kodi", -"Help" => "Ndihmë" +"Failed to clear the mappings." => "dështoi së pastruari planifikimet", +"Failed to delete the server configuration" => "dështoi fshirjen e konfigurimit të serverit", +"The configuration is valid and the connection could be established!" => "Konfigurimi është i vlefshem dhe lidhja mund të kryhet", +"The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "Konfigurimi është i saktë por lidhja dështoi. Kontrolloni konfigurimete serverit dhe kredencialet.", +"Deletion failed" => "Fshirja dështoi", +"Take over settings from recent server configuration?" => "Doni të rivini konfigurmet më të fundit të serverit?", +"Keep settings?" => "Doni të mbani konfigurimet?", +"Cannot add server configuration" => "E pamundur të shtohen konfigurimet në server", +"mappings cleared" => "planifikimi u fshi", +"Success" => "Sukses", +"Error" => "Gabim", +"Connection test succeeded" => "Prova e lidhjes përfundoi me sukses", +"Connection test failed" => "Prova e lidhjes dështoi", +"Do you really want to delete the current Server Configuration?" => "Jeni vërtetë të sigurt të fshini konfigurimet aktuale të serverit?", +"Confirm Deletion" => "Konfirmoni Fshirjen", +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("",""), +"Save" => "Ruaj", +"Test Configuration" => "Provoni konfigurimet", +"Help" => "Ndihmë", +"Add Server Configuration" => "Shtoni konfigurimet e serverit", +"Host" => "Pritësi", +"You can omit the protocol, except you require SSL. Then start with ldaps://" => "Ju mund të mos vendosni protokollin ,vetëm nëse ju nevojitet SSL. atherë filloni me ldaps://", +"Port" => "Porta", +"User DN" => "Përdoruesi DN", +"The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "DN -ja e klientit për përdoruesin që kërkon të lidhet duhet të jetë si psh,uid=agent,dc=example,dc=com. Për lidhjet anonime lini boshe hapsirat e DN dhe fjalëkalim ", +"Password" => "fjalëkalim", +"For anonymous access, leave DN and Password empty." => "Për tu lidhur në mënyre anonime, lini bosh hapsirat e DN dhe fjalëkalim", +"One Base DN per line" => "Një baze DN për rrjesht", +"You can specify Base DN for users and groups in the Advanced tab" => "Ju mund të specifikoni Bazen DN për përdorues dhe grupe në butonin 'Të Përparuara'", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Njoftim:</b> moduli PHP LDAP nuk është instaluar, motori nuk do të funksionojë.Kontaktoni me administratorin e sistemit.", +"Connection Settings" => "Të dhënat e lidhjes", +"Configuration Active" => "Konfigurimi Aktiv", +"When unchecked, this configuration will be skipped." => "Nëse nuk është i zgjedhur, ky konfigurim do të anashkalohet.", +"Backup (Replica) Host" => "Pritësi rezervë (Replika)", +"Give an optional backup host. It must be a replica of the main LDAP/AD server." => "Jepni një pritës rezervë. Duhet të jetë replikimi i serverit AD/LDAP kryesor.", +"Backup (Replica) Port" => "Porta rezervë (Replika)", +"Disable Main Server" => "Ç'aktivizoni serverin kryesor", +"Case insensitve LDAP server (Windows)" => " Server LDAP i pavëmëndshëm ndaj gërmëzimit të madh apo jo (Windows)", +"Turn off SSL certificate validation." => "Ç'aktivizoni kontrollin e certifikatës SSL.", +"Cache Time-To-Live" => "Cache Time-To-Live", +"in seconds. A change empties the cache." => "në sekonda Ndryshimi boshatis 'cache'-n.", +"Directory Settings" => "Konfigurimet e Dosjeve", +"User Display Name Field" => "Hapsira e Emrit të Përdoruesit", +"Base User Tree" => "Struktura bazë e përdoruesit", +"One User Base DN per line" => "Një përdorues baze DN për rrjesht", +"User Search Attributes" => "Atributet e kërkimit të përdoruesëve", +"Optional; one attribute per line" => "Opsionale; një atribut për rrjesht", +"Group Display Name Field" => "Hapsira e Emrit të Grupit", +"Base Group Tree" => "Struktura bazë e grupit", +"One Group Base DN per line" => "Një grup baze DN për rrjesht", +"Group Search Attributes" => "Atributet e kërkimit të grupit", +"Group-Member association" => "Pjestar Grup-Përdorues ", +"Special Attributes" => "Atribute të veçanta", +"Quota Field" => "Hapsira e Kuotës", +"Quota Default" => "Kuota e paracaktuar", +"in bytes" => "në byte", +"Email Field" => "Hapsira e Postës Elektronike", +"User Home Folder Naming Rule" => "Rregulli i emërimit të dosjes së përdoruesit", +"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "Lëreni bosh për emrin e përdoruesit (I Paracaktuar). Ose, përcaktoni një atribut LDAP/AD.", +"Internal Username" => "Emër i brëndshëm i përdoruesit", +"Internal Username Attribute:" => "Atributet e emrit të përdoruesit të brëndshëm", +"Override UUID detection" => "Mbivendosni gjetjen e UUID", +"Username-LDAP User Mapping" => "Emri përdoruesit-LAPD përcaktues përdoruesi", +"Clear Username-LDAP User Mapping" => "Fshini Emër përdoruesi-LAPD Përcaktues përdoruesi", +"Clear Groupname-LDAP Group Mapping" => "Fshini Emër Grupi-LADP Përcaktues grupi" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/sr.php b/apps/user_ldap/l10n/sr.php index d0c9290dc19..d2ce2cf08b6 100644 --- a/apps/user_ldap/l10n/sr.php +++ b/apps/user_ldap/l10n/sr.php @@ -2,18 +2,18 @@ $TRANSLATIONS = array( "Deletion failed" => "Брисање није успело", "Error" => "Грешка", +"_%s group found_::_%s groups found_" => array("","",""), +"_%s user found_::_%s users found_" => array("","",""), +"Save" => "Сачувај", +"Help" => "Помоћ", "Host" => "Домаћин", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Можете да изоставите протокол, осим ако захтевате SSL. У том случају почните са ldaps://.", -"Base DN" => "База DN", +"Port" => "Порт", "User DN" => "Корисник DN", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "DN корисника клијента са којим треба да се успостави веза, нпр. uid=agent,dc=example,dc=com. За анониман приступ, оставите поља DN и лозинка празним.", "Password" => "Лозинка", "For anonymous access, leave DN and Password empty." => "За анониман приступ, оставите поља DN и лозинка празним.", -"User Login Filter" => "Филтер за пријаву корисника", -"User List Filter" => "Филтер за списак корисника", -"Group Filter" => "Филтер групе", -"Port" => "Порт", -"Use TLS" => "Користи TLS", +"Back" => "Назад", "Case insensitve LDAP server (Windows)" => "LDAP сервер осетљив на велика и мала слова (Windows)", "Turn off SSL certificate validation." => "Искључите потврду SSL сертификата.", "in seconds. A change empties the cache." => "у секундама. Промена испражњава кеш меморију.", @@ -22,7 +22,6 @@ $TRANSLATIONS = array( "Group Display Name Field" => "Име приказа групе", "Base Group Tree" => "Основна стабло група", "Group-Member association" => "Придруживање чланова у групу", -"in bytes" => "у бајтовима", -"Help" => "Помоћ" +"in bytes" => "у бајтовима" ); $PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"; diff --git a/apps/user_ldap/l10n/sr@latin.php b/apps/user_ldap/l10n/sr@latin.php index 24fff94fc65..e3023996ad3 100644 --- a/apps/user_ldap/l10n/sr@latin.php +++ b/apps/user_ldap/l10n/sr@latin.php @@ -1,7 +1,10 @@ <?php $TRANSLATIONS = array( "Error" => "Greška", -"Password" => "Lozinka", -"Help" => "Pomoć" +"_%s group found_::_%s groups found_" => array("","",""), +"_%s user found_::_%s users found_" => array("","",""), +"Save" => "Snimi", +"Help" => "Pomoć", +"Password" => "Lozinka" ); $PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"; diff --git a/apps/user_ldap/l10n/sv.php b/apps/user_ldap/l10n/sv.php index 3288438c09b..62beec274e9 100644 --- a/apps/user_ldap/l10n/sv.php +++ b/apps/user_ldap/l10n/sv.php @@ -4,7 +4,11 @@ $TRANSLATIONS = array( "Failed to delete the server configuration" => "Misslyckades med att radera serverinställningen", "The configuration is valid and the connection could be established!" => "Inställningen är giltig och anslutningen kunde upprättas!", "The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "Konfigurationen är riktig, men Bind felade. Var vänlig och kontrollera serverinställningar och logininformation.", -"The configuration is invalid. Please look in the ownCloud log for further details." => "Inställningen är ogiltig. Vänligen se ownCloud-loggen för fler detaljer.", +"The configuration is invalid. Please have a look at the logs for further details." => "Inställningen är ogiltig. Vänligen se ownCloud-loggen för fler detaljer.", +"No action specified" => "Ingen åtgärd har angetts", +"No configuration specified" => "Ingen konfiguration har angetts", +"No data specified" => "Ingen data har angetts", +" Could not set configuration %s" => "Kunde inte sätta inställning %s", "Deletion failed" => "Raderingen misslyckades", "Take over settings from recent server configuration?" => "Ta över inställningar från tidigare serverkonfiguration?", "Keep settings?" => "Behåll inställningarna?", @@ -12,40 +16,58 @@ $TRANSLATIONS = array( "mappings cleared" => "mappningar rensade", "Success" => "Lyckat", "Error" => "Fel", +"Configuration OK" => "Konfigurationen är OK", +"Configuration incorrect" => "Felaktig konfiguration", +"Configuration incomplete" => "Konfigurationen är ej komplett", +"Select groups" => "Välj grupper", +"Select object classes" => "Välj Objekt-klasser", +"Select attributes" => "Välj attribut", "Connection test succeeded" => "Anslutningstestet lyckades", "Connection test failed" => "Anslutningstestet misslyckades", "Do you really want to delete the current Server Configuration?" => "Vill du verkligen radera den nuvarande serverinställningen?", "Confirm Deletion" => "Bekräfta radering", -"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Varning:</b> Apps user_ldap och user_webdavauth är inkompatibla. Oväntade problem kan uppstå. Be din systemadministratör att inaktivera en av dom.", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Varning:</b> PHP LDAP - modulen är inte installerad, serversidan kommer inte att fungera. Kontakta din systemadministratör för installation.", -"Server configuration" => "Serverinställning", +"_%s group found_::_%s groups found_" => array("%s grupp hittad","%s grupper hittade"), +"_%s user found_::_%s users found_" => array("%s användare hittad","%s användare hittade"), +"Invalid Host" => "Felaktig Host", +"Could not find the desired feature" => "Det gick inte hitta den önskade funktionen", +"Save" => "Spara", +"Test Configuration" => "Testa konfigurationen", +"Help" => "Hjälp", +"Limit the access to %s to groups meeting this criteria:" => "Begränsa åtkomsten till %s till grupper som möter följande kriterie:", +"only those object classes:" => "Endast de objekt-klasserna:", +"only from those groups:" => "endast ifrån de här grupperna:", +"The filter specifies which LDAP groups shall have access to the %s instance." => "Filtret specifierar vilka LDAD-grupper som ska ha åtkomst till %s instans", +"groups found" => "grupper hittade", +"What attribute shall be used as login name:" => "Vilket attribut ska användas som login namn:", +"LDAP Username:" => "LDAP användarnamn:", +"LDAP Email Address:" => "LDAP e-postadress:", +"Other Attributes:" => "Övriga attribut:", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Definierar filter som tillämpas vid inloggning. %%uid ersätter användarnamn vid inloggningen. Exempel: \"uid=%%uid\"", "Add Server Configuration" => "Lägg till serverinställning", "Host" => "Server", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Du behöver inte ange protokoll förutom om du använder SSL. Starta då med ldaps://", -"Base DN" => "Start DN", -"One Base DN per line" => "Ett Start DN per rad", -"You can specify Base DN for users and groups in the Advanced tab" => "Du kan ange start DN för användare och grupper under fliken Avancerat", +"Port" => "Port", "User DN" => "Användare DN", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "DN för användaren som skall användas, t.ex. uid=agent, dc=example, dc=com. För anonym åtkomst, lämna DN och lösenord tomt.", "Password" => "Lösenord", "For anonymous access, leave DN and Password empty." => "För anonym åtkomst, lämna DN och lösenord tomt.", -"User Login Filter" => "Filter logga in användare", -"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Definierar filter som tillämpas vid inloggning. %%uid ersätter användarnamn vid inloggningen. Exempel: \"uid=%%uid\"", -"User List Filter" => "Filter lista användare", -"Defines the filter to apply, when retrieving users (no placeholders). Example: \"objectClass=person\"" => "Definierar filter som tillämpas vid sökning efter användare (inga platshållare). Exempel: \"objectClass=person\"", -"Group Filter" => "Gruppfilter", -"Defines the filter to apply, when retrieving groups (no placeholders). Example: \"objectClass=posixGroup\"" => "Definierar filter som tillämpas vid sökning efter grupper (inga platshållare). Exempel: \"objectClass=posixGroup\"", +"One Base DN per line" => "Ett Start DN per rad", +"You can specify Base DN for users and groups in the Advanced tab" => "Du kan ange start DN för användare och grupper under fliken Avancerat", +"Limit the access to %s to users meeting this criteria:" => "Begränsa åtkomsten till %s till användare som möter följande kriterie:", +"The filter specifies which LDAP users shall have access to the %s instance." => "Filtret specifierar vilka LDAP-användare som skall ha åtkomst till %s instans", +"users found" => "användare funna", +"Back" => "Tillbaka", +"Continue" => "Fortsätt", +"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Varning:</b> Apps user_ldap och user_webdavauth är inkompatibla. Oväntade problem kan uppstå. Be din systemadministratör att inaktivera en av dom.", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Varning:</b> PHP LDAP - modulen är inte installerad, serversidan kommer inte att fungera. Kontakta din systemadministratör för installation.", "Connection Settings" => "Uppkopplingsinställningar", "Configuration Active" => "Konfiguration aktiv", "When unchecked, this configuration will be skipped." => "Ifall denna är avbockad så kommer konfigurationen att skippas.", -"Port" => "Port", "Backup (Replica) Host" => "Säkerhetskopierings-värd (Replika)", "Give an optional backup host. It must be a replica of the main LDAP/AD server." => "Ange en valfri värd för säkerhetskopiering. Den måste vara en replika av den huvudsakliga LDAP/AD-servern", "Backup (Replica) Port" => "Säkerhetskopierins-port (Replika)", "Disable Main Server" => "Inaktivera huvudserver", "Only connect to the replica server." => "Anslut endast till replikaservern.", -"Use TLS" => "Använd TLS", -"Do not use it additionally for LDAPS connections, it will fail." => "Använd inte för LDAPS-anslutningar, det kommer inte att fungera.", "Case insensitve LDAP server (Windows)" => "LDAP-servern är okänslig för gemener och versaler (Windows)", "Turn off SSL certificate validation." => "Stäng av verifiering av SSL-certifikat.", "Not recommended, use it for testing only! If connection only works with this option, import the LDAP server's SSL certificate in your %s server." => "Rekommenderas inte, använd endast för test! Om anslutningen bara fungerar med denna inställning behöver du importera LDAP-serverns SSL-certifikat till din %s server.", @@ -76,12 +98,11 @@ $TRANSLATIONS = array( "Internal Username Attribute:" => "Internt Användarnamn Attribut:", "Override UUID detection" => "Åsidosätt UUID detektion", "By default, the UUID attribute is automatically detected. The UUID attribute is used to doubtlessly identify LDAP users and groups. Also, the internal username will be created based on the UUID, if not specified otherwise above. You can override the setting and pass an attribute of your choice. You must make sure that the attribute of your choice can be fetched for both users and groups and it is unique. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users and groups." => "Som standard upptäcker ownCloud automatiskt UUID-attributet. Det UUID-attributet används för att utan tvivel identifiera LDAP-användare och grupper. Dessutom kommer interna användarnamn skapas baserat på detta UUID, om inte annat anges ovan. Du kan åsidosätta inställningen och passera ett attribut som du själv väljer. Du måste se till att attributet som du väljer kan hämtas för både användare och grupper och att det är unikt. Lämna det tomt för standard beteende. Förändringar kommer endast att påverka nyligen mappade (tillagda) LDAP-användare och grupper.", -"UUID Attribute:" => "UUID Attribut:", +"UUID Attribute for Users:" => "UUID Attribut för Användare:", +"UUID Attribute for Groups:" => "UUID Attribut för Grupper:", "Username-LDAP User Mapping" => "Användarnamn-LDAP User Mapping", "Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have a internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." => "ownCloud använder sig av användarnamn för att lagra och tilldela (meta) data. För att exakt kunna identifiera och känna igen användare, kommer varje LDAP-användare ha ett internt användarnamn. Detta kräver en mappning från ownCloud-användarnamn till LDAP-användare. Det skapade användarnamnet mappas till UUID för LDAP-användaren. Dessutom cachas DN samt minska LDAP-interaktionen, men den används inte för identifiering. Om DN förändras, kommer förändringarna hittas av ownCloud. Det interna ownCloud-namnet används överallt i ownCloud. Om du rensar/raderar mappningarna kommer att lämna referenser överallt i systemet. Men den är inte konfigurationskänslig, den påverkar alla LDAP-konfigurationer! Rensa/radera aldrig mappningarna i en produktionsmiljö. Utan gör detta endast på i testmiljö!", "Clear Username-LDAP User Mapping" => "Rensa Användarnamn-LDAP User Mapping", -"Clear Groupname-LDAP Group Mapping" => "Rensa Gruppnamn-LDAP Group Mapping", -"Test Configuration" => "Testa konfigurationen", -"Help" => "Hjälp" +"Clear Groupname-LDAP Group Mapping" => "Rensa Gruppnamn-LDAP Group Mapping" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/sw_KE.php b/apps/user_ldap/l10n/sw_KE.php new file mode 100644 index 00000000000..3a1e002311c --- /dev/null +++ b/apps/user_ldap/l10n/sw_KE.php @@ -0,0 +1,6 @@ +<?php +$TRANSLATIONS = array( +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("","") +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/ta_LK.php b/apps/user_ldap/l10n/ta_LK.php index 25053f2e3d1..c7efcf05894 100644 --- a/apps/user_ldap/l10n/ta_LK.php +++ b/apps/user_ldap/l10n/ta_LK.php @@ -2,14 +2,17 @@ $TRANSLATIONS = array( "Deletion failed" => "நீக்கம் தோல்வியடைந்தது", "Error" => "வழு", +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("",""), +"Save" => "சேமிக்க ", +"Help" => "உதவி", "Host" => "ஓம்புனர்", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "நீங்கள் SSL சேவையை தவிர உடன்படு வரைமுறையை தவிர்க்க முடியும். பிறகு ldaps:.// உடன் ஆரம்பிக்கவும்", -"Base DN" => "தள DN", -"You can specify Base DN for users and groups in the Advanced tab" => "நீங்கள் பயனாளர்களுக்கும் மேன்மை தத்தலில் உள்ள குழுவிற்கும் தள DN ஐ குறிப்பிடலாம் ", +"Port" => "துறை ", "User DN" => "பயனாளர் DN", "Password" => "கடவுச்சொல்", -"Port" => "துறை ", -"Use TLS" => "TLS ஐ பயன்படுத்தவும்", +"You can specify Base DN for users and groups in the Advanced tab" => "நீங்கள் பயனாளர்களுக்கும் மேன்மை தத்தலில் உள்ள குழுவிற்கும் தள DN ஐ குறிப்பிடலாம் ", +"Back" => "பின்னுக்கு", "Case insensitve LDAP server (Windows)" => "உணர்ச்சியான LDAP சேவையகம் (சாளரங்கள்)", "Turn off SSL certificate validation." => "SSL சான்றிதழின் செல்லுபடியை நிறுத்திவிடவும்", "in seconds. A change empties the cache." => "செக்கன்களில். ஒரு மாற்றம் இடைமாற்றுநினைவகத்தை வெற்றிடமாக்கும்.", @@ -19,7 +22,6 @@ $TRANSLATIONS = array( "Base Group Tree" => "தள குழு மரம்", "Group-Member association" => "குழு உறுப்பினர் சங்கம்", "in bytes" => "bytes களில் ", -"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "பயனாளர் பெயரிற்கு வெற்றிடமாக விடவும் (பொது இருப்பு). இல்லாவிடின் LDAP/AD பண்புக்கூறை குறிப்பிடவும்.", -"Help" => "உதவி" +"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "பயனாளர் பெயரிற்கு வெற்றிடமாக விடவும் (பொது இருப்பு). இல்லாவிடின் LDAP/AD பண்புக்கூறை குறிப்பிடவும்." ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/te.php b/apps/user_ldap/l10n/te.php index 23728a9d34b..ad3ffb1c5e8 100644 --- a/apps/user_ldap/l10n/te.php +++ b/apps/user_ldap/l10n/te.php @@ -1,7 +1,10 @@ <?php $TRANSLATIONS = array( "Error" => "పొరపాటు", -"Password" => "సంకేతపదం", -"Help" => "సహాయం" +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("",""), +"Save" => "భద్రపరచు", +"Help" => "సహాయం", +"Password" => "సంకేతపదం" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/th_TH.php b/apps/user_ldap/l10n/th_TH.php index 91d93e1235c..2202a2f0a83 100644 --- a/apps/user_ldap/l10n/th_TH.php +++ b/apps/user_ldap/l10n/th_TH.php @@ -3,35 +3,34 @@ $TRANSLATIONS = array( "Failed to delete the server configuration" => "การลบการกำหนดค่าเซิร์ฟเวอร์ล้มเหลว", "The configuration is valid and the connection could be established!" => "การกำหนดค่าถูกต้องและการเชื่อมต่อสามารถเชื่อมต่อได้!", "The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "การกำหนดค่าถูกต้อง, แต่การผูกข้อมูลล้มเหลว, กรุณาตรวจสอบการตั้งค่าเซิร์ฟเวอร์และข้อมูลการเข้าใช้งาน", -"The configuration is invalid. Please look in the ownCloud log for further details." => "การกำหนดค่าไม่ถูกต้อง กรุณาดูรายละเอียดจากบันทึกการเปลี่ยนแปลงของ ownCloud สำหรับรายละเอียดเพิ่มเติม", "Deletion failed" => "การลบทิ้งล้มเหลว", "Keep settings?" => "รักษาการตั้งค่าไว้?", "Cannot add server configuration" => "ไม่สามารถเพิ่มค่ากำหนดเซิร์ฟเวอร์ได้", "Success" => "เสร็จสิ้น", "Error" => "ข้อผิดพลาด", +"Select groups" => "เลือกกลุ่ม", "Connection test succeeded" => "ทดสอบการเชื่อมต่อสำเร็จ", "Connection test failed" => "ทดสอบการเชื่อมต่อล้มเหลว", "Do you really want to delete the current Server Configuration?" => "คุณแน่ใจแล้วหรือว่าต้องการลบการกำหนดค่าเซิร์ฟเวอร์ปัจจุบันทิ้งไป?", "Confirm Deletion" => "ยืนยันการลบทิ้ง", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>คำเตือน:</b> โมดูล PHP LDAP ยังไม่ได้ถูกติดตั้ง, ระบบด้านหลังจะไม่สามารถทำงานได้ กรุณาติดต่อผู้ดูแลระบบของคุณเพื่อทำการติดตั้งโมดูลดังกล่าว", -"Server configuration" => "การกำหนดค่าเซิร์ฟเวอร์", +"_%s group found_::_%s groups found_" => array(""), +"_%s user found_::_%s users found_" => array(""), +"Save" => "บันทึก", +"Help" => "ช่วยเหลือ", "Add Server Configuration" => "เพิ่มการกำหนดค่าเซิร์ฟเวอร์", "Host" => "โฮสต์", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "คุณสามารถปล่อยช่องโปรโตคอลเว้นไว้ได้, ยกเว้นกรณีที่คุณต้องการใช้ SSL จากนั้นเริ่มต้นด้วย ldaps://", -"Base DN" => "DN ฐาน", -"One Base DN per line" => "หนึ่ง Base DN ต่อบรรทัด", -"You can specify Base DN for users and groups in the Advanced tab" => "คุณสามารถระบุ DN หลักสำหรับผู้ใช้งานและกลุ่มต่างๆในแท็บขั้นสูงได้", +"Port" => "พอร์ต", "User DN" => "DN ของผู้ใช้งาน", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "DN ของผู้ใช้งานที่เป็นลูกค้าอะไรก็ตามที่ผูกอยู่ด้วย เช่น uid=agent, dc=example, dc=com, สำหรับการเข้าถึงโดยบุคคลนิรนาม, ให้เว้นว่าง DN และ รหัสผ่านเอาไว้", "Password" => "รหัสผ่าน", "For anonymous access, leave DN and Password empty." => "สำหรับการเข้าถึงโดยบุคคลนิรนาม ให้เว้นว่าง DN และรหัสผ่านไว้", -"User Login Filter" => "ตัวกรองข้อมูลการเข้าสู่ระบบของผู้ใช้งาน", -"User List Filter" => "ตัวกรองข้อมูลรายชื่อผู้ใช้งาน", -"Group Filter" => "ตัวกรองข้อมูลกลุ่ม", +"One Base DN per line" => "หนึ่ง Base DN ต่อบรรทัด", +"You can specify Base DN for users and groups in the Advanced tab" => "คุณสามารถระบุ DN หลักสำหรับผู้ใช้งานและกลุ่มต่างๆในแท็บขั้นสูงได้", +"Back" => "ย้อนกลับ", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>คำเตือน:</b> โมดูล PHP LDAP ยังไม่ได้ถูกติดตั้ง, ระบบด้านหลังจะไม่สามารถทำงานได้ กรุณาติดต่อผู้ดูแลระบบของคุณเพื่อทำการติดตั้งโมดูลดังกล่าว", "Connection Settings" => "ตั้งค่าการเชื่อมต่อ", -"Port" => "พอร์ต", "Disable Main Server" => "ปิดใช้งานเซิร์ฟเวอร์หลัก", -"Use TLS" => "ใช้ TLS", "Case insensitve LDAP server (Windows)" => "เซิร์ฟเวอร์ LDAP ประเภท Case insensitive (วินโดวส์)", "Turn off SSL certificate validation." => "ปิดใช้งานการตรวจสอบความถูกต้องของใบรับรองความปลอดภัย SSL", "in seconds. A change empties the cache." => "ในอีกไม่กี่วินาที ระบบจะเปลี่ยนแปลงข้อมูลในแคชให้ว่างเปล่า", @@ -48,7 +47,6 @@ $TRANSLATIONS = array( "Group-Member association" => "ความสัมพันธ์ของสมาชิกในกลุ่ม", "Special Attributes" => "คุณลักษณะพิเศษ", "in bytes" => "ในหน่วยไบต์", -"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "เว้นว่างไว้สำหรับ ชื่อผู้ใช้ (ค่าเริ่มต้น) หรือไม่กรุณาระบุคุณลักษณะของ LDAP/AD", -"Help" => "ช่วยเหลือ" +"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "เว้นว่างไว้สำหรับ ชื่อผู้ใช้ (ค่าเริ่มต้น) หรือไม่กรุณาระบุคุณลักษณะของ LDAP/AD" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/user_ldap/l10n/tr.php b/apps/user_ldap/l10n/tr.php index fc9cceddf03..8299c5fecac 100644 --- a/apps/user_ldap/l10n/tr.php +++ b/apps/user_ldap/l10n/tr.php @@ -1,58 +1,110 @@ <?php $TRANSLATIONS = array( +"Failed to clear the mappings." => "Eşleştirmeler temizlenirken hata oluştu.", "Failed to delete the server configuration" => "Sunucu yapılandırmasını silme başarısız oldu", "The configuration is valid and the connection could be established!" => "Yapılandırma geçerli ve bağlantı kuruldu!", -"The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "Yapılandırma geçerli fakat bağlanma(bind) başarısız. Lütfen Sunucu ayarları ve kimlik bilgilerini kontrol ediniz.", -"The configuration is invalid. Please look in the ownCloud log for further details." => "Yapılandırma geçersiz. Daha fazla detay için lütfen ownCloud günlüklerine bakınız.", +"The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "Yapılandırma geçerli fakat bağlama (bind) başarısız. Lütfen Sunucu ayarları ve kimlik bilgilerini kontrol edin.", +"The configuration is invalid. Please have a look at the logs for further details." => "Yapılandırma geçersiz. Lütfen ayrıntılar için günlüklere bakın.", +"No action specified" => "Eylem belirtilmedi", +"No configuration specified" => "Yapılandırma belirtilmemiş", +"No data specified" => "Veri belirtilmemiş", +" Could not set configuration %s" => "Yapılandırma %s olarak ayarlanamadı", "Deletion failed" => "Silme başarısız oldu", -"Take over settings from recent server configuration?" => "Ayarları son sunucu yapılandırmalarından devral?", +"Take over settings from recent server configuration?" => "Ayarlar son sunucu yapılandırmalarından devralınsın mı?", "Keep settings?" => "Ayarlar kalsın mı?", "Cannot add server configuration" => "Sunucu yapılandırması eklenemedi", +"mappings cleared" => "eşleştirmeler temizlendi", +"Success" => "Başarılı", "Error" => "Hata", +"Configuration OK" => "Yapılandırma tamam", +"Configuration incorrect" => "Yapılandırma geçersiz", +"Configuration incomplete" => "Yapılandırma tamamlanmamış", +"Select groups" => "Grupları seç", +"Select object classes" => "Nesne sınıflarını seç", +"Select attributes" => "Nitelikleri seç", "Connection test succeeded" => "Bağlantı testi başarılı oldu", "Connection test failed" => "Bağlantı testi başarısız oldu", "Do you really want to delete the current Server Configuration?" => "Şu anki sunucu yapılandırmasını silmek istediğinizden emin misiniz?", "Confirm Deletion" => "Silmeyi onayla", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Ihbar <b> Modulu PHP LDAP yuklemdi degil, backend calismacak. Lutfen sistem yonetici sormak yuklemek icin.", -"Server configuration" => "Sunucu uyunlama ", +"_%s group found_::_%s groups found_" => array("%s grup bulundu","%s grup bulundu"), +"_%s user found_::_%s users found_" => array("%s kullanıcı bulundu","%s kullanıcı bulundu"), +"Invalid Host" => "Geçersiz Makine", +"Could not find the desired feature" => "İstenen özellik bulunamadı", +"Save" => "Kaydet", +"Test Configuration" => "Test Yapılandırması", +"Help" => "Yardım", +"Limit the access to %s to groups meeting this criteria:" => "%s erişimini, şu kriterle eşleşen gruplara sınırla:", +"only those object classes:" => "sadece bu nesne sınıflarına:", +"only from those groups:" => "sadece bu gruplardan:", +"Edit raw filter instead" => "Bunun yerine ham filtreyi düzenle", +"Raw LDAP filter" => "Ham LDAP filtresi", +"The filter specifies which LDAP groups shall have access to the %s instance." => "Filtre, %s örneğine erişmesi gereken LDAP gruplarını belirtir.", +"groups found" => "grup bulundu", +"What attribute shall be used as login name:" => "Oturum ismi olarak hangi nitelik kullanılmalı:", +"LDAP Username:" => "LDAP Kullanıcı Adı:", +"LDAP Email Address:" => "LDAP E-posta Adresi:", +"Other Attributes:" => "Diğer Nitelikler", +"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" => "Oturum açma girişimi olduğunda uygulanacak filtreyi tanımlar. %%uid, oturum işleminde kullanıcı adı ile değiştirilir. Örneğin: \"uid=%%uid\"", "Add Server Configuration" => "Sunucu Uyunlama birlemek ", "Host" => "Sunucu", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Protokol atlamak edesin, sadece SSL istiyorsaniz. O zaman, idapsile baslamak. ", -"Base DN" => "Ana DN", -"One Base DN per line" => "Bir Tabani DN herbir dizi. ", -"You can specify Base DN for users and groups in the Advanced tab" => "Base DN kullanicileri ve kaynaklari icin tablosu Advanced tayin etmek ederiz. ", +"Port" => "Port", "User DN" => "Kullanıcı DN", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "DN musterinin, kimle baglamaya yapacagiz,meselâ uid=agent.dc mesela, dc=com Gecinme adisiz ici, DN ve Parola bos birakmak. ", "Password" => "Parola", "For anonymous access, leave DN and Password empty." => "Anonim erişim için DN ve Parola alanlarını boş bırakın.", -"User Login Filter" => "Kullanıcı Oturum Filtresi", -"User List Filter" => "Kullanıcı Liste Filtresi", -"Group Filter" => "Grup Süzgeci", +"One Base DN per line" => "Bir Tabani DN herbir dizi. ", +"You can specify Base DN for users and groups in the Advanced tab" => "Base DN kullanicileri ve kaynaklari icin tablosu Advanced tayin etmek ederiz. ", +"Limit the access to %s to users meeting this criteria:" => "%s erişimini, şu kriterle eşleşen kullanıcılara sınırla:", +"The filter specifies which LDAP users shall have access to the %s instance." => "Filtre, %s örneğine erişmesi gereken LDAP kullanıcılarını belirtir.", +"users found" => "kullanıcı bulundu", +"Back" => "Geri", +"Continue" => "Devam et", +"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Uyarı:</b> user_ldap ve user_webdavauth uygulamaları uyumlu değil. Beklenmedik bir davranışla karşılaşabilirsiniz. Lütfen ikisinden birini devre dışı bırakmak için sistem yöneticinizle iletişime geçin.", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Ihbar <b> Modulu PHP LDAP yuklemdi degil, backend calismacak. Lutfen sistem yonetici sormak yuklemek icin.", "Connection Settings" => "Bağlantı ayarları", +"Configuration Active" => "Yapılandırma Etkin", "When unchecked, this configuration will be skipped." => "Ne zaman iptal, bu uynnlama isletici ", -"Port" => "Port", "Backup (Replica) Host" => "Sigorta Kopya Cephe ", "Give an optional backup host. It must be a replica of the main LDAP/AD server." => "Bir kopya cevre vermek, kopya sunucu onemli olmali. ", "Backup (Replica) Port" => "Kopya Port ", "Disable Main Server" => "Ana sunucuyu devredışı birak", -"Use TLS" => "TLS kullan", -"Do not use it additionally for LDAPS connections, it will fail." => "Bu LDAPS baglama icin kullamaminiz, basamacak. ", +"Only connect to the replica server." => "Sadece kopya sunucuya bağlan.", "Case insensitve LDAP server (Windows)" => "Dusme sunucu LDAP zor degil. (Windows)", "Turn off SSL certificate validation." => "SSL sertifika doğrulamasını kapat.", +"Not recommended, use it for testing only! If connection only works with this option, import the LDAP server's SSL certificate in your %s server." => "Önerilmez, sadece test için kullanın! Eğer bağlantı sadece bu seçenekle çalışıyorsa %s sunucunuza LDAP sunucusunun SSL sertifikasını ekleyin.", "Cache Time-To-Live" => "Cache Time-To-Live ", "in seconds. A change empties the cache." => "saniye cinsinden. Bir değişiklik önbelleği temizleyecektir.", "Directory Settings" => "Parametrar Listesin Adresinin ", "User Display Name Field" => "Ekran Adi Kullanici, (Alan Adi Kullanici Ekrane)", +"The LDAP attribute to use to generate the user's display name." => "Kullanıcının görünen adını oluşturmak için kullanılacak LDAP niteliği.", "Base User Tree" => "Temel Kullanıcı Ağacı", "One User Base DN per line" => "Bir Temel Kullanici DN her dizgi ", "User Search Attributes" => "Kategorii Arama Kullanici ", +"Optional; one attribute per line" => "Tercihe bağlı; her bir satırda bir öznitelik", "Group Display Name Field" => "Grub Ekrane Alani Adi", +"The LDAP attribute to use to generate the groups's display name." => "Grubun görünen adını oluşturmak için kullanılacak LDAP niteliği.", "Base Group Tree" => "Temel Grup Ağacı", "One Group Base DN per line" => "Bir Grubu Tabani DN her dizgi. ", "Group Search Attributes" => "Kategorii Arama Grubu", "Group-Member association" => "Grup-Üye işbirliği", +"Special Attributes" => "Özel Öznitelikler", +"Quota Field" => "Kota Alanı", +"Quota Default" => "Öntanımlı Kota", "in bytes" => "byte cinsinden", +"Email Field" => "E-posta Alanı", +"User Home Folder Naming Rule" => "Kullanıcı Ana Dizini İsimlendirme Kuralı", "Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "Kullanıcı adı bölümünü boş bırakın (varsayılan). ", -"Help" => "Yardım" +"Internal Username" => "Dahili Kullanıcı Adı", +"By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. To achieve a similar behavior as before ownCloud 5 enter the user display name attribute in the following field. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users." => "Öntanımlı olarak UUID niteliğinden dahili bir kullanıcı adı oluşturulacak. Bu, kullanıcı adının benzersiz ve karakterlerinin dönüştürme gereksinimini ortadan kaldırır. Dahili kullanıcı adı, sadece bu karakterlerin izin verildiği kısıtlamaya sahip: [ a-zA-Z0-9_.@- ]. Diğer karakterler ise ASCII karşılıkları ile yer değiştirilir veya basitçe yoksayılır. Çakışmalar olduğunda ise bir numara eklenir veya arttırılır. Dahili kullanıcı adı, bir kullanıcıyı dahili olarak tanımlamak için kullanılır. Ayrıca kullanıcı ev klasörü için öntanımlı bir isimdir. Bu ayrıca uzak adreslerin (örneğin tüm *DAV hizmetleri) bir parçasıdır. Bu yar ise, öntanımlı davranışın üzerine yazılabilir. ownCloud 5'ten önce benzer davranışı yapabilmek için aşağıdaki alana bir kullanıcı görünen adı niteliği girin. Öntanımlı davranış için boş bırakın. Değişiklikler, sadece yeni eşleştirilen (eklenen) LDAP kullanıcılarında etkili olacaktır.", +"Internal Username Attribute:" => "Dahili Kullanıcı Adı Özniteliği:", +"Override UUID detection" => "UUID tespitinin üzerine yaz", +"By default, the UUID attribute is automatically detected. The UUID attribute is used to doubtlessly identify LDAP users and groups. Also, the internal username will be created based on the UUID, if not specified otherwise above. You can override the setting and pass an attribute of your choice. You must make sure that the attribute of your choice can be fetched for both users and groups and it is unique. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users and groups." => "Öntanımlı olarak, UUID niteliği otomatik olarak tespit edilmez. UUID niteliği LDAP kullanıcılarını ve gruplarını şüphesiz biçimde tanımlamak için kullanılır. Ayrıca yukarıda belirtilmemişse, bu UUID'ye bağlı olarak dahili bir kullanıcı adı oluşturulacaktır. Bu ayarın üzerine yazabilir ve istediğiniz bir nitelik belirtebilirsiniz. Ancak istediğiniz niteliğin benzersiz olduğundan ve hem kullanıcı hem de gruplar tarafından getirilebileceğinden emin olmalısınız. Öntanımlı davranış için boş bırakın. Değişiklikler sadece yeni eşleştirilen (eklenen) LDAP kullanıcı ve gruplarında etkili olacaktır.", +"UUID Attribute for Users:" => "Kullanıcılar için UUID Özniteliği:", +"UUID Attribute for Groups:" => "Gruplar için UUID Özniteliği:", +"Username-LDAP User Mapping" => "Kullanıcı Adı-LDAP Kullanıcısı Eşleştirme", +"Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have a internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage." => "Kullanıcı adları, (üst) veri depolaması ve ataması için kullanılır. Kullanıcıları kesin olarak tanımlamak ve algılamak için, her LDAP kullanıcısı bir dahili kullanıcı adına sahip olacak. Bu kullanıcı adı ile LDAP kullanıcısı arasında bir eşleşme gerektirir. Oluşturulan kullanıcı adı LDAP kullanıcısının UUID'si ile eşleştirilir. Ek olarak LDAP etkileşimini azaltmak için DN de önbelleğe alınır ancak bu kimlik tanıma için kullanılmaz. Eğer DN değişirse, değişiklikler tespit edilir. Dahili kullanıcı her yerde kullanılır. Eşleştirmeleri temizlemek, her yerde kalıntılar bırakacaktır. Eşleştirmeleri temizlemek yapılandırmaya hassas bir şekilde bağlı değildir, tüm LDAP yapılandırmalarını etkiler! Üretim ortamında eşleştirmeleri asla temizlemeyin, sadece sınama veya deneysel aşamada kullanın.", +"Clear Username-LDAP User Mapping" => "Kullanıcı Adı-LDAP Kullanıcısı Eşleştirmesini Temizle", +"Clear Groupname-LDAP Group Mapping" => "Grup Adı-LDAP Grubu Eşleştirme" ); $PLURAL_FORMS = "nplurals=2; plural=(n > 1);"; diff --git a/apps/user_ldap/l10n/tzm.php b/apps/user_ldap/l10n/tzm.php new file mode 100644 index 00000000000..5a0481c397a --- /dev/null +++ b/apps/user_ldap/l10n/tzm.php @@ -0,0 +1,6 @@ +<?php +$TRANSLATIONS = array( +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("","") +); +$PLURAL_FORMS = "nplurals=2; plural=(n == 0 || n == 1 || (n > 10 && n < 100) ? 0 : 1;"; diff --git a/apps/user_ldap/l10n/ug.php b/apps/user_ldap/l10n/ug.php index 39382fed1f0..7f751814396 100644 --- a/apps/user_ldap/l10n/ug.php +++ b/apps/user_ldap/l10n/ug.php @@ -2,15 +2,14 @@ $TRANSLATIONS = array( "Deletion failed" => "ئۆچۈرۈش مەغلۇپ بولدى", "Error" => "خاتالىق", +"_%s group found_::_%s groups found_" => array(""), +"_%s user found_::_%s users found_" => array(""), +"Save" => "ساقلا", +"Help" => "ياردەم", "Host" => "باش ئاپپارات", +"Port" => "ئېغىز", "Password" => "ئىم", -"User Login Filter" => "ئىشلەتكۈچى تىزىمغا كىرىش سۈزگۈچى", -"User List Filter" => "ئىشلەتكۈچى تىزىم سۈزگۈچى", -"Group Filter" => "گۇرۇپپا سۈزگۈچ", "Connection Settings" => "باغلىنىش تەڭشىكى", -"Configuration Active" => "سەپلىمە ئاكتىپ", -"Port" => "ئېغىز", -"Use TLS" => "TLS ئىشلەت", -"Help" => "ياردەم" +"Configuration Active" => "سەپلىمە ئاكتىپ" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/user_ldap/l10n/uk.php b/apps/user_ldap/l10n/uk.php index 5fb52761215..e87348ec44d 100644 --- a/apps/user_ldap/l10n/uk.php +++ b/apps/user_ldap/l10n/uk.php @@ -3,42 +3,42 @@ $TRANSLATIONS = array( "Failed to delete the server configuration" => "Не вдалося видалити конфігурацію сервера", "The configuration is valid and the connection could be established!" => "Конфігурація вірна і зв'язок може бути встановлений !", "The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "Конфігурація вірна, але встановити зв'язок не вдалося. Будь ласка, перевірте налаштування сервера і облікові дані.", -"The configuration is invalid. Please look in the ownCloud log for further details." => "Конфігурація невірна. Подробиці подивіться, будь ласка, в журналі ownCloud.", "Deletion failed" => "Видалення не було виконано", "Take over settings from recent server configuration?" => "Застосувати налаштування з останньої конфігурації сервера ?", "Keep settings?" => "Зберегти налаштування ?", "Cannot add server configuration" => "Неможливо додати конфігурацію сервера", "Success" => "Успіх", "Error" => "Помилка", +"Select groups" => "Оберіть групи", "Connection test succeeded" => "Перевірка з'єднання пройшла успішно", "Connection test failed" => "Перевірка з'єднання завершилась неуспішно", "Do you really want to delete the current Server Configuration?" => "Ви дійсно бажаєте видалити поточну конфігурацію сервера ?", "Confirm Deletion" => "Підтвердіть Видалення", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Увага:</ b> Потрібний модуль PHP LDAP не встановлено, базова програма працювати не буде. Будь ласка, зверніться до системного адміністратора, щоб встановити його.", -"Server configuration" => "Налаштування Сервера", +"_%s group found_::_%s groups found_" => array("","",""), +"_%s user found_::_%s users found_" => array("","",""), +"Save" => "Зберегти", +"Test Configuration" => "Тестове налаштування", +"Help" => "Допомога", "Add Server Configuration" => "Додати налаштування Сервера", "Host" => "Хост", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Можна не вказувати протокол, якщо вам не потрібен SSL. Тоді почніть з ldaps://", -"Base DN" => "Базовий DN", -"One Base DN per line" => "Один Base DN на одній строчці", -"You can specify Base DN for users and groups in the Advanced tab" => "Ви можете задати Базовий DN для користувачів і груп на вкладинці Додатково", +"Port" => "Порт", "User DN" => "DN Користувача", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "DN клієнтського користувача для прив'язки, наприклад: uid=agent,dc=example,dc=com. Для анонімного доступу, залиште DN і Пароль порожніми.", "Password" => "Пароль", "For anonymous access, leave DN and Password empty." => "Для анонімного доступу, залиште DN і Пароль порожніми.", -"User Login Filter" => "Фільтр Користувачів, що під'єднуються", -"User List Filter" => "Фільтр Списку Користувачів", -"Group Filter" => "Фільтр Груп", +"One Base DN per line" => "Один Base DN на одній строчці", +"You can specify Base DN for users and groups in the Advanced tab" => "Ви можете задати Базовий DN для користувачів і груп на вкладинці Додатково", +"Back" => "Назад", +"Continue" => "Продовжити", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Увага:</ b> Потрібний модуль PHP LDAP не встановлено, базова програма працювати не буде. Будь ласка, зверніться до системного адміністратора, щоб встановити його.", "Connection Settings" => "Налаштування З'єднання", "Configuration Active" => "Налаштування Активне", "When unchecked, this configuration will be skipped." => "Якщо \"галочка\" знята, ця конфігурація буде пропущена.", -"Port" => "Порт", "Backup (Replica) Host" => "Сервер для резервних копій", "Give an optional backup host. It must be a replica of the main LDAP/AD server." => "Вкажіть додатковий резервний сервер. Він повинен бути копією головного LDAP/AD сервера.", "Backup (Replica) Port" => "Порт сервера для резервних копій", "Disable Main Server" => "Вимкнути Головний Сервер", -"Use TLS" => "Використовуйте TLS", -"Do not use it additionally for LDAPS connections, it will fail." => "Не використовуйте це додатково для під'єднання до LDAP, бо виконано не буде.", "Case insensitve LDAP server (Windows)" => "Нечутливий до регістру LDAP сервер (Windows)", "Turn off SSL certificate validation." => "Вимкнути перевірку SSL сертифіката.", "Cache Time-To-Live" => "Час актуальності Кеша", @@ -60,8 +60,6 @@ $TRANSLATIONS = array( "in bytes" => "в байтах", "Email Field" => "Поле Ел. пошти", "User Home Folder Naming Rule" => "Правило іменування домашньої теки користувача", -"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "Залиште порожнім для імені користувача (за замовчанням). Інакше, вкажіть атрибут LDAP/AD.", -"Test Configuration" => "Тестове налаштування", -"Help" => "Допомога" +"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "Залиште порожнім для імені користувача (за замовчанням). Інакше, вкажіть атрибут LDAP/AD." ); $PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"; diff --git a/apps/user_ldap/l10n/ur.php b/apps/user_ldap/l10n/ur.php new file mode 100644 index 00000000000..3a1e002311c --- /dev/null +++ b/apps/user_ldap/l10n/ur.php @@ -0,0 +1,6 @@ +<?php +$TRANSLATIONS = array( +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("","") +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/ur_PK.php b/apps/user_ldap/l10n/ur_PK.php index a84be798f92..9fbd174bd1f 100644 --- a/apps/user_ldap/l10n/ur_PK.php +++ b/apps/user_ldap/l10n/ur_PK.php @@ -1,7 +1,9 @@ <?php $TRANSLATIONS = array( "Error" => "ایرر", -"Password" => "پاسورڈ", -"Help" => "مدد" +"_%s group found_::_%s groups found_" => array("",""), +"_%s user found_::_%s users found_" => array("",""), +"Help" => "مدد", +"Password" => "پاسورڈ" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_ldap/l10n/uz.php b/apps/user_ldap/l10n/uz.php new file mode 100644 index 00000000000..bba52d53a1a --- /dev/null +++ b/apps/user_ldap/l10n/uz.php @@ -0,0 +1,6 @@ +<?php +$TRANSLATIONS = array( +"_%s group found_::_%s groups found_" => array(""), +"_%s user found_::_%s users found_" => array("") +); +$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/user_ldap/l10n/vi.php b/apps/user_ldap/l10n/vi.php index 7ef961df7ad..f1f069cc4d4 100644 --- a/apps/user_ldap/l10n/vi.php +++ b/apps/user_ldap/l10n/vi.php @@ -3,23 +3,23 @@ $TRANSLATIONS = array( "Deletion failed" => "Xóa thất bại", "Success" => "Thành công", "Error" => "Lỗi", +"Select groups" => "Chọn nhóm", +"_%s group found_::_%s groups found_" => array(""), +"_%s user found_::_%s users found_" => array(""), +"Save" => "Lưu", +"Help" => "Giúp đỡ", "Host" => "Máy chủ", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Bạn có thể bỏ qua các giao thức, ngoại trừ SSL. Sau đó bắt đầu với ldaps://", -"Base DN" => "DN cơ bản", -"You can specify Base DN for users and groups in the Advanced tab" => "Bạn có thể chỉ định DN cơ bản cho người dùng và các nhóm trong tab Advanced", +"Port" => "Cổng", "User DN" => "Người dùng DN", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "Các DN của người sử dụng đã được thực hiện, ví dụ như uid =agent , dc = example, dc = com. Để truy cập nặc danh ,DN và mật khẩu trống.", "Password" => "Mật khẩu", "For anonymous access, leave DN and Password empty." => "Cho phép truy cập nặc danh , DN và mật khẩu trống.", -"User Login Filter" => "Lọc người dùng đăng nhập", -"User List Filter" => "Lọc danh sách thành viên", -"Group Filter" => "Bộ lọc nhóm", +"You can specify Base DN for users and groups in the Advanced tab" => "Bạn có thể chỉ định DN cơ bản cho người dùng và các nhóm trong tab Advanced", +"Back" => "Trở lại", "Connection Settings" => "Connection Settings", -"Port" => "Cổng", "Backup (Replica) Port" => "Cổng sao lưu (Replica)", "Disable Main Server" => "Tắt máy chủ chính", -"Use TLS" => "Sử dụng TLS", -"Do not use it additionally for LDAPS connections, it will fail." => "Do not use it additionally for LDAPS connections, it will fail.", "Case insensitve LDAP server (Windows)" => "Trường hợp insensitve LDAP máy chủ (Windows)", "Turn off SSL certificate validation." => "Tắt xác thực chứng nhận SSL", "in seconds. A change empties the cache." => "trong vài giây. Một sự thay đổi bộ nhớ cache.", @@ -34,7 +34,6 @@ $TRANSLATIONS = array( "Group-Member association" => "Nhóm thành viên Cộng đồng", "Special Attributes" => "Special Attributes", "in bytes" => "Theo Byte", -"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "Để trống tên người dùng (mặc định). Nếu không chỉ định thuộc tính LDAP/AD", -"Help" => "Giúp đỡ" +"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "Để trống tên người dùng (mặc định). Nếu không chỉ định thuộc tính LDAP/AD" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/user_ldap/l10n/zh_CN.php b/apps/user_ldap/l10n/zh_CN.php index c30cb421505..f1a3625bf38 100644 --- a/apps/user_ldap/l10n/zh_CN.php +++ b/apps/user_ldap/l10n/zh_CN.php @@ -4,7 +4,6 @@ $TRANSLATIONS = array( "Failed to delete the server configuration" => "未能删除服务器配置", "The configuration is valid and the connection could be established!" => "配置有效,能够建立连接!", "The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "配置有效但绑定失败。请检查服务器设置和认证信息。", -"The configuration is invalid. Please look in the ownCloud log for further details." => "配置无效。更多细节请查看 ownCloud 日志。", "Deletion failed" => "删除失败", "Take over settings from recent server configuration?" => "从近期的服务器配置中导入设置?", "Keep settings?" => "保留设置吗?", @@ -12,35 +11,35 @@ $TRANSLATIONS = array( "mappings cleared" => "清除映射", "Success" => "成功", "Error" => "错误", +"Select groups" => "选择分组", "Connection test succeeded" => "连接测试成功", "Connection test failed" => "连接测试失败", "Do you really want to delete the current Server Configuration?" => "您真的想要删除当前服务器配置吗?", "Confirm Deletion" => "确认删除", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>警告:</b> PHP LDAP 模块未安装,后端将无法工作。请请求您的系统管理员安装该模块。", -"Server configuration" => "服务器配置", +"_%s group found_::_%s groups found_" => array(""), +"_%s user found_::_%s users found_" => array(""), +"Save" => "保存", +"Test Configuration" => "测试配置", +"Help" => "帮助", "Add Server Configuration" => "添加服务器配置", "Host" => "主机", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "可以忽略协议,但如要使用SSL,则需以ldaps://开头", -"Base DN" => "Base DN", -"One Base DN per line" => "每行一个基本判别名", -"You can specify Base DN for users and groups in the Advanced tab" => "您可以在高级选项卡里为用户和组指定Base DN", +"Port" => "端口", "User DN" => "User DN", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "客户端使用的DN必须与绑定的相同,比如uid=agent,dc=example,dc=com\n如需匿名访问,将DN和密码保留为空", "Password" => "密码", "For anonymous access, leave DN and Password empty." => "启用匿名访问,将DN和密码保留为空", -"User Login Filter" => "用户登录过滤", -"User List Filter" => "用户列表过滤", -"Group Filter" => "组过滤", +"One Base DN per line" => "每行一个基本判别名", +"You can specify Base DN for users and groups in the Advanced tab" => "您可以在高级选项卡里为用户和组指定Base DN", +"Back" => "返回", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>警告:</b> PHP LDAP 模块未安装,后端将无法工作。请请求您的系统管理员安装该模块。", "Connection Settings" => "连接设置", "Configuration Active" => "现行配置", "When unchecked, this configuration will be skipped." => "当反选后,此配置将被忽略。", -"Port" => "端口", "Backup (Replica) Host" => "备份 (镜像) 主机", "Give an optional backup host. It must be a replica of the main LDAP/AD server." => "给出一个可选的备份主机。它必须为主 LDAP/AD 服务器的一个镜像。", "Backup (Replica) Port" => "备份 (镜像) 端口", "Disable Main Server" => "禁用主服务器", -"Use TLS" => "使用TLS", -"Do not use it additionally for LDAPS connections, it will fail." => "对于 LDAPS 连接不要额外启用它,连接必然失败。", "Case insensitve LDAP server (Windows)" => "大小写敏感LDAP服务器(Windows)", "Turn off SSL certificate validation." => "关闭SSL证书验证", "Cache Time-To-Live" => "缓存存活时间", @@ -66,11 +65,8 @@ $TRANSLATIONS = array( "Internal Username" => "内部用户名", "Internal Username Attribute:" => "内部用户名属性:", "Override UUID detection" => "超越UUID检测", -"UUID Attribute:" => "UUID属性:", "Username-LDAP User Mapping" => "用户名-LDAP用户映射", "Clear Username-LDAP User Mapping" => "清除用户-LDAP用户映射", -"Clear Groupname-LDAP Group Mapping" => "清除组用户-LDAP级映射", -"Test Configuration" => "测试配置", -"Help" => "帮助" +"Clear Groupname-LDAP Group Mapping" => "清除组用户-LDAP级映射" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/user_ldap/l10n/zh_HK.php b/apps/user_ldap/l10n/zh_HK.php index b656f0fc464..cb504b17463 100644 --- a/apps/user_ldap/l10n/zh_HK.php +++ b/apps/user_ldap/l10n/zh_HK.php @@ -2,8 +2,11 @@ $TRANSLATIONS = array( "Success" => "成功", "Error" => "錯誤", -"Password" => "密碼", +"_%s group found_::_%s groups found_" => array(""), +"_%s user found_::_%s users found_" => array(""), +"Save" => "儲存", +"Help" => "幫助", "Port" => "連接埠", -"Help" => "幫助" +"Password" => "密碼" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/user_ldap/l10n/zh_TW.php b/apps/user_ldap/l10n/zh_TW.php index 2cc1ac99336..a7ae04cd167 100644 --- a/apps/user_ldap/l10n/zh_TW.php +++ b/apps/user_ldap/l10n/zh_TW.php @@ -4,7 +4,6 @@ $TRANSLATIONS = array( "Failed to delete the server configuration" => "刪除伺服器設定時失敗", "The configuration is valid and the connection could be established!" => "設定有效且連線可建立", "The configuration is valid, but the Bind failed. Please check the server settings and credentials." => "設定有效但連線無法建立,請檢查伺服器設定與認證資料。", -"The configuration is invalid. Please look in the ownCloud log for further details." => "設定無效,更多細節請參閱 ownCloud 的記錄檔。", "Deletion failed" => "移除失敗", "Take over settings from recent server configuration?" => "要使用最近一次的伺服器設定嗎?", "Keep settings?" => "維持設定嗎?", @@ -12,35 +11,36 @@ $TRANSLATIONS = array( "mappings cleared" => "映射已清除", "Success" => "成功", "Error" => "錯誤", +"Select groups" => "選擇群組", "Connection test succeeded" => "連線測試成功", "Connection test failed" => "連線測試失敗", "Do you really want to delete the current Server Configuration?" => "您真的要刪除現在的伺服器設定嗎?", "Confirm Deletion" => "確認刪除", -"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>警告:</b>沒有安裝 PHP LDAP 模組,後端系統將無法運作,請要求您的系統管理員安裝模組。", -"Server configuration" => "伺服器設定", +"_%s group found_::_%s groups found_" => array(""), +"_%s user found_::_%s users found_" => array(""), +"Save" => "儲存", +"Test Configuration" => "測試此設定", +"Help" => "說明", "Add Server Configuration" => "新增伺服器設定", "Host" => "主機", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "若您不需要 SSL 加密連線則不需輸入通訊協定,反之請輸入 ldaps://", -"Base DN" => "Base DN", -"One Base DN per line" => "一行一個 Base DN", -"You can specify Base DN for users and groups in the Advanced tab" => "您可以在進階標籤頁裡面指定使用者及群組的 Base DN", +"Port" => "連接埠", "User DN" => "User DN", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "客戶端使用者的DN與特定字詞的連結需要完善,例如:uid=agent,dc=example,dc=com。若是匿名連接,則將DN與密碼欄位留白。", "Password" => "密碼", "For anonymous access, leave DN and Password empty." => "匿名連接時請將 DN 與密碼欄位留白", -"User Login Filter" => "User Login Filter", -"User List Filter" => "User List Filter", -"Group Filter" => "Group Filter", +"One Base DN per line" => "一行一個 Base DN", +"You can specify Base DN for users and groups in the Advanced tab" => "您可以在進階標籤頁裡面指定使用者及群組的 Base DN", +"Back" => "返回", +"Continue" => "繼續", +"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>警告:</b>沒有安裝 PHP LDAP 模組,後端系統將無法運作,請要求您的系統管理員安裝模組。", "Connection Settings" => "連線設定", "Configuration Active" => "設定使用中", "When unchecked, this configuration will be skipped." => "沒有被勾選時,此設定會被略過。", -"Port" => "連接埠", "Backup (Replica) Host" => "備用主機", "Give an optional backup host. It must be a replica of the main LDAP/AD server." => "可以選擇性設定備用主機,必須是 LDAP/AD 中央伺服器的複本。", "Backup (Replica) Port" => "備用(複本)連接埠", "Disable Main Server" => "停用主伺服器", -"Use TLS" => "使用 TLS", -"Do not use it additionally for LDAPS connections, it will fail." => "不要同時與 LDAPS 使用,會有問題。", "Case insensitve LDAP server (Windows)" => "不區分大小寫的 LDAP 伺服器 (Windows)", "Turn off SSL certificate validation." => "關閉 SSL 憑證檢查", "Cache Time-To-Live" => "快取的存活時間", @@ -63,8 +63,6 @@ $TRANSLATIONS = array( "Email Field" => "電郵欄位", "User Home Folder Naming Rule" => "使用者家目錄的命名規則", "Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." => "使用者名稱請留白(預設)。若不留白請指定一個LDAP/AD屬性。", -"Internal Username" => "內部使用者名稱", -"Test Configuration" => "測試此設定", -"Help" => "說明" +"Internal Username" => "內部使用者名稱" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/user_ldap/lib/access.php b/apps/user_ldap/lib/access.php index fdf9c24612d..72f9c740921 100644 --- a/apps/user_ldap/lib/access.php +++ b/apps/user_ldap/lib/access.php @@ -28,6 +28,8 @@ class Access extends LDAPUtility { //never ever check this var directly, always use getPagedSearchResultState protected $pagedSearchedSuccessful; + protected $cookies = array(); + public function __construct(Connection $connection, ILDAPWrapper $ldap) { parent::__construct($ldap); $this->connection = $connection; @@ -60,6 +62,8 @@ class Access extends LDAPUtility { \OCP\Util::writeLog('user_ldap', 'LDAP resource not available.', \OCP\Util::DEBUG); return false; } + //all or nothing! otherwise we get in trouble with. + $this->initPagedSearch($filter, array($dn), $attr, 99999, 0); $dn = $this->DNasBaseParameter($dn); $rr = @$this->ldap->read($cr, $dn, $filter, array($attr)); if(!$this->ldap->isResource($rr)) { @@ -195,7 +199,9 @@ class Access extends LDAPUtility { */ public function username2dn($name) { $dn = $this->ocname2dn($name, true); - if($dn) { + //Check whether the DN belongs to the Base, to avoid issues on multi- + //server setups + if($dn && $this->isDNPartOfBase($dn, $this->connection->ldapBaseUsers)) { return $dn; } @@ -288,7 +294,7 @@ class Access extends LDAPUtility { } //second try: get the UUID and check if it is known. Then, update the DN and return the name. - $uuid = $this->getUUID($dn); + $uuid = $this->getUUID($dn, $isUser); if($uuid) { $query = \OCP\DB::prepare(' SELECT `owncloud_name` @@ -352,7 +358,7 @@ class Access extends LDAPUtility { } //if everything else did not help.. - \OCP\Util::writeLog('user_ldap', 'Could not create unique ownCloud name for '.$dn.'.', \OCP\Util::INFO); + \OCP\Util::writeLog('user_ldap', 'Could not create unique name for '.$dn.'.', \OCP\Util::INFO); return false; } @@ -580,7 +586,9 @@ class Access extends LDAPUtility { '); //feed the DB - $insRows = $insert->execute(array($dn, $ocname, $this->getUUID($dn), $dn, $ocname)); + $insRows = $insert->execute(array($dn, $ocname, + $this->getUUID($dn, $isUser), $dn, + $ocname)); if(\OCP\DB::isError($insRows)) { return false; @@ -626,6 +634,10 @@ class Access extends LDAPUtility { return $this->search($filter, $this->connection->ldapBaseUsers, $attr, $limit, $offset); } + public function countUsers($filter, $attr = array('dn'), $limit = null, $offset = null) { + return $this->count($filter, $this->connection->ldapBaseGroups, $attr, $limit, $offset); + } + /** * @brief executes an LDAP search, optimized for Groups * @param $filter the LDAP filter for the search @@ -639,61 +651,68 @@ class Access extends LDAPUtility { } /** - * @brief executes an LDAP search + * @brief prepares and executes an LDAP search operation * @param $filter the LDAP filter for the search * @param $base an array containing the LDAP subtree(s) that shall be searched * @param $attr optional, array, one or more attributes that shall be * retrieved. Results will according to the order in the array. - * @returns array with the search result - * - * Executes an LDAP search + * @param $limit optional, maximum results to be counted + * @param $offset optional, a starting point + * @returns array with the search result as first value and pagedSearchOK as + * second | false if not successful */ - private function search($filter, $base, $attr = null, $limit = null, $offset = null, $skipHandling = false) { + private function executeSearch($filter, $base, &$attr = null, $limit = null, $offset = null) { if(!is_null($attr) && !is_array($attr)) { $attr = array(mb_strtolower($attr, 'UTF-8')); } // See if we have a resource, in case not cancel with message - $link_resource = $this->connection->getConnectionResource(); - if(!$this->ldap->isResource($link_resource)) { + $cr = $this->connection->getConnectionResource(); + if(!$this->ldap->isResource($cr)) { // Seems like we didn't find any resource. // Return an empty array just like before. \OCP\Util::writeLog('user_ldap', 'Could not search, because resource is missing.', \OCP\Util::DEBUG); - return array(); + return false; } //check wether paged search should be attempted $pagedSearchOK = $this->initPagedSearch($filter, $base, $attr, $limit, $offset); - $linkResources = array_pad(array(), count($base), $link_resource); + $linkResources = array_pad(array(), count($base), $cr); $sr = $this->ldap->search($linkResources, $base, $filter, $attr); - $error = $this->ldap->errno($link_resource); + $error = $this->ldap->errno($cr); if(!is_array($sr) || $error !== 0) { \OCP\Util::writeLog('user_ldap', - 'Error when searching: '.$this->ldap->error($link_resource). - ' code '.$this->ldap->errno($link_resource), + 'Error when searching: '.$this->ldap->error($cr). + ' code '.$this->ldap->errno($cr), \OCP\Util::ERROR); \OCP\Util::writeLog('user_ldap', 'Attempt for Paging? '.print_r($pagedSearchOK, true), \OCP\Util::ERROR); - return array(); + return false; } - // Do the server-side sorting - foreach(array_reverse($attr) as $sortAttr){ - foreach($sr as $searchResource) { - $this->ldap->sort($link_resource, $searchResource, $sortAttr); - } - } + return array($sr, $pagedSearchOK); + } - $findings = array(); - foreach($sr as $key => $res) { - $findings = array_merge($findings, $this->ldap->getEntries($link_resource, $res )); - } + /** + * @brief processes an LDAP paged search operation + * @param $sr the array containing the LDAP search resources + * @param $filter the LDAP filter for the search + * @param $base an array containing the LDAP subtree(s) that shall be searched + * @param $iFoundItems number of results in the search operation + * @param $limit maximum results to be counted + * @param $offset a starting point + * @param $pagedSearchOK whether a paged search has been executed + * @param $skipHandling required for paged search when cookies to + * prior results need to be gained + * @returns array with the search result as first value and pagedSearchOK as + * second | false if not successful + */ + private function processPagedSearchStatus($sr, $filter, $base, $iFoundItems, $limit, $offset, $pagedSearchOK, $skipHandling) { if($pagedSearchOK) { - \OCP\Util::writeLog('user_ldap', 'Paged search successful', \OCP\Util::INFO); + $cr = $this->connection->getConnectionResource(); foreach($sr as $key => $res) { $cookie = null; - if($this->ldap->controlPagedResultResponse($link_resource, $res, $cookie)) { - \OCP\Util::writeLog('user_ldap', 'Set paged search cookie', \OCP\Util::INFO); + if($this->ldap->controlPagedResultResponse($cr, $res, $cookie)) { $this->setPagedResultCookie($base[$key], $filter, $limit, $offset, $cookie); } } @@ -705,7 +724,7 @@ class Access extends LDAPUtility { // if count is bigger, then the server does not support // paged search. Instead, he did a normal search. We set a // flag here, so the callee knows how to deal with it. - if($findings['count'] <= $limit) { + if($iFoundItems <= $limit) { $this->pagedSearchedSuccessful = true; } } else { @@ -713,6 +732,86 @@ class Access extends LDAPUtility { \OCP\Util::writeLog('user_ldap', 'Paged search failed :(', \OCP\Util::INFO); } } + } + + /** + * @brief executes an LDAP search, but counts the results only + * @param $filter the LDAP filter for the search + * @param $base an array containing the LDAP subtree(s) that shall be searched + * @param $attr optional, array, one or more attributes that shall be + * retrieved. Results will according to the order in the array. + * @param $limit optional, maximum results to be counted + * @param $offset optional, a starting point + * @param $skipHandling indicates whether the pages search operation is + * completed + * @returns int | false if the search could not be initialized + * + */ + private function count($filter, $base, $attr = null, $limit = null, $offset = null, $skipHandling = false) { + \OCP\Util::writeLog('user_ldap', 'Count filter: '.print_r($filter, true), \OCP\Util::DEBUG); + $search = $this->executeSearch($filter, $base, $attr, $limit, $offset); + if($search === false) { + return false; + } + list($sr, $pagedSearchOK) = $search; + $cr = $this->connection->getConnectionResource(); + $counter = 0; + foreach($sr as $key => $res) { + $count = $this->ldap->countEntries($cr, $res); + if($count !== false) { + $counter += $count; + } + } + + $this->processPagedSearchStatus($sr, $filter, $base, $counter, $limit, + $offset, $pagedSearchOK, $skipHandling); + + return $counter; + } + + /** + * @brief executes an LDAP search + * @param $filter the LDAP filter for the search + * @param $base an array containing the LDAP subtree(s) that shall be searched + * @param $attr optional, array, one or more attributes that shall be + * retrieved. Results will according to the order in the array. + * @returns array with the search result + * + * Executes an LDAP search + */ + private function search($filter, $base, $attr = null, $limit = null, $offset = null, $skipHandling = false) { + $search = $this->executeSearch($filter, $base, $attr, $limit, $offset); + if($search === false) { + return array(); + } + list($sr, $pagedSearchOK) = $search; + $cr = $this->connection->getConnectionResource(); + + if($skipHandling) { + //i.e. result do not need to be fetched, we just need the cookie + //thus pass 1 or any other value as $iFoundItems because it is not + //used + $this->processPagedSearchStatus($sr, $filter, $base, 1, $limit, + $offset, $pagedSearchOK, + $skipHandling); + return; + } + + // Do the server-side sorting + foreach(array_reverse($attr) as $sortAttr){ + foreach($sr as $searchResource) { + $this->ldap->sort($cr, $searchResource, $sortAttr); + } + } + + $findings = array(); + foreach($sr as $key => $res) { + $findings = array_merge($findings, $this->ldap->getEntries($cr , $res )); + } + + $this->processPagedSearchStatus($sr, $filter, $base, $findings['count'], + $limit, $offset, $pagedSearchOK, + $skipHandling); // if we're here, probably no connection resource is returned. // to make ownCloud behave nicely, we simply give back an empty array. @@ -829,7 +928,7 @@ class Access extends LDAPUtility { private function combineFilter($filters, $operator) { $combinedFilter = '('.$operator; foreach($filters as $filter) { - if($filter[0] !== '(') { + if(!empty($filter) && $filter[0] !== '(') { $filter = '('.$filter.')'; } $combinedFilter.=$filter; @@ -896,7 +995,9 @@ class Access extends LDAPUtility { if(!$testConnection->setConfiguration($credentials)) { return false; } - return $testConnection->bind(); + $result=$testConnection->bind(); + $this->connection->bind(); + return $result; } /** @@ -905,55 +1006,67 @@ class Access extends LDAPUtility { * @param $force the detection should be run, even if it is not set to auto * @returns true on success, false otherwise */ - private function detectUuidAttribute($dn, $force = false) { - if(($this->connection->ldapUuidAttribute !== 'auto') && !$force) { + private function detectUuidAttribute($dn, $isUser = true, $force = false) { + if($isUser) { + $uuidAttr = 'ldapUuidUserAttribute'; + $uuidOverride = $this->connection->ldapExpertUUIDUserAttr; + } else { + $uuidAttr = 'ldapUuidGroupAttribute'; + $uuidOverride = $this->connection->ldapExpertUUIDGroupAttr; + } + + if(($this->connection->$uuidAttr !== 'auto') && !$force) { return true; } - $fixedAttribute = $this->connection->ldapExpertUUIDAttr; - if(!empty($fixedAttribute)) { - $this->connection->ldapUuidAttribute = $fixedAttribute; + if(!empty($uuidOverride) && !$force) { + $this->connection->$uuidAttr = $uuidOverride; return true; } - //for now, supported (known) attributes are entryUUID, nsuniqueid, objectGUID + //for now, supported attributes are entryUUID, nsuniqueid, objectGUID $testAttributes = array('entryuuid', 'nsuniqueid', 'objectguid', 'guid'); foreach($testAttributes as $attribute) { - \OCP\Util::writeLog('user_ldap', 'Testing '.$attribute.' as UUID attr', \OCP\Util::DEBUG); - $value = $this->readAttribute($dn, $attribute); if(is_array($value) && isset($value[0]) && !empty($value[0])) { - \OCP\Util::writeLog('user_ldap', 'Setting '.$attribute.' as UUID attr', \OCP\Util::DEBUG); - $this->connection->ldapUuidAttribute = $attribute; + \OCP\Util::writeLog('user_ldap', + 'Setting '.$attribute.' as '.$uuidAttr, + \OCP\Util::DEBUG); + $this->connection->$uuidAttr = $attribute; return true; } - \OCP\Util::writeLog('user_ldap', - 'The looked for uuid attr is not '.$attribute.', result was '.print_r($value, true), - \OCP\Util::DEBUG); } + \OCP\Util::writeLog('user_ldap', + 'Could not autodetect the UUID attribute', + \OCP\Util::ERROR); return false; } - public function getUUID($dn) { - if($this->detectUuidAttribute($dn)) { - \OCP\Util::writeLog('user_ldap', - 'UUID Checking \ UUID for '.$dn.' using '. $this->connection->ldapUuidAttribute, - \OCP\Util::DEBUG); - $uuid = $this->readAttribute($dn, $this->connection->ldapUuidAttribute); - if(!is_array($uuid) && $this->connection->ldapOverrideUuidAttribute) { - $this->detectUuidAttribute($dn, true); - $uuid = $this->readAttribute($dn, $this->connection->ldapUuidAttribute); + public function getUUID($dn, $isUser = true) { + if($isUser) { + $uuidAttr = 'ldapUuidUserAttribute'; + $uuidOverride = $this->connection->ldapExpertUUIDUserAttr; + } else { + $uuidAttr = 'ldapUuidGroupAttribute'; + $uuidOverride = $this->connection->ldapExpertUUIDGroupAttr; + } + + $uuid = false; + if($this->detectUuidAttribute($dn, $isUser)) { + $uuid = $this->readAttribute($dn, $this->connection->$uuidAttr); + if( !is_array($uuid) + && !empty($uuidOverride) + && $this->detectUuidAttribute($dn, $isUser, true)) { + $uuid = $this->readAttribute($dn, + $this->connection->$uuidAttr); } if(is_array($uuid) && isset($uuid[0]) && !empty($uuid[0])) { $uuid = $uuid[0]; - } else { - $uuid = false; } - } else { - $uuid = false; } + return $uuid; } @@ -1007,7 +1120,7 @@ class Access extends LDAPUtility { $bases = $this->sanitizeDN($bases); foreach($bases as $base) { $belongsToBase = true; - if(mb_strripos($dn, $base, 0, 'UTF-8') !== (mb_strlen($dn, 'UTF-8')-mb_strlen($base))) { + if(mb_strripos($dn, $base, 0, 'UTF-8') !== (mb_strlen($dn, 'UTF-8')-mb_strlen($base, 'UTF-8'))) { $belongsToBase = false; } if($belongsToBase) { @@ -1032,9 +1145,12 @@ class Access extends LDAPUtility { $offset -= $limit; //we work with cache here $cachekey = 'lc' . crc32($base) . '-' . crc32($filter) . '-' . $limit . '-' . $offset; - $cookie = $this->connection->getFromCache($cachekey); - if(is_null($cookie)) { - $cookie = ''; + $cookie = ''; + if(isset($this->cookies[$cachekey])) { + $cookie = $this->cookies[$cachekey]; + if(is_null($cookie)) { + $cookie = ''; + } } return $cookie; } @@ -1051,7 +1167,7 @@ class Access extends LDAPUtility { private function setPagedResultCookie($base, $filter, $limit, $offset, $cookie) { if(!empty($cookie)) { $cachekey = 'lc' . crc32($base) . '-' . crc32($filter) . '-' .$limit . '-' . $offset; - $cookie = $this->connection->writeToCache($cachekey, $cookie); + $this->cookies[$cachekey] = $cookie; } } diff --git a/apps/user_ldap/lib/configuration.php b/apps/user_ldap/lib/configuration.php new file mode 100644 index 00000000000..93f044e3152 --- /dev/null +++ b/apps/user_ldap/lib/configuration.php @@ -0,0 +1,397 @@ +<?php + +/** + * ownCloud – LDAP Connection + * + * @author Arthur Schiwon + * @copyright 2012, 2013 Arthur Schiwon blizzz@owncloud.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library 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 along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCA\user_ldap\lib; + +class Configuration { + + protected $configPrefix = null; + protected $configRead = false; + + //settings + protected $config = array( + 'ldapHost' => null, + 'ldapPort' => null, + 'ldapBackupHost' => null, + 'ldapBackupPort' => null, + 'ldapBase' => null, + 'ldapBaseUsers' => null, + 'ldapBaseGroups' => null, + 'ldapAgentName' => null, + 'ldapAgentPassword' => null, + 'ldapTLS' => null, + 'ldapNoCase' => null, + 'turnOffCertCheck' => null, + 'ldapIgnoreNamingRules' => null, + 'ldapUserDisplayName' => null, + 'ldapUserFilterObjectclass' => null, + 'ldapUserFilterGroups' => null, + 'ldapUserFilter' => null, + 'ldapUserFilterMode' => null, + 'ldapGroupFilter' => null, + 'ldapGroupFilterMode' => null, + 'ldapGroupFilterObjectclass' => null, + 'ldapGroupFilterGroups' => null, + 'ldapGroupDisplayName' => null, + 'ldapGroupMemberAssocAttr' => null, + 'ldapLoginFilter' => null, + 'ldapLoginFilterMode' => null, + 'ldapLoginFilterEmail' => null, + 'ldapLoginFilterUsername' => null, + 'ldapLoginFilterAttributes' => null, + 'ldapQuotaAttribute' => null, + 'ldapQuotaDefault' => null, + 'ldapEmailAttribute' => null, + 'ldapCacheTTL' => null, + 'ldapUuidUserAttribute' => 'auto', + 'ldapUuidGroupAttribute' => 'auto', + 'ldapOverrideMainServer' => false, + 'ldapConfigurationActive' => false, + 'ldapAttributesForUserSearch' => null, + 'ldapAttributesForGroupSearch' => null, + 'homeFolderNamingRule' => null, + 'hasPagedResultSupport' => false, + 'hasMemberOfFilterSupport' => false, + 'ldapExpertUsernameAttr' => null, + 'ldapExpertUUIDUserAttr' => null, + 'ldapExpertUUIDGroupAttr' => null, + 'lastJpegPhotoLookup' => null, + ); + + public function __construct($configPrefix, $autoread = true) { + $this->configPrefix = $configPrefix; + if($autoread) { + $this->readConfiguration(); + } + } + + public function __get($name) { + if(isset($this->config[$name])) { + return $this->config[$name]; + } + } + + public function __set($name, $value) { + $this->setConfiguration(array($name => $value)); + } + + public function getConfiguration() { + return $this->config; + } + + /** + * @brief set LDAP configuration with values delivered by an array, not read + * from configuration. It does not save the configuration! To do so, you + * must call saveConfiguration afterwards. + * @param $config array that holds the config parameters in an associated + * array + * @param &$applied optional; array where the set fields will be given to + * @return null + */ + public function setConfiguration($config, &$applied = null) { + if(!is_array($config)) { + return false; + } + + $cta = $this->getConfigTranslationArray(); + foreach($config as $inputkey => $val) { + if(strpos($inputkey, '_') !== false && isset($cta[$inputkey])) { + $key = $cta[$inputkey]; + } elseif(isset($this->config[$inputkey])) { + $key = $inputkey; + } else { + continue; + } + + $setMethod = 'setValue'; + switch($key) { + case 'homeFolderNamingRule': + if(!empty($val) && strpos($val, 'attr:') === false) { + $val = 'attr:'.$val; + } + break; + case 'ldapBase': + case 'ldapBaseUsers': + case 'ldapBaseGroups': + case 'ldapAttributesForUserSearch': + case 'ldapAttributesForGroupSearch': + case 'ldapUserFilterObjectclass': + case 'ldapUserFilterGroups': + case 'ldapGroupFilterObjectclass': + case 'ldapGroupFilterGroups': + case 'ldapLoginFilterAttributes': + $setMethod = 'setMultiLine'; + break; + } + $this->$setMethod($key, $val); + if(is_array($applied)) { + $applied[] = $inputkey; + } + } + + } + + public function readConfiguration() { + if(!$this->configRead && !is_null($this->configPrefix)) { + $cta = array_flip($this->getConfigTranslationArray()); + foreach($this->config as $key => $val) { + if(!isset($cta[$key])) { + //some are determined + continue; + } + $dbkey = $cta[$key]; + switch($key) { + case 'ldapBase': + case 'ldapBaseUsers': + case 'ldapBaseGroups': + case 'ldapAttributesForUserSearch': + case 'ldapAttributesForGroupSearch': + case 'ldapUserFilterObjectclass': + case 'ldapUserFilterGroups': + case 'ldapGroupFilterObjectclass': + case 'ldapGroupFilterGroups': + case 'ldapLoginFilterAttributes': + $readMethod = 'getMultiLine'; + break; + case 'ldapIgnoreNamingRules': + $readMethod = 'getSystemValue'; + $dbkey = $key; + break; + case 'ldapAgentPassword': + $readMethod = 'getPwd'; + break; + case 'ldapUserDisplayName': + case 'ldapGroupDisplayName': + $readMethod = 'getLcValue'; + break; + default: + $readMethod = 'getValue'; + break; + } + $this->config[$key] = $this->$readMethod($dbkey); + } + $this->configRead = true; + } + } + + /** + * @brief saves the current Configuration in the database + */ + public function saveConfiguration() { + $cta = array_flip($this->getConfigTranslationArray()); + foreach($this->config as $key => $value) { + switch ($key) { + case 'ldapAgentPassword': + $value = base64_encode($value); + break; + case 'ldapBase': + case 'ldapBaseUsers': + case 'ldapBaseGroups': + case 'ldapAttributesForUserSearch': + case 'ldapAttributesForGroupSearch': + case 'ldapUserFilterObjectclass': + case 'ldapUserFilterGroups': + case 'ldapGroupFilterObjectclass': + case 'ldapGroupFilterGroups': + case 'ldapLoginFilterAttributes': + if(is_array($value)) { + $value = implode("\n", $value); + } + break; + //following options are not stored but detected, skip them + case 'ldapIgnoreNamingRules': + case 'hasPagedResultSupport': + case 'ldapUuidUserAttribute': + case 'ldapUuidGroupAttribute': + continue 2; + } + if(is_null($value)) { + $value = ''; + } + $this->saveValue($cta[$key], $value); + } + } + + protected function getMultiLine($varname) { + $value = $this->getValue($varname); + if(empty($value)) { + $value = ''; + } else { + $value = preg_split('/\r\n|\r|\n/', $value); + } + + return $value; + } + + protected function setMultiLine($varname, $value) { + if(empty($value)) { + $value = ''; + } else if (!is_array($value)) { + $value = preg_split('/\r\n|\r|\n/', $value); + if($value === false) { + $value = ''; + } + } + + $this->setValue($varname, $value); + } + + protected function getPwd($varname) { + return base64_decode($this->getValue($varname)); + } + + protected function getLcValue($varname) { + return mb_strtolower($this->getValue($varname), 'UTF-8'); + } + + protected function getSystemValue($varname) { + //FIXME: if another system value is added, softcode the default value + return \OCP\Config::getSystemValue($varname, false); + } + + protected function getValue($varname) { + static $defaults; + if(is_null($defaults)) { + $defaults = $this->getDefaults(); + } + return \OCP\Config::getAppValue('user_ldap', + $this->configPrefix.$varname, + $defaults[$varname]); + } + + protected function setValue($varname, $value) { + $this->config[$varname] = $value; + } + + protected function saveValue($varname, $value) { + return \OCP\Config::setAppValue('user_ldap', + $this->configPrefix.$varname, + $value); + } + + /** + * @returns an associative array with the default values. Keys are correspond + * to config-value entries in the database table + */ + public function getDefaults() { + return array( + 'ldap_host' => '', + 'ldap_port' => '', + 'ldap_backup_host' => '', + 'ldap_backup_port' => '', + 'ldap_override_main_server' => '', + 'ldap_dn' => '', + 'ldap_agent_password' => '', + 'ldap_base' => '', + 'ldap_base_users' => '', + 'ldap_base_groups' => '', + 'ldap_userlist_filter' => '', + 'ldap_user_filter_mode' => 0, + 'ldap_userfilter_objectclass' => '', + 'ldap_userfilter_groups' => '', + 'ldap_login_filter' => '', + 'ldap_login_filter_mode' => 0, + 'ldap_loginfilter_email' => 0, + 'ldap_loginfilter_username' => 1, + 'ldap_loginfilter_attributes' => '', + 'ldap_group_filter' => '', + 'ldap_group_filter_mode' => 0, + 'ldap_groupfilter_objectclass' => '', + 'ldap_groupfilter_groups' => '', + 'ldap_display_name' => 'displayName', + 'ldap_group_display_name' => 'cn', + 'ldap_tls' => 1, + 'ldap_nocase' => 0, + 'ldap_quota_def' => '', + 'ldap_quota_attr' => '', + 'ldap_email_attr' => '', + 'ldap_group_member_assoc_attribute' => 'uniqueMember', + 'ldap_cache_ttl' => 600, + 'ldap_uuid_user_attribute' => 'auto', + 'ldap_uuid_group_attribute' => 'auto', + 'home_folder_naming_rule' => '', + 'ldap_turn_off_cert_check' => 0, + 'ldap_configuration_active' => 0, + 'ldap_attributes_for_user_search' => '', + 'ldap_attributes_for_group_search' => '', + 'ldap_expert_username_attr' => '', + 'ldap_expert_uuid_user_attr' => '', + 'ldap_expert_uuid_group_attr' => '', + 'has_memberof_filter_support' => 0, + 'last_jpegPhoto_lookup' => 0, + ); + } + + /** + * @return returns an array that maps internal variable names to database fields + */ + public function getConfigTranslationArray() { + //TODO: merge them into one representation + static $array = array( + 'ldap_host' => 'ldapHost', + 'ldap_port' => 'ldapPort', + 'ldap_backup_host' => 'ldapBackupHost', + 'ldap_backup_port' => 'ldapBackupPort', + 'ldap_override_main_server' => 'ldapOverrideMainServer', + 'ldap_dn' => 'ldapAgentName', + 'ldap_agent_password' => 'ldapAgentPassword', + 'ldap_base' => 'ldapBase', + 'ldap_base_users' => 'ldapBaseUsers', + 'ldap_base_groups' => 'ldapBaseGroups', + 'ldap_userfilter_objectclass' => 'ldapUserFilterObjectclass', + 'ldap_userfilter_groups' => 'ldapUserFilterGroups', + 'ldap_userlist_filter' => 'ldapUserFilter', + 'ldap_user_filter_mode' => 'ldapUserFilterMode', + 'ldap_login_filter' => 'ldapLoginFilter', + 'ldap_login_filter_mode' => 'ldapLoginFilterMode', + 'ldap_loginfilter_email' => 'ldapLoginFilterEmail', + 'ldap_loginfilter_username' => 'ldapLoginFilterUsername', + 'ldap_loginfilter_attributes' => 'ldapLoginFilterAttributes', + 'ldap_group_filter' => 'ldapGroupFilter', + 'ldap_group_filter_mode' => 'ldapGroupFilterMode', + 'ldap_groupfilter_objectclass' => 'ldapGroupFilterObjectclass', + 'ldap_groupfilter_groups' => 'ldapGroupFilterGroups', + 'ldap_display_name' => 'ldapUserDisplayName', + 'ldap_group_display_name' => 'ldapGroupDisplayName', + 'ldap_tls' => 'ldapTLS', + 'ldap_nocase' => 'ldapNoCase', + 'ldap_quota_def' => 'ldapQuotaDefault', + 'ldap_quota_attr' => 'ldapQuotaAttribute', + 'ldap_email_attr' => 'ldapEmailAttribute', + 'ldap_group_member_assoc_attribute' => 'ldapGroupMemberAssocAttr', + 'ldap_cache_ttl' => 'ldapCacheTTL', + 'home_folder_naming_rule' => 'homeFolderNamingRule', + 'ldap_turn_off_cert_check' => 'turnOffCertCheck', + 'ldap_configuration_active' => 'ldapConfigurationActive', + 'ldap_attributes_for_user_search' => 'ldapAttributesForUserSearch', + 'ldap_attributes_for_group_search' => 'ldapAttributesForGroupSearch', + 'ldap_expert_username_attr' => 'ldapExpertUsernameAttr', + 'ldap_expert_uuid_user_attr' => 'ldapExpertUUIDUserAttr', + 'ldap_expert_uuid_group_attr' => 'ldapExpertUUIDGroupAttr', + 'has_memberof_filter_support' => 'hasMemberOfFilterSupport', + 'last_jpegPhoto_lookup' => 'lastJpegPhotoLookup', + ); + return $array; + } + +}
\ No newline at end of file diff --git a/apps/user_ldap/lib/connection.php b/apps/user_ldap/lib/connection.php index a53022c27b3..c4e4efd0483 100644 --- a/apps/user_ldap/lib/connection.php +++ b/apps/user_ldap/lib/connection.php @@ -1,7 +1,7 @@ <?php /** - * ownCloud – LDAP Access + * ownCloud – LDAP Connection * * @author Arthur Schiwon * @copyright 2012, 2013 Arthur Schiwon blizzz@owncloud.com @@ -31,46 +31,15 @@ class Connection extends LDAPUtility { //whether connection should be kept on __destruct private $dontDestruct = false; + private $hasPagedResultSupport = true; //cache handler protected $cache; - //settings - protected $config = array( - 'ldapHost' => null, - 'ldapPort' => null, - 'ldapBackupHost' => null, - 'ldapBackupPort' => null, - 'ldapBase' => null, - 'ldapBaseUsers' => null, - 'ldapBaseGroups' => null, - 'ldapAgentName' => null, - 'ldapAgentPassword' => null, - 'ldapTLS' => null, - 'ldapNoCase' => null, - 'turnOffCertCheck' => null, - 'ldapIgnoreNamingRules' => null, - 'ldapUserDisplayName' => null, - 'ldapUserFilter' => null, - 'ldapGroupFilter' => null, - 'ldapGroupDisplayName' => null, - 'ldapGroupMemberAssocAttr' => null, - 'ldapLoginFilter' => null, - 'ldapQuotaAttribute' => null, - 'ldapQuotaDefault' => null, - 'ldapEmailAttribute' => null, - 'ldapCacheTTL' => null, - 'ldapUuidAttribute' => 'auto', - 'ldapOverrideUuidAttribute' => null, - 'ldapOverrideMainServer' => false, - 'ldapConfigurationActive' => false, - 'ldapAttributesForUserSearch' => null, - 'ldapAttributesForGroupSearch' => null, - 'homeFolderNamingRule' => null, - 'hasPagedResultSupport' => false, - 'ldapExpertUsernameAttr' => null, - 'ldapExpertUUIDAttr' => null, - ); + //settings handler + protected $configuration; + + protected $doNotValidate = false; /** * @brief Constructor @@ -81,14 +50,18 @@ class Connection extends LDAPUtility { parent::__construct($ldap); $this->configPrefix = $configPrefix; $this->configID = $configID; + $this->configuration = new Configuration($configPrefix, + !is_null($configID)); $memcache = new \OC\Memcache\Factory(); if($memcache->isAvailable()) { $this->cache = $memcache->create(); } else { $this->cache = \OC_Cache::getGlobalCache(); } - $this->config['hasPagedResultSupport'] = + $this->hasPagedResultSupport = $this->ldap->hasPagedResultSupport(); + $this->doNotValidate = !in_array($this->configPrefix, + Helper::getServerConfigurationPrefixes()); } public function __destruct() { @@ -112,23 +85,22 @@ class Connection extends LDAPUtility { $this->readConfiguration(); } - if(isset($this->config[$name])) { - return $this->config[$name]; + if($name === 'hasPagedResultSupport') { + return $this->hasPagedResultSupport; } + + return $this->configuration->$name; } public function __set($name, $value) { - $changed = false; - //only few options are writable - if($name === 'ldapUuidAttribute') { - \OCP\Util::writeLog('user_ldap', 'Set config ldapUuidAttribute to '.$value, \OCP\Util::DEBUG); - $this->config[$name] = $value; + $this->doNotValidate = false; + $before = $this->configuration->$name; + $this->configuration->$name = $value; + $after = $this->configuration->$name; + if($before !== $after) { if(!empty($this->configID)) { - \OCP\Config::setAppValue($this->configID, $this->configPrefix.'ldap_uuid_attribute', $value); + $this->configuration->saveConfiguration(); } - $changed = true; - } - if($changed) { $this->validateConfiguration(); } } @@ -172,7 +144,7 @@ class Connection extends LDAPUtility { if(!$this->configured) { $this->readConfiguration(); } - if(!$this->config['ldapCacheTTL']) { + if(!$this->configuration->ldapCacheTTL) { return null; } if(!$this->isCached($key)) { @@ -188,7 +160,7 @@ class Connection extends LDAPUtility { if(!$this->configured) { $this->readConfiguration(); } - if(!$this->config['ldapCacheTTL']) { + if(!$this->configuration->ldapCacheTTL) { return false; } $key = $this->getCacheKey($key); @@ -199,230 +171,59 @@ class Connection extends LDAPUtility { if(!$this->configured) { $this->readConfiguration(); } - if(!$this->config['ldapCacheTTL'] - || !$this->config['ldapConfigurationActive']) { + if(!$this->configuration->ldapCacheTTL + || !$this->configuration->ldapConfigurationActive) { return null; } $key = $this->getCacheKey($key); $value = base64_encode(serialize($value)); - $this->cache->set($key, $value, $this->config['ldapCacheTTL']); + $this->cache->set($key, $value, $this->configuration->ldapCacheTTL); } public function clearCache() { $this->cache->clear($this->getCacheKey(null)); } - private function getValue($varname) { - static $defaults; - if(is_null($defaults)) { - $defaults = $this->getDefaults(); - } - return \OCP\Config::getAppValue($this->configID, - $this->configPrefix.$varname, - $defaults[$varname]); - } - - private function setValue($varname, $value) { - \OCP\Config::setAppValue($this->configID, - $this->configPrefix.$varname, - $value); - } - /** - * Special handling for reading Base Configuration - * - * @param $base the internal name of the config key - * @param $value the value stored for the base - */ - private function readBase($base, $value) { - if(empty($value)) { - $value = ''; - } else { - $value = preg_split('/\r\n|\r|\n/', $value); - } - - $this->config[$base] = $value; - } - - /** - * Caches the general LDAP configuration. + * @brief Caches the general LDAP configuration. + * @param $force optional. true, if the re-read should be forced. defaults + * to false. + * @return null */ private function readConfiguration($force = false) { if((!$this->configured || $force) && !is_null($this->configID)) { - $v = 'getValue'; - $this->config['ldapHost'] = $this->$v('ldap_host'); - $this->config['ldapBackupHost'] = $this->$v('ldap_backup_host'); - $this->config['ldapPort'] = $this->$v('ldap_port'); - $this->config['ldapBackupPort'] = $this->$v('ldap_backup_port'); - $this->config['ldapOverrideMainServer'] - = $this->$v('ldap_override_main_server'); - $this->config['ldapAgentName'] = $this->$v('ldap_dn'); - $this->config['ldapAgentPassword'] - = base64_decode($this->$v('ldap_agent_password')); - $this->readBase('ldapBase', $this->$v('ldap_base')); - $this->readBase('ldapBaseUsers', $this->$v('ldap_base_users')); - $this->readBase('ldapBaseGroups', $this->$v('ldap_base_groups')); - $this->config['ldapTLS'] = $this->$v('ldap_tls'); - $this->config['ldapNoCase'] = $this->$v('ldap_nocase'); - $this->config['turnOffCertCheck'] - = $this->$v('ldap_turn_off_cert_check'); - $this->config['ldapUserDisplayName'] - = mb_strtolower($this->$v('ldap_display_name'), 'UTF-8'); - $this->config['ldapUserFilter'] - = $this->$v('ldap_userlist_filter'); - $this->config['ldapGroupFilter'] = $this->$v('ldap_group_filter'); - $this->config['ldapLoginFilter'] = $this->$v('ldap_login_filter'); - $this->config['ldapGroupDisplayName'] - = mb_strtolower($this->$v('ldap_group_display_name'), 'UTF-8'); - $this->config['ldapQuotaAttribute'] - = $this->$v('ldap_quota_attr'); - $this->config['ldapQuotaDefault'] - = $this->$v('ldap_quota_def'); - $this->config['ldapEmailAttribute'] - = $this->$v('ldap_email_attr'); - $this->config['ldapGroupMemberAssocAttr'] - = $this->$v('ldap_group_member_assoc_attribute'); - $this->config['ldapIgnoreNamingRules'] - = \OCP\Config::getSystemValue('ldapIgnoreNamingRules', false); - $this->config['ldapCacheTTL'] = $this->$v('ldap_cache_ttl'); - $this->config['ldapUuidAttribute'] - = $this->$v('ldap_uuid_attribute'); - $this->config['ldapOverrideUuidAttribute'] - = $this->$v('ldap_override_uuid_attribute'); - $this->config['homeFolderNamingRule'] - = $this->$v('home_folder_naming_rule'); - $this->config['ldapConfigurationActive'] - = $this->$v('ldap_configuration_active'); - $this->config['ldapAttributesForUserSearch'] - = preg_split('/\r\n|\r|\n/', $this->$v('ldap_attributes_for_user_search')); - $this->config['ldapAttributesForGroupSearch'] - = preg_split('/\r\n|\r|\n/', $this->$v('ldap_attributes_for_group_search')); - $this->config['ldapExpertUsernameAttr'] - = $this->$v('ldap_expert_username_attr'); - $this->config['ldapExpertUUIDAttr'] - = $this->$v('ldap_expert_uuid_attr'); - + $this->configuration->readConfiguration(); $this->configured = $this->validateConfiguration(); } } /** - * @return returns an array that maps internal variable names to database fields - */ - private function getConfigTranslationArray() { - static $array = array( - 'ldap_host'=>'ldapHost', - 'ldap_port'=>'ldapPort', - 'ldap_backup_host'=>'ldapBackupHost', - 'ldap_backup_port'=>'ldapBackupPort', - 'ldap_override_main_server' => 'ldapOverrideMainServer', - 'ldap_dn'=>'ldapAgentName', - 'ldap_agent_password'=>'ldapAgentPassword', - 'ldap_base'=>'ldapBase', - 'ldap_base_users'=>'ldapBaseUsers', - 'ldap_base_groups'=>'ldapBaseGroups', - 'ldap_userlist_filter'=>'ldapUserFilter', - 'ldap_login_filter'=>'ldapLoginFilter', - 'ldap_group_filter'=>'ldapGroupFilter', - 'ldap_display_name'=>'ldapUserDisplayName', - 'ldap_group_display_name'=>'ldapGroupDisplayName', - 'ldap_tls'=>'ldapTLS', - 'ldap_nocase'=>'ldapNoCase', - 'ldap_quota_def'=>'ldapQuotaDefault', - 'ldap_quota_attr'=>'ldapQuotaAttribute', - 'ldap_email_attr'=>'ldapEmailAttribute', - 'ldap_group_member_assoc_attribute'=>'ldapGroupMemberAssocAttr', - 'ldap_cache_ttl'=>'ldapCacheTTL', - 'home_folder_naming_rule' => 'homeFolderNamingRule', - 'ldap_turn_off_cert_check' => 'turnOffCertCheck', - 'ldap_configuration_active' => 'ldapConfigurationActive', - 'ldap_attributes_for_user_search' => 'ldapAttributesForUserSearch', - 'ldap_attributes_for_group_search' => 'ldapAttributesForGroupSearch', - 'ldap_expert_username_attr' => 'ldapExpertUsernameAttr', - 'ldap_expert_uuid_attr' => 'ldapExpertUUIDAttr', - ); - return $array; - } - - /** * @brief set LDAP configuration with values delivered by an array, not read from configuration * @param $config array that holds the config parameters in an associated array * @param &$setParameters optional; array where the set fields will be given to * @return true if config validates, false otherwise. Check with $setParameters for detailed success on single parameters */ public function setConfiguration($config, &$setParameters = null) { - if(!is_array($config)) { - return false; + if(is_null($setParameters)) { + $setParameters = array(); } - - $params = $this->getConfigTranslationArray(); - - foreach($config as $parameter => $value) { - if(($parameter === 'homeFolderNamingRule' - || (isset($params[$parameter]) - && $params[$parameter] === 'homeFolderNamingRule')) - && !empty($value)) { - $value = 'attr:'.$value; - } else if (strpos($parameter, 'ldapBase') !== false - || (isset($params[$parameter]) - && strpos($params[$parameter], 'ldapBase') !== false)) { - $this->readBase($params[$parameter], $value); - if(is_array($setParameters)) { - $setParameters[] = $parameter; - } - continue; - } - if(isset($this->config[$parameter])) { - $this->config[$parameter] = $value; - if(is_array($setParameters)) { - $setParameters[] = $parameter; - } - } else if(isset($params[$parameter])) { - $this->config[$params[$parameter]] = $value; - if(is_array($setParameters)) { - $setParameters[] = $params[$parameter]; - } - } + $this->doNotValidate = false; + $this->configuration->setConfiguration($config, $setParameters); + if(count($setParameters) > 0) { + $this->configured = $this->validateConfiguration(); } - $this->configured = $this->validateConfiguration(); return $this->configured; } /** - * @brief saves the current Configuration in the database + * @brief saves the current Configuration in the database and empties the + * cache + * @return null */ public function saveConfiguration() { - $trans = array_flip($this->getConfigTranslationArray()); - foreach($this->config as $key => $value) { - \OCP\Util::writeLog('user_ldap', 'LDAP: storing key '.$key. - ' value '.print_r($value, true), \OCP\Util::DEBUG); - switch ($key) { - case 'ldapAgentPassword': - $value = base64_encode($value); - break; - case 'ldapBase': - case 'ldapBaseUsers': - case 'ldapBaseGroups': - case 'ldapAttributesForUserSearch': - case 'ldapAttributesForGroupSearch': - if(is_array($value)) { - $value = implode("\n", $value); - } - break; - case 'ldapIgnoreNamingRules': - case 'ldapOverrideUuidAttribute': - case 'ldapUuidAttribute': - case 'hasPagedResultSupport': - continue 2; - } - if(is_null($value)) { - $value = ''; - } - - $this->setValue($trans[$key], $value); - } + $this->configuration->saveConfiguration(); $this->clearCache(); } @@ -432,178 +233,205 @@ class Connection extends LDAPUtility { */ public function getConfiguration() { $this->readConfiguration(); - $trans = $this->getConfigTranslationArray(); - $config = array(); - foreach($trans as $dbKey => $classKey) { - if($classKey === 'homeFolderNamingRule') { - if(strpos($this->config[$classKey], 'attr:') === 0) { - $config[$dbKey] = substr($this->config[$classKey], 5); - } else { - $config[$dbKey] = ''; - } - continue; - } else if((strpos($classKey, 'ldapBase') !== false - || strpos($classKey, 'ldapAttributes') !== false) - && is_array($this->config[$classKey])) { - $config[$dbKey] = implode("\n", $this->config[$classKey]); - continue; + $config = $this->configuration->getConfiguration(); + $cta = $this->configuration->getConfigTranslationArray(); + $result = array(); + foreach($cta as $dbkey => $configkey) { + switch($configkey) { + case 'homeFolderNamingRule': + if(strpos($config[$configkey], 'attr:') === 0) { + $result[$dbkey] = substr($config[$configkey], 5); + } else { + $result[$dbkey] = ''; + } + break; + case 'ldapBase': + case 'ldapBaseUsers': + case 'ldapBaseGroups': + case 'ldapAttributesForUserSearch': + case 'ldapAttributesForGroupSearch': + if(is_array($config[$configkey])) { + $result[$dbkey] = implode("\n", $config[$configkey]); + break; + } //else follows default + default: + $result[$dbkey] = $config[$configkey]; } - $config[$dbKey] = $this->config[$classKey]; } - - return $config; + return $result; } - /** - * @brief Validates the user specified configuration - * @returns true if configuration seems OK, false otherwise - */ - private function validateConfiguration() { - // first step: "soft" checks: settings that are not really - // necessary, but advisable. If left empty, give an info message - if(empty($this->config['ldapBaseUsers'])) { - \OCP\Util::writeLog('user_ldap', 'Base tree for Users is empty, using Base DN', \OCP\Util::INFO); - $this->config['ldapBaseUsers'] = $this->config['ldapBase']; - } - if(empty($this->config['ldapBaseGroups'])) { - \OCP\Util::writeLog('user_ldap', 'Base tree for Groups is empty, using Base DN', \OCP\Util::INFO); - $this->config['ldapBaseGroups'] = $this->config['ldapBase']; - } - if(empty($this->config['ldapGroupFilter']) && empty($this->config['ldapGroupMemberAssocAttr'])) { - \OCP\Util::writeLog('user_ldap', - 'No group filter is specified, LDAP group feature will not be used.', - \OCP\Util::INFO); - } - $uuidAttributes = array( - 'auto', 'entryuuid', 'nsuniqueid', 'objectguid', 'guid'); - if(!in_array($this->config['ldapUuidAttribute'], $uuidAttributes) - && (!is_null($this->configID))) { - \OCP\Config::setAppValue($this->configID, $this->configPrefix.'ldap_uuid_attribute', 'auto'); - \OCP\Util::writeLog('user_ldap', - 'Illegal value for the UUID Attribute, reset to autodetect.', - \OCP\Util::INFO); - } - if(empty($this->config['ldapBackupPort'])) { - //force default - $this->config['ldapBackupPort'] = $this->config['ldapPort']; - } - foreach(array('ldapAttributesForUserSearch', 'ldapAttributesForGroupSearch') as $key) { - if(is_array($this->config[$key]) - && count($this->config[$key]) === 1 - && empty($this->config[$key][0])) { - $this->config[$key] = array(); + private function doSoftValidation() { + //if User or Group Base are not set, take over Base DN setting + foreach(array('ldapBaseUsers', 'ldapBaseGroups') as $keyBase) { + $val = $this->configuration->$keyBase; + if(empty($val)) { + $obj = strpos('Users', $keyBase) !== false ? 'Users' : 'Groups'; + \OCP\Util::writeLog('user_ldap', + 'Base tree for '.$obj. + ' is empty, using Base DN', + \OCP\Util::INFO); + $this->configuration->$keyBase = $this->configuration->ldapBase; } } - if((strpos($this->config['ldapHost'], 'ldaps') === 0) - && $this->config['ldapTLS']) { - $this->config['ldapTLS'] = false; + + $groupFilter = $this->configuration->ldapGroupFilter; + if(empty($groupFilter)) { \OCP\Util::writeLog('user_ldap', - 'LDAPS (already using secure connection) and TLS do not work together. Switched off TLS.', - \OCP\Util::INFO); + 'No group filter is specified, LDAP group '. + 'feature will not be used.', + \OCP\Util::INFO); } + foreach(array('ldapExpertUUIDUserAttr' => 'ldapUuidUserAttribute', + 'ldapExpertUUIDGroupAttr' => 'ldapUuidGroupAttribute') + as $expertSetting => $effectiveSetting) { + $uuidOverride = $this->configuration->$expertSetting; + if(!empty($uuidOverride)) { + $this->configuration->$effectiveSetting = $uuidOverride; + } else { + $uuidAttributes = array('auto', 'entryuuid', 'nsuniqueid', + 'objectguid', 'guid'); + if(!in_array($this->configuration->$effectiveSetting, + $uuidAttributes) + && (!is_null($this->configID))) { + $this->configuration->$effectiveSetting = 'auto'; + $this->configuration->saveConfiguration(); + \OCP\Util::writeLog('user_ldap', + 'Illegal value for the '. + $effectiveSetting.', '.'reset to '. + 'autodetect.', \OCP\Util::INFO); + } + } + } - //second step: critical checks. If left empty or filled wrong, set as unconfigured and give a warning. - $configurationOK = true; - if(empty($this->config['ldapHost'])) { - \OCP\Util::writeLog('user_ldap', 'No LDAP host given, won`t connect.', \OCP\Util::WARN); - $configurationOK = false; + $backupPort = $this->configuration->ldapBackupPort; + if(empty($backupPort)) { + $this->configuration->backupPort = $this->configuration->ldapPort; } - if(empty($this->config['ldapPort'])) { - \OCP\Util::writeLog('user_ldap', 'No LDAP Port given, won`t connect.', \OCP\Util::WARN); - $configurationOK = false; + + //make sure empty search attributes are saved as simple, empty array + $sakeys = array('ldapAttributesForUserSearch', + 'ldapAttributesForGroupSearch'); + foreach($sakeys as $key) { + $val = $this->configuration->$key; + if(is_array($val) && count($val) === 1 && empty($val[0])) { + $this->configuration->$key = array(); + } } - if((empty($this->config['ldapAgentName']) && !empty($this->config['ldapAgentPassword'])) - || (!empty($this->config['ldapAgentName']) && empty($this->config['ldapAgentPassword']))) { + + if((stripos($this->configuration->ldapHost, 'ldaps://') === 0) + && $this->configuration->ldapTLS) { + $this->configuration->ldapTLS = false; \OCP\Util::writeLog('user_ldap', - 'Either no password given for the user agent or a password is given, but no LDAP agent; won`t connect.', - \OCP\Util::WARN); - $configurationOK = false; + 'LDAPS (already using secure connection) and '. + 'TLS do not work together. Switched off TLS.', + \OCP\Util::INFO); } - //TODO: check if ldapAgentName is in DN form - if(empty($this->config['ldapBase']) - && (empty($this->config['ldapBaseUsers']) - && empty($this->config['ldapBaseGroups']))) { - \OCP\Util::writeLog('user_ldap', 'No Base DN given, won`t connect.', \OCP\Util::WARN); - $configurationOK = false; + } + + private function doCriticalValidation() { + $configurationOK = true; + $errorStr = 'Configuration Error (prefix '. + strval($this->configPrefix).'): '; + + //options that shall not be empty + $options = array('ldapHost', 'ldapPort', 'ldapUserDisplayName', + 'ldapGroupDisplayName', 'ldapLoginFilter'); + foreach($options as $key) { + $val = $this->configuration->$key; + if(empty($val)) { + switch($key) { + case 'ldapHost': + $subj = 'LDAP Host'; + break; + case 'ldapPort': + $subj = 'LDAP Port'; + break; + case 'ldapUserDisplayName': + $subj = 'LDAP User Display Name'; + break; + case 'ldapGroupDisplayName': + $subj = 'LDAP Group Display Name'; + break; + case 'ldapLoginFilter': + $subj = 'LDAP Login Filter'; + break; + default: + $subj = $key; + break; + } + $configurationOK = false; + \OCP\Util::writeLog('user_ldap', + $errorStr.'No '.$subj.' given!', + \OCP\Util::WARN); + } } - if(empty($this->config['ldapUserDisplayName'])) { + + //combinations + $agent = $this->configuration->ldapAgentName; + $pwd = $this->configuration->ldapAgentPassword; + if((empty($agent) && !empty($pwd)) || (!empty($agent) && empty($pwd))) { \OCP\Util::writeLog('user_ldap', - 'No user display name attribute specified, won`t connect.', + $errorStr.'either no password is given for the'. + 'user agent or a password is given, but not an'. + 'LDAP agent.', \OCP\Util::WARN); $configurationOK = false; } - if(empty($this->config['ldapGroupDisplayName'])) { + + $base = $this->configuration->ldapBase; + $baseUsers = $this->configuration->ldapBaseUsers; + $baseGroups = $this->configuration->ldapBaseGroups; + + if(empty($base) && empty($baseUsers) && empty($baseGroups)) { \OCP\Util::writeLog('user_ldap', - 'No group display name attribute specified, won`t connect.', - \OCP\Util::WARN); + $errorStr.'Not a single Base DN given.', + \OCP\Util::WARN); $configurationOK = false; } - if(empty($this->config['ldapLoginFilter'])) { - \OCP\Util::writeLog('user_ldap', 'No login filter specified, won`t connect.', \OCP\Util::WARN); - $configurationOK = false; - } - if(mb_strpos($this->config['ldapLoginFilter'], '%uid', 0, 'UTF-8') === false) { + + if(mb_strpos($this->configuration->ldapLoginFilter, '%uid', 0, 'UTF-8') + === false) { \OCP\Util::writeLog('user_ldap', - 'Login filter does not contain %uid place holder, won`t connect.', - \OCP\Util::WARN); - \OCP\Util::writeLog('user_ldap', 'Login filter was ' . $this->config['ldapLoginFilter'], \OCP\Util::DEBUG); + $errorStr.'login filter does not contain %uid '. + 'place holder.', + \OCP\Util::WARN); $configurationOK = false; } - if(!empty($this->config['ldapExpertUUIDAttr'])) { - $this->config['ldapUuidAttribute'] = $this->config['ldapExpertUUIDAttr']; - } - return $configurationOK; } /** - * @returns an associative array with the default values. Keys are correspond - * to config-value entries in the database table + * @brief Validates the user specified configuration + * @returns true if configuration seems OK, false otherwise */ - static public function getDefaults() { - return array( - 'ldap_host' => '', - 'ldap_port' => '389', - 'ldap_backup_host' => '', - 'ldap_backup_port' => '', - 'ldap_override_main_server' => '', - 'ldap_dn' => '', - 'ldap_agent_password' => '', - 'ldap_base' => '', - 'ldap_base_users' => '', - 'ldap_base_groups' => '', - 'ldap_userlist_filter' => 'objectClass=person', - 'ldap_login_filter' => 'uid=%uid', - 'ldap_group_filter' => 'objectClass=posixGroup', - 'ldap_display_name' => 'cn', - 'ldap_group_display_name' => 'cn', - 'ldap_tls' => 1, - 'ldap_nocase' => 0, - 'ldap_quota_def' => '', - 'ldap_quota_attr' => '', - 'ldap_email_attr' => '', - 'ldap_group_member_assoc_attribute' => 'uniqueMember', - 'ldap_cache_ttl' => 600, - 'ldap_uuid_attribute' => 'auto', - 'ldap_override_uuid_attribute' => 0, - 'home_folder_naming_rule' => '', - 'ldap_turn_off_cert_check' => 0, - 'ldap_configuration_active' => 1, - 'ldap_attributes_for_user_search' => '', - 'ldap_attributes_for_group_search' => '', - 'ldap_expert_username_attr' => '', - 'ldap_expert_uuid_attr' => '', - ); + private function validateConfiguration() { + + if($this->doNotValidate) { + //don't do a validation if it is a new configuration with pure + //default values. Will be allowed on changes via __set or + //setConfiguration + return false; + } + + // first step: "soft" checks: settings that are not really + // necessary, but advisable. If left empty, give an info message + $this->doSoftValidation(); + + //second step: critical checks. If left empty or filled wrong, set as + //unconfigured and give a warning. + return $this->doCriticalValidation(); } + /** * Connects and Binds to LDAP */ private function establishConnection() { - if(!$this->config['ldapConfigurationActive']) { + if(!$this->configuration->ldapConfigurationActive) { return null; } static $phpLDAPinstalled = true; @@ -611,29 +439,36 @@ class Connection extends LDAPUtility { return false; } if(!$this->configured) { - \OCP\Util::writeLog('user_ldap', 'Configuration is invalid, cannot connect', \OCP\Util::WARN); + \OCP\Util::writeLog('user_ldap', + 'Configuration is invalid, cannot connect', + \OCP\Util::WARN); return false; } if(!$this->ldapConnectionRes) { if(!$this->ldap->areLDAPFunctionsAvailable()) { $phpLDAPinstalled = false; \OCP\Util::writeLog('user_ldap', - 'function ldap_connect is not available. Make sure that the PHP ldap module is installed.', - \OCP\Util::ERROR); + 'function ldap_connect is not available. Make '. + 'sure that the PHP ldap module is installed.', + \OCP\Util::ERROR); return false; } - if($this->config['turnOffCertCheck']) { + if($this->configuration->turnOffCertCheck) { if(putenv('LDAPTLS_REQCERT=never')) { \OCP\Util::writeLog('user_ldap', 'Turned off SSL certificate validation successfully.', \OCP\Util::WARN); } else { - \OCP\Util::writeLog('user_ldap', 'Could not turn off SSL certificate validation.', \OCP\Util::WARN); + \OCP\Util::writeLog('user_ldap', + 'Could not turn off SSL certificate validation.', + \OCP\Util::WARN); } } - if(!$this->config['ldapOverrideMainServer'] && !$this->getFromCache('overrideMainServer')) { - $this->doConnect($this->config['ldapHost'], $this->config['ldapPort']); + if(!$this->configuration->ldapOverrideMainServer + && !$this->getFromCache('overrideMainServer')) { + $this->doConnect($this->configuration->ldapHost, + $this->configuration->ldapPort); $bindStatus = $this->bind(); $error = $this->ldap->isResource($this->ldapConnectionRes) ? $this->ldap->errno($this->ldapConnectionRes) : -1; @@ -644,9 +479,10 @@ class Connection extends LDAPUtility { //if LDAP server is not reachable, try the Backup (Replica!) Server if((!$bindStatus && ($error !== 0)) - || $this->config['ldapOverrideMainServer'] + || $this->configuration->ldapOverrideMainServer || $this->getFromCache('overrideMainServer')) { - $this->doConnect($this->config['ldapBackupHost'], $this->config['ldapBackupPort']); + $this->doConnect($this->configuration->ldapBackupHost, + $this->configuration->ldapBackupPort); $bindStatus = $this->bind(); if(!$bindStatus && $error === -1) { //when bind to backup server succeeded and failed to main server, @@ -669,7 +505,7 @@ class Connection extends LDAPUtility { $this->ldapConnectionRes = $this->ldap->connect($host, $port); if($this->ldap->setOption($this->ldapConnectionRes, LDAP_OPT_PROTOCOL_VERSION, 3)) { if($this->ldap->setOption($this->ldapConnectionRes, LDAP_OPT_REFERRALS, 0)) { - if($this->config['ldapTLS']) { + if($this->configuration->ldapTLS) { $this->ldap->startTls($this->ldapConnectionRes); } } @@ -681,7 +517,7 @@ class Connection extends LDAPUtility { */ public function bind() { static $getConnectionResourceAttempt = false; - if(!$this->config['ldapConfigurationActive']) { + if(!$this->configuration->ldapConfigurationActive) { return false; } if($getConnectionResourceAttempt) { @@ -695,8 +531,8 @@ class Connection extends LDAPUtility { return false; } $ldapLogin = @$this->ldap->bind($cr, - $this->config['ldapAgentName'], - $this->config['ldapAgentPassword']); + $this->configuration->ldapAgentName, + $this->configuration->ldapAgentPassword); if(!$ldapLogin) { \OCP\Util::writeLog('user_ldap', 'Bind failed: ' . $this->ldap->errno($cr) . ': ' . $this->ldap->error($cr), diff --git a/apps/user_ldap/lib/helper.php b/apps/user_ldap/lib/helper.php index 4c9dd07a12c..09f646921e3 100644 --- a/apps/user_ldap/lib/helper.php +++ b/apps/user_ldap/lib/helper.php @@ -161,4 +161,25 @@ class Helper { return true; } + + /** + * @brief extractsthe domain from a given URL + * @param $url the URL + * @return mixed, domain as string on success, false otherwise + */ + static public function getDomainFromURL($url) { + $uinfo = parse_url($url); + if(!is_array($uinfo)) { + return false; + } + + $domain = false; + if(isset($uinfo['host'])) { + $domain = $uinfo['host']; + } else if(isset($uinfo['path'])) { + $domain = $uinfo['path']; + } + + return $domain; + } } diff --git a/apps/user_ldap/lib/ildapwrapper.php b/apps/user_ldap/lib/ildapwrapper.php index 9e6bd56ef2a..20587cba7db 100644 --- a/apps/user_ldap/lib/ildapwrapper.php +++ b/apps/user_ldap/lib/ildapwrapper.php @@ -68,6 +68,14 @@ interface ILDAPWrapper { public function controlPagedResultResponse($link, $result, &$cookie); /** + * @brief Count the number of entries in a search + * @param $link LDAP link resource + * @param $result LDAP result resource + * @return mixed, number of results on success, false otherwise + */ + public function countEntries($link, $result); + + /** * @brief Return the LDAP error number of the last LDAP command * @param $link LDAP link resource * @return error message as string @@ -98,6 +106,14 @@ interface ILDAPWrapper { public function getAttributes($link, $result); /** + * @brief Get the DN of a result entry + * @param $link LDAP link resource + * @param $result LDAP result resource + * @return string containing the DN, false on error + */ + public function getDN($link, $result); + + /** * @brief Get all result entries * @param $link LDAP link resource * @param $result LDAP result resource @@ -106,6 +122,14 @@ interface ILDAPWrapper { public function getEntries($link, $result); /** + * @brief Return next result id + * @param $link LDAP link resource + * @param $result LDAP entry result resource + * @return an LDAP search result resource + * */ + public function nextEntry($link, $result); + + /** * @brief Read an entry * @param $link LDAP link resource * @param $baseDN The DN of the entry to read from diff --git a/apps/user_ldap/lib/jobs.php b/apps/user_ldap/lib/jobs.php index 2f90da3bfb6..9b108da6331 100644 --- a/apps/user_ldap/lib/jobs.php +++ b/apps/user_ldap/lib/jobs.php @@ -139,12 +139,12 @@ class Jobs extends \OC\BackgroundJob\TimedJob { return self::$groupBE; } $configPrefixes = Helper::getServerConfigurationPrefixes(true); - $ldapWrapper = new OCA\user_ldap\lib\LDAP(); + $ldapWrapper = new LDAP(); if(count($configPrefixes) === 1) { //avoid the proxy when there is only one LDAP server configured - $connector = new OCA\user_ldap\lib\Connection($ldapWrapper, $configPrefixes[0]); - $ldapAccess = new OCA\user_ldap\lib\Access($connector, $ldapWrapper); - self::$groupBE = new OCA\user_ldap\GROUP_LDAP($ldapAccess); + $connector = new Connection($ldapWrapper, $configPrefixes[0]); + $ldapAccess = new Access($connector, $ldapWrapper); + self::$groupBE = new \OCA\user_ldap\GROUP_LDAP($ldapAccess); } else { self::$groupBE = new \OCA\user_ldap\Group_Proxy($configPrefixes, $ldapWrapper); } diff --git a/apps/user_ldap/lib/ldap.php b/apps/user_ldap/lib/ldap.php index b63e969912a..dda8533c41f 100644 --- a/apps/user_ldap/lib/ldap.php +++ b/apps/user_ldap/lib/ldap.php @@ -49,6 +49,10 @@ class LDAP implements ILDAPWrapper { $isCritical, $cookie); } + public function countEntries($link, $result) { + return $this->invokeLDAPMethod('count_entries', $link, $result); + } + public function errno($link) { return $this->invokeLDAPMethod('errno', $link); } @@ -65,10 +69,18 @@ class LDAP implements ILDAPWrapper { return $this->invokeLDAPMethod('get_attributes', $link, $result); } + public function getDN($link, $result) { + return $this->invokeLDAPMethod('get_dn', $link, $result); + } + public function getEntries($link, $result) { return $this->invokeLDAPMethod('get_entries', $link, $result); } + public function nextEntry($link, $result) { + return $this->invokeLDAPMethod('next_entry', $link, $result); + } + public function read($link, $baseDN, $filter, $attr) { return $this->invokeLDAPMethod('read', $link, $baseDN, $filter, $attr); } @@ -79,7 +91,7 @@ class LDAP implements ILDAPWrapper { } public function setOption($link, $option, $value) { - $this->invokeLDAPMethod('set_option', $link, $option, $value); + return $this->invokeLDAPMethod('set_option', $link, $option, $value); } public function sort($link, $result, $sortfilter) { diff --git a/apps/user_ldap/lib/proxy.php b/apps/user_ldap/lib/proxy.php index c74b357bdd2..30e1875901c 100644 --- a/apps/user_ldap/lib/proxy.php +++ b/apps/user_ldap/lib/proxy.php @@ -54,7 +54,7 @@ abstract class Proxy { return 'group-'.$gid.'-lastSeenOn'; } - abstract protected function callOnLastSeenOn($id, $method, $parameters); + abstract protected function callOnLastSeenOn($id, $method, $parameters, $passOnWhen); abstract protected function walkBackends($id, $method, $parameters); /** @@ -64,8 +64,9 @@ abstract class Proxy { * @param $parameters an array of parameters to be passed * @return mixed, the result of the specified method */ - protected function handleRequest($id, $method, $parameters) { - if(!$result = $this->callOnLastSeenOn($id, $method, $parameters)) { + protected function handleRequest($id, $method, $parameters, $passOnWhen = false) { + $result = $this->callOnLastSeenOn($id, $method, $parameters, $passOnWhen); + if($result === $passOnWhen) { $result = $this->walkBackends($id, $method, $parameters); } return $result; diff --git a/apps/user_ldap/lib/wizard.php b/apps/user_ldap/lib/wizard.php new file mode 100644 index 00000000000..b70ede8599c --- /dev/null +++ b/apps/user_ldap/lib/wizard.php @@ -0,0 +1,1068 @@ +<?php + +/** + * ownCloud – LDAP Wizard + * + * @author Arthur Schiwon + * @copyright 2013 Arthur Schiwon blizzz@owncloud.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library 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 along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCA\user_ldap\lib; + +class Wizard extends LDAPUtility { + static protected $l; + protected $cr; + protected $configuration; + protected $result; + protected $resultCache = array(); + + const LRESULT_PROCESSED_OK = 2; + const LRESULT_PROCESSED_INVALID = 3; + const LRESULT_PROCESSED_SKIP = 4; + + const LFILTER_LOGIN = 2; + const LFILTER_USER_LIST = 3; + const LFILTER_GROUP_LIST = 4; + + const LFILTER_MODE_ASSISTED = 2; + const LFILTER_MODE_RAW = 1; + + const LDAP_NW_TIMEOUT = 4; + + /** + * @brief Constructor + * @param $configuration an instance of Configuration + * @param $ldap an instance of ILDAPWrapper + */ + public function __construct(Configuration $configuration, ILDAPWrapper $ldap) { + parent::__construct($ldap); + $this->configuration = $configuration; + if(is_null(Wizard::$l)) { + Wizard::$l = \OC_L10N::get('user_ldap'); + } + $this->result = new WizardResult; + } + + public function __destruct() { + if($this->result->hasChanges()) { + $this->configuration->saveConfiguration(); + } + } + + public function countGroups() { + if(!$this->checkRequirements(array('ldapHost', + 'ldapPort', + 'ldapBase', + ))) { + return false; + } + + $base = $this->configuration->ldapBase[0]; + $filter = $this->configuration->ldapGroupFilter; + \OCP\Util::writeLog('user_ldap', 'Wiz: g filter '. print_r($filter, true), \OCP\Util::DEBUG); + $l = \OC_L10N::get('user_ldap'); + if(empty($filter)) { + $output = $l->n('%s group found', '%s groups found', 0, array(0)); + $this->result->addChange('ldap_group_count', $output); + return $this->result; + } + $cr = $this->getConnection(); + if(!$cr) { + throw new \Exception('Could not connect to LDAP'); + } + $rr = $this->ldap->search($cr, $base, $filter, array('dn')); + if(!$this->ldap->isResource($rr)) { + return false; + } + $entries = $this->ldap->countEntries($cr, $rr); + $entries = ($entries !== false) ? $entries : 0; + $output = $l->n('%s group found', '%s groups found', $entries, $entries); + $this->result->addChange('ldap_group_count', $output); + + return $this->result; + } + + public function countUsers() { + if(!$this->checkRequirements(array('ldapHost', + 'ldapPort', + 'ldapBase', + 'ldapUserFilter', + ))) { + return false; + } + + $cr = $this->getConnection(); + if(!$cr) { + throw new \Exception('Could not connect to LDAP'); + } + + $base = $this->configuration->ldapBase[0]; + $filter = $this->configuration->ldapUserFilter; + $rr = $this->ldap->search($cr, $base, $filter, array('dn')); + if(!$this->ldap->isResource($rr)) { + return false; + } + $entries = $this->ldap->countEntries($cr, $rr); + $entries = ($entries !== false) ? $entries : 0; + $l = \OC_L10N::get('user_ldap'); + $output = $l->n('%s user found', '%s users found', $entries, $entries); + $this->result->addChange('ldap_user_count', $output); + + return $this->result; + } + + + public function determineAttributes() { + if(!$this->checkRequirements(array('ldapHost', + 'ldapPort', + 'ldapBase', + 'ldapUserFilter', + ))) { + return false; + } + + $attributes = $this->getUserAttributes(); + + natcasesort($attributes); + $attributes = array_values($attributes); + + $this->result->addOptions('ldap_loginfilter_attributes', $attributes); + + $selected = $this->configuration->ldapLoginFilterAttributes; + if(is_array($selected) && !empty($selected)) { + $this->result->addChange('ldap_loginfilter_attributes', $selected); + } + + return $this->result; + } + + /** + * @brief return the state of the Group Filter Mode + */ + public function getGroupFilterMode() { + $this->getFilterMode('ldapGroupFilterMode'); + return $this->result; + } + + /** + * @brief return the state of the Login Filter Mode + */ + public function getLoginFilterMode() { + $this->getFilterMode('ldapLoginFilterMode'); + return $this->result; + } + + /** + * @brief return the state of the User Filter Mode + */ + public function getUserFilterMode() { + $this->getFilterMode('ldapUserFilterMode'); + return $this->result; + } + + /** + * @brief return the state of the mode of the specified filter + * @param $confkey string, contains the access key of the Configuration + */ + private function getFilterMode($confkey) { + $mode = $this->configuration->$confkey; + if(is_null($mode)) { + $mode = $this->LFILTER_MODE_ASSISTED; + } + $this->result->addChange($confkey, $mode); + } + + /** + * @brief detects the available LDAP attributes + * @returns the instance's WizardResult instance + */ + private function getUserAttributes() { + if(!$this->checkRequirements(array('ldapHost', + 'ldapPort', + 'ldapBase', + 'ldapUserFilter', + ))) { + return false; + } + $cr = $this->getConnection(); + if(!$cr) { + throw new \Exception('Could not connect to LDAP'); + } + + $base = $this->configuration->ldapBase[0]; + $filter = $this->configuration->ldapUserFilter; + $rr = $this->ldap->search($cr, $base, $filter, array(), 1, 1); + if(!$this->ldap->isResource($rr)) { + return false; + } + $er = $this->ldap->firstEntry($cr, $rr); + $attributes = $this->ldap->getAttributes($cr, $er); + $pureAttributes = array(); + for($i = 0; $i < $attributes['count']; $i++) { + $pureAttributes[] = $attributes[$i]; + } + + return $pureAttributes; + } + + /** + * @brief detects the available LDAP groups + * @returns the instance's WizardResult instance + */ + public function determineGroupsForGroups() { + return $this->determineGroups('ldap_groupfilter_groups', + 'ldapGroupFilterGroups', + false); + } + + /** + * @brief detects the available LDAP groups + * @returns the instance's WizardResult instance + */ + public function determineGroupsForUsers() { + return $this->determineGroups('ldap_userfilter_groups', + 'ldapUserFilterGroups'); + } + + /** + * @brief detects the available LDAP groups + * @returns the instance's WizardResult instance + */ + private function determineGroups($dbkey, $confkey, $testMemberOf = true) { + if(!$this->checkRequirements(array('ldapHost', + 'ldapPort', + 'ldapBase', + ))) { + return false; + } + $cr = $this->getConnection(); + if(!$cr) { + throw new \Exception('Could not connect to LDAP'); + } + + $obclasses = array('posixGroup', 'group', 'zimbraDistributionList', '*'); + $this->determineFeature($obclasses, 'cn', $dbkey, $confkey); + + if($testMemberOf) { + $this->configuration->hasMemberOfFilterSupport = $this->testMemberOf(); + $this->result->markChange(); + if(!$this->configuration->hasMemberOfFilterSupport) { + throw new \Exception('memberOf is not supported by the server'); + } + } + + return $this->result; + } + + public function determineGroupMemberAssoc() { + if(!$this->checkRequirements(array('ldapHost', + 'ldapPort', + 'ldapGroupFilter', + ))) { + return false; + } + $attribute = $this->detectGroupMemberAssoc(); + if($attribute === false) { + return false; + } + $this->configuration->setConfiguration(array('ldapGroupMemberAssocAttr' => $attribute)); + //so it will be saved on destruct + $this->result->markChange(); + + return $this->result; + } + + /** + * @brief detects the available object classes + * @returns the instance's WizardResult instance + */ + public function determineGroupObjectClasses() { + if(!$this->checkRequirements(array('ldapHost', + 'ldapPort', + 'ldapBase', + ))) { + return false; + } + $cr = $this->getConnection(); + if(!$cr) { + throw new \Exception('Could not connect to LDAP'); + } + + $obclasses = array('group', 'posixGroup', '*'); + $this->determineFeature($obclasses, + 'objectclass', + 'ldap_groupfilter_objectclass', + 'ldapGroupFilterObjectclass', + false); + + return $this->result; + } + + /** + * @brief detects the available object classes + * @returns the instance's WizardResult instance + */ + public function determineUserObjectClasses() { + if(!$this->checkRequirements(array('ldapHost', + 'ldapPort', + 'ldapBase', + ))) { + return false; + } + $cr = $this->getConnection(); + if(!$cr) { + throw new \Exception('Could not connect to LDAP'); + } + + $obclasses = array('inetOrgPerson', 'person', 'organizationalPerson', + 'user', 'posixAccount', '*'); + $filter = $this->configuration->ldapUserFilter; + //if filter is empty, it is probably the first time the wizard is called + //then, apply suggestions. + $this->determineFeature($obclasses, + 'objectclass', + 'ldap_userfilter_objectclass', + 'ldapUserFilterObjectclass', + empty($filter)); + + return $this->result; + } + + public function getGroupFilter() { + if(!$this->checkRequirements(array('ldapHost', + 'ldapPort', + 'ldapBase', + ))) { + return false; + } + //make sure the use display name is set + $displayName = $this->configuration->ldapGroupDisplayName; + if(empty($displayName)) { + $d = $this->configuration->getDefaults(); + $this->applyFind('ldap_group_display_name', + $d['ldap_group_display_name']); + } + $filter = $this->composeLdapFilter(self::LFILTER_GROUP_LIST); + + $this->applyFind('ldap_group_filter', $filter); + return $this->result; + } + + public function getUserListFilter() { + if(!$this->checkRequirements(array('ldapHost', + 'ldapPort', + 'ldapBase', + ))) { + return false; + } + //make sure the use display name is set + $displayName = $this->configuration->ldapUserDisplayName; + if(empty($displayName)) { + $d = $this->configuration->getDefaults(); + $this->applyFind('ldap_display_name', $d['ldap_display_name']); + } + $filter = $this->composeLdapFilter(self::LFILTER_USER_LIST); + if(!$filter) { + throw new \Exception('Cannot create filter'); + } + + $this->applyFind('ldap_userlist_filter', $filter); + return $this->result; + } + + public function getUserLoginFilter() { + if(!$this->checkRequirements(array('ldapHost', + 'ldapPort', + 'ldapBase', + 'ldapUserFilter', + ))) { + return false; + } + + $filter = $this->composeLdapFilter(self::LFILTER_LOGIN); + if(!$filter) { + throw new \Exception('Cannot create filter'); + } + + $this->applyFind('ldap_login_filter', $filter); + return $this->result; + } + + /** + * Tries to determine the port, requires given Host, User DN and Password + * @returns mixed WizardResult on success, false otherwise + */ + public function guessPortAndTLS() { + if(!$this->checkRequirements(array('ldapHost', + ))) { + return false; + } + $this->checkHost(); + $portSettings = $this->getPortSettingsToTry(); + + if(!is_array($portSettings)) { + throw new \Exception(print_r($portSettings, true)); + } + + //proceed from the best configuration and return on first success + foreach($portSettings as $setting) { + $p = $setting['port']; + $t = $setting['tls']; + \OCP\Util::writeLog('user_ldap', 'Wiz: trying port '. $p . ', TLS '. $t, \OCP\Util::DEBUG); + //connectAndBind may throw Exception, it needs to be catched by the + //callee of this method + if($this->connectAndBind($p, $t) === true) { + $config = array('ldapPort' => $p, + 'ldapTLS' => intval($t) + ); + $this->configuration->setConfiguration($config); + \OCP\Util::writeLog('user_ldap', 'Wiz: detected Port '. $p, \OCP\Util::DEBUG); + $this->result->addChange('ldap_port', $p); + return $this->result; + } + } + + //custom port, undetected (we do not brute force) + return false; + } + + /** + * @brief tries to determine a base dn from User DN or LDAP Host + * @returns mixed WizardResult on success, false otherwise + */ + public function guessBaseDN() { + if(!$this->checkRequirements(array('ldapHost', + 'ldapPort', + ))) { + return false; + } + + //check whether a DN is given in the agent name (99.9% of all cases) + $base = null; + $i = stripos($this->configuration->ldapAgentName, 'dc='); + if($i !== false) { + $base = substr($this->configuration->ldapAgentName, $i); + if($this->testBaseDN($base)) { + $this->applyFind('ldap_base', $base); + return $this->result; + } + } + + //this did not help :( + //Let's see whether we can parse the Host URL and convert the domain to + //a base DN + $domain = Helper::getDomainFromURL($this->configuration->ldapHost); + if(!$domain) { + return false; + } + + $dparts = explode('.', $domain); + $base2 = implode('dc=', $dparts); + if($base !== $base2 && $this->testBaseDN($base2)) { + $this->applyFind('ldap_base', $base2); + return $this->result; + } + + return false; + } + + /** + * @brief sets the found value for the configuration key in the WizardResult + * as well as in the Configuration instance + * @param $key the configuration key + * @param $value the (detected) value + * @return null + * + */ + private function applyFind($key, $value) { + $this->result->addChange($key, $value); + $this->configuration->setConfiguration(array($key => $value)); + } + + /** + * @brief Checks, whether a port was entered in the Host configuration + * field. In this case the port will be stripped off, but also stored as + * setting. + */ + private function checkHost() { + $host = $this->configuration->ldapHost; + $hostInfo = parse_url($host); + + //removes Port from Host + if(is_array($hostInfo) && isset($hostInfo['port'])) { + $port = $hostInfo['port']; + $host = str_replace(':'.$port, '', $host); + $this->applyFind('ldap_host', $host); + $this->applyFind('ldap_port', $port); + } + } + + /** + * @brief tries to detect the group member association attribute which is + * one of 'uniqueMember', 'memberUid', 'member' + * @return mixed, string with the attribute name, false on error + */ + private function detectGroupMemberAssoc() { + $possibleAttrs = array('uniqueMember', 'memberUid', 'member', 'unfugasdfasdfdfa'); + $filter = $this->configuration->ldapGroupFilter; + if(empty($filter)) { + return false; + } + $cr = $this->getConnection(); + if(!$cr) { + throw new \Exception('Could not connect to LDAP'); + } + $base = $this->configuration->ldapBase[0]; + $rr = $this->ldap->search($cr, $base, $filter, $possibleAttrs); + if(!$this->ldap->isResource($rr)) { + return false; + } + $er = $this->ldap->firstEntry($cr, $rr); + while(is_resource($er)) { + $dn = $this->ldap->getDN($cr, $er); + $attrs = $this->ldap->getAttributes($cr, $er); + $result = array(); + for($i = 0; $i < count($possibleAttrs); $i++) { + if(isset($attrs[$possibleAttrs[$i]])) { + $result[$possibleAttrs[$i]] = $attrs[$possibleAttrs[$i]]['count']; + } + } + if(!empty($result)) { + natsort($result); + return key($result); + } + + $er = $this->ldap->nextEntry($cr, $er); + } + + return false; + } + + /** + * @brief Checks whether for a given BaseDN results will be returned + * @param $base the BaseDN to test + * @return bool true on success, false otherwise + */ + private function testBaseDN($base) { + $cr = $this->getConnection(); + if(!$cr) { + throw new \Exception('Could not connect to LDAP'); + } + + //base is there, let's validate it. If we search for anything, we should + //get a result set > 0 on a proper base + $rr = $this->ldap->search($cr, $base, 'objectClass=*', array('dn'), 0, 1); + if(!$this->ldap->isResource($rr)) { + return false; + } + $entries = $this->ldap->countEntries($cr, $rr); + return ($entries !== false) && ($entries > 0); + } + + /** + * @brief Checks whether the server supports memberOf in LDAP Filter. + * Requires that groups are determined, thus internally called from within + * determineGroups() + * @return bool, true if it does, false otherwise + */ + private function testMemberOf() { + $cr = $this->getConnection(); + if(!$cr) { + throw new \Exception('Could not connect to LDAP'); + } + if(!is_array($this->configuration->ldapBase) + || !isset($this->configuration->ldapBase[0])) { + return false; + } + $base = $this->configuration->ldapBase[0]; + $filterPrefix = '(&(objectclass=*)(memberOf='; + $filterSuffix = '))'; + + foreach($this->resultCache as $dn => $properties) { + if(!isset($properties['cn'])) { + //assuming only groups have their cn cached :) + continue; + } + $filter = strtolower($filterPrefix . $dn . $filterSuffix); + $rr = $this->ldap->search($cr, $base, $filter, array('dn')); + if(!$this->ldap->isResource($rr)) { + continue; + } + $entries = $this->ldap->countEntries($cr, $rr); + //we do not know which groups are empty, so test any and return + //success on the first match that returns at least one user + if(($entries !== false) && ($entries > 0)) { + return true; + } + } + + return false; + } + + /** + * @brief creates an LDAP Filter from given configuration + * @param $filterType int, for which use case the filter shall be created + * can be any of self::LFILTER_USER_LIST, self::LFILTER_LOGIN or + * self::LFILTER_GROUP_LIST + * @return mixed, string with the filter on success, false otherwise + */ + private function composeLdapFilter($filterType) { + $filter = ''; + $parts = 0; + switch ($filterType) { + case self::LFILTER_USER_LIST: + $objcs = $this->configuration->ldapUserFilterObjectclass; + //glue objectclasses + if(is_array($objcs) && count($objcs) > 0) { + $filter .= '(|'; + foreach($objcs as $objc) { + $filter .= '(objectclass=' . $objc . ')'; + } + $filter .= ')'; + $parts++; + } + //glue group memberships + if($this->configuration->hasMemberOfFilterSupport) { + $cns = $this->configuration->ldapUserFilterGroups; + if(is_array($cns) && count($cns) > 0) { + $filter .= '(|'; + $cr = $this->getConnection(); + if(!$cr) { + throw new \Exception('Could not connect to LDAP'); + } + $base = $this->configuration->ldapBase[0]; + foreach($cns as $cn) { + $rr = $this->ldap->search($cr, $base, 'cn=' . $cn, array('dn')); + if(!$this->ldap->isResource($rr)) { + continue; + } + $er = $this->ldap->firstEntry($cr, $rr); + $dn = $this->ldap->getDN($cr, $er); + $filter .= '(memberof=' . $dn . ')'; + } + $filter .= ')'; + } + $parts++; + } + //wrap parts in AND condition + if($parts > 1) { + $filter = '(&' . $filter . ')'; + } + if(empty($filter)) { + $filter = '(objectclass=*)'; + } + break; + + case self::LFILTER_GROUP_LIST: + $objcs = $this->configuration->ldapGroupFilterObjectclass; + //glue objectclasses + if(is_array($objcs) && count($objcs) > 0) { + $filter .= '(|'; + foreach($objcs as $objc) { + $filter .= '(objectclass=' . $objc . ')'; + } + $filter .= ')'; + $parts++; + } + //glue group memberships + $cns = $this->configuration->ldapGroupFilterGroups; + if(is_array($cns) && count($cns) > 0) { + $filter .= '(|'; + $base = $this->configuration->ldapBase[0]; + foreach($cns as $cn) { + $filter .= '(cn=' . $cn . ')'; + } + $filter .= ')'; + } + $parts++; + //wrap parts in AND condition + if($parts > 1) { + $filter = '(&' . $filter . ')'; + } + break; + + case self::LFILTER_LOGIN: + $ulf = $this->configuration->ldapUserFilter; + $loginpart = '=%uid'; + $filterUsername = ''; + $userAttributes = $this->getUserAttributes(); + $userAttributes = array_change_key_case(array_flip($userAttributes)); + $parts = 0; + + $x = $this->configuration->ldapLoginFilterUsername; + if($this->configuration->ldapLoginFilterUsername === '1') { + $attr = ''; + if(isset($userAttributes['uid'])) { + $attr = 'uid'; + } else if(isset($userAttributes['samaccountname'])) { + $attr = 'samaccountname'; + } else if(isset($userAttributes['cn'])) { + //fallback + $attr = 'cn'; + } + if(!empty($attr)) { + $filterUsername = '(' . $attr . $loginpart . ')'; + $parts++; + } + } + + $filterEmail = ''; + if($this->configuration->ldapLoginFilterEmail === '1') { + $filterEmail = '(|(mailPrimaryAddress=%uid)(mail=%uid))'; + $parts++; + } + + $filterAttributes = ''; + $attrsToFilter = $this->configuration->ldapLoginFilterAttributes; + if(is_array($attrsToFilter) && count($attrsToFilter) > 0) { + $filterAttributes = '(|'; + foreach($attrsToFilter as $attribute) { + $filterAttributes .= '(' . $attribute . $loginpart . ')'; + } + $filterAttributes .= ')'; + $parts++; + } + + $filterLogin = ''; + if($parts > 1) { + $filterLogin = '(|'; + } + $filterLogin .= $filterUsername; + $filterLogin .= $filterEmail; + $filterLogin .= $filterAttributes; + if($parts > 1) { + $filterLogin .= ')'; + } + + $filter = '(&'.$ulf.$filterLogin.')'; + break; + } + + \OCP\Util::writeLog('user_ldap', 'Wiz: Final filter '.$filter, \OCP\Util::DEBUG); + + return $filter; + } + + /** + * Connects and Binds to an LDAP Server + * @param $port the port to connect with + * @param $tls whether startTLS is to be used + * @return + */ + private function connectAndBind($port = 389, $tls = false, $ncc = false) { + if($ncc) { + //No certificate check + //FIXME: undo afterwards + putenv('LDAPTLS_REQCERT=never'); + } + + //connect, does not really trigger any server communication + \OCP\Util::writeLog('user_ldap', 'Wiz: Checking Host Info ', \OCP\Util::DEBUG); + $host = $this->configuration->ldapHost; + $hostInfo = parse_url($host); + if(!$hostInfo) { + throw new \Exception($this->l->t('Invalid Host')); + } + if(isset($hostInfo['scheme'])) { + if(isset($hostInfo['port'])) { + //problem + } else { + $host .= ':' . $port; + } + } + \OCP\Util::writeLog('user_ldap', 'Wiz: Attempting to connect ', \OCP\Util::DEBUG); + $cr = $this->ldap->connect($host, $port); + if(!is_resource($cr)) { + throw new \Exception($this->l->t('Invalid Host')); + } + + \OCP\Util::writeLog('user_ldap', 'Wiz: Setting LDAP Options ', \OCP\Util::DEBUG); + //set LDAP options + $this->ldap->setOption($cr, LDAP_OPT_PROTOCOL_VERSION, 3); + $this->ldap->setOption($cr, LDAP_OPT_NETWORK_TIMEOUT, self::LDAP_NW_TIMEOUT); + if($tls) { + $isTlsWorking = @$this->ldap->startTls($cr); + if(!$isTlsWorking) { + return false; + } + } + + \OCP\Util::writeLog('user_ldap', 'Wiz: Attemping to Bind ', \OCP\Util::DEBUG); + //interesting part: do the bind! + $login = $this->ldap->bind($cr, + $this->configuration->ldapAgentName, + $this->configuration->ldapAgentPassword); + + if($login === true) { + $this->ldap->unbind($cr); + if($ncc) { + throw new \Exception('Certificate cannot be validated.'); + } + \OCP\Util::writeLog('user_ldap', 'Wiz: Bind successfull to Port '. $port . ' TLS ' . intval($tls), \OCP\Util::DEBUG); + return true; + } + + $errno = $this->ldap->errno($cr); + $error = ldap_error($cr); + $this->ldap->unbind($cr); + if($errno === -1 || ($errno === 2 && $ncc)) { + //host, port or TLS wrong + return false; + } else if ($errno === 2) { + return $this->connectAndBind($port, $tls, true); + } + throw new \Exception($error); + } + + /** + * @brief checks whether a valid combination of agent and password has been + * provided (either two values or nothing for anonymous connect) + * @return boolean, true if everything is fine, false otherwise + * + */ + private function checkAgentRequirements() { + $agent = $this->configuration->ldapAgentName; + $pwd = $this->configuration->ldapAgentPassword; + + return ( (!empty($agent) && !empty($pwd)) + || (empty($agent) && empty($pwd))); + } + + private function checkRequirements($reqs) { + $this->checkAgentRequirements(); + foreach($reqs as $option) { + $value = $this->configuration->$option; + if(empty($value)) { + return false; + } + } + return true; + } + + /** + * @brief does a cumulativeSearch on LDAP to get different values of a + * specified attribute + * @param $filters array, the filters that shall be used in the search + * @param $attr the attribute of which a list of values shall be returned + * @param $lfw bool, whether the last filter is a wildcard which shall not + * be processed if there were already findings, defaults to true + * @param $maxF string. if not null, this variable will have the filter that + * yields most result entries + * @return mixed, an array with the values on success, false otherwise + * + */ + private function cumulativeSearchOnAttribute($filters, $attr, $lfw = true, &$maxF = null) { + $dnRead = array(); + $foundItems = array(); + $maxEntries = 0; + if(!is_array($this->configuration->ldapBase) + || !isset($this->configuration->ldapBase[0])) { + return false; + } + $base = $this->configuration->ldapBase[0]; + $cr = $this->getConnection(); + if(!is_resource($cr)) { + return false; + } + foreach($filters as $filter) { + if($lfw && count($foundItems) > 0) { + continue; + } + $rr = $this->ldap->search($cr, $base, $filter, array($attr)); + if(!$this->ldap->isResource($rr)) { + continue; + } + $entries = $this->ldap->countEntries($cr, $rr); + $getEntryFunc = 'firstEntry'; + if(($entries !== false) && ($entries > 0)) { + if(!is_null($maxF) && $entries > $maxEntries) { + $maxEntries = $entries; + $maxF = $filter; + } + do { + $entry = $this->ldap->$getEntryFunc($cr, $rr); + if(!$this->ldap->isResource($entry)) { + continue 2; + } + $attributes = $this->ldap->getAttributes($cr, $entry); + $dn = $this->ldap->getDN($cr, $entry); + if($dn === false || in_array($dn, $dnRead)) { + continue; + } + $newItems = array(); + $state = $this->getAttributeValuesFromEntry($attributes, + $attr, + $newItems); + $foundItems = array_merge($foundItems, $newItems); + $this->resultCache[$dn][$attr] = $newItems; + $dnRead[] = $dn; + $getEntryFunc = 'nextEntry'; + $rr = $entry; //will be expected by nextEntry next round + } while($state === self::LRESULT_PROCESSED_SKIP + || $this->ldap->isResource($entry)); + } + } + + return array_unique($foundItems); + } + + /** + * @brief determines if and which $attr are available on the LDAP server + * @param $objectclasses the objectclasses to use as search filter + * @param $attr the attribute to look for + * @param $dbkey the dbkey of the setting the feature is connected to + * @param $confkey the confkey counterpart for the $dbkey as used in the + * Configuration class + * @param $po boolean, whether the objectClass with most result entries + * shall be pre-selected via the result + * @returns array, list of found items. + */ + private function determineFeature($objectclasses, $attr, $dbkey, $confkey, $po = false) { + $cr = $this->getConnection(); + if(!$cr) { + throw new \Exception('Could not connect to LDAP'); + } + $p = 'objectclass='; + foreach($objectclasses as $key => $value) { + $objectclasses[$key] = $p.$value; + } + $maxEntryObjC = ''; + $availableFeatures = + $this->cumulativeSearchOnAttribute($objectclasses, $attr, + true, $maxEntryObjC); + if(is_array($availableFeatures) + && count($availableFeatures) > 0) { + natcasesort($availableFeatures); + //natcasesort keeps indices, but we must get rid of them for proper + //sorting in the web UI. Therefore: array_values + $this->result->addOptions($dbkey, array_values($availableFeatures)); + } else { + throw new \Exception(self::$l->t('Could not find the desired feature')); + } + + $setFeatures = $this->configuration->$confkey; + if(is_array($setFeatures) && !empty($setFeatures)) { + //something is already configured? pre-select it. + $this->result->addChange($dbkey, $setFeatures); + } else if($po && !empty($maxEntryObjC)) { + //pre-select objectclass with most result entries + $maxEntryObjC = str_replace($p, '', $maxEntryObjC); + $this->applyFind($dbkey, $maxEntryObjC); + $this->result->addChange($dbkey, $maxEntryObjC); + } + + return $availableFeatures; + } + + /** + * @brief appends a list of values fr + * @param $result resource, the return value from ldap_get_attributes + * @param $attribute string, the attribute values to look for + * @param &$known array, new values will be appended here + * @return int, state on of the class constants LRESULT_PROCESSED_OK, + * LRESULT_PROCESSED_INVALID or LRESULT_PROCESSED_SKIP + */ + private function getAttributeValuesFromEntry($result, $attribute, &$known) { + if(!is_array($result) + || !isset($result['count']) + || !$result['count'] > 0) { + return self::LRESULT_PROCESSED_INVALID; + } + + //strtolower on all keys for proper comparison + $result = \OCP\Util::mb_array_change_key_case($result); + $attribute = strtolower($attribute); + if(isset($result[$attribute])) { + foreach($result[$attribute] as $key => $val) { + if($key === 'count') { + continue; + } + if(!in_array($val, $known)) { + $known[] = $val; + } + } + return self::LRESULT_PROCESSED_OK; + } else { + return self::LRESULT_PROCESSED_SKIP; + } + } + + private function getConnection() { + if(!is_null($this->cr)) { + return $this->cr; + } + $cr = $this->ldap->connect( + $this->configuration->ldapHost.':'.$this->configuration->ldapPort, + $this->configuration->ldapPort); + + $this->ldap->setOption($cr, LDAP_OPT_PROTOCOL_VERSION, 3); + $this->ldap->setOption($cr, LDAP_OPT_NETWORK_TIMEOUT, self::LDAP_NW_TIMEOUT); + if($this->configuration->ldapTLS === 1) { + $this->ldap->startTls($cr); + } + + $lo = @$this->ldap->bind($cr, + $this->configuration->ldapAgentName, + $this->configuration->ldapAgentPassword); + if($lo === true) { + $this->$cr = $cr; + return $cr; + } + + return false; + } + + private function getDefaultLdapPortSettings() { + static $settings = array( + array('port' => 7636, 'tls' => false), + array('port' => 636, 'tls' => false), + array('port' => 7389, 'tls' => true), + array('port' => 389, 'tls' => true), + array('port' => 7389, 'tls' => false), + array('port' => 389, 'tls' => false), + ); + return $settings; + } + + private function getPortSettingsToTry() { + //389 ← LDAP / Unencrypted or StartTLS + //636 ← LDAPS / SSL + //7xxx ← UCS. need to be checked first, because both ports may be open + $host = $this->configuration->ldapHost; + $port = intval($this->configuration->ldapPort); + $portSettings = array(); + + //In case the port is already provided, we will check this first + if($port > 0) { + $hostInfo = parse_url($host); + if(!(is_array($hostInfo) + && isset($hostInfo['scheme']) + && stripos($hostInfo['scheme'], 'ldaps') !== false)) { + $portSettings[] = array('port' => $port, 'tls' => true); + } + $portSettings[] =array('port' => $port, 'tls' => false); + } + + //default ports + $portSettings = array_merge($portSettings, + $this->getDefaultLdapPortSettings()); + + return $portSettings; + } + + +}
\ No newline at end of file diff --git a/apps/user_ldap/lib/wizardresult.php b/apps/user_ldap/lib/wizardresult.php new file mode 100644 index 00000000000..542f106cad8 --- /dev/null +++ b/apps/user_ldap/lib/wizardresult.php @@ -0,0 +1,58 @@ +<?php + +/** + * ownCloud – LDAP Wizard Result + * + * @author Arthur Schiwon + * @copyright 2013 Arthur Schiwon blizzz@owncloud.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library 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 along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCA\user_ldap\lib; + +class WizardResult { + protected $changes = array(); + protected $options = array(); + protected $markedChange = false; + + public function addChange($key, $value) { + $this->changes[$key] = $value; + } + + public function markChange() { + $this->markedChange = true; + } + + public function addOptions($key, $values) { + if(!is_array($values)) { + $values = array($values); + } + $this->options[$key] = $values; + } + + public function hasChanges() { + return (count($this->changes) > 0 || $this->markedChange); + } + + public function getResultArray() { + $result = array(); + $result['changes'] = $this->changes; + if(count($this->options) > 0) { + $result['options'] = $this->options; + } + return $result; + } +}
\ No newline at end of file diff --git a/apps/user_ldap/settings.php b/apps/user_ldap/settings.php index b7070f23183..d077eafdde9 100644 --- a/apps/user_ldap/settings.php +++ b/apps/user_ldap/settings.php @@ -25,31 +25,50 @@ OC_Util::checkAdminUser(); -$params = array('ldap_host', 'ldap_port', 'ldap_backup_host', - 'ldap_backup_port', 'ldap_override_main_server', 'ldap_dn', - 'ldap_agent_password', 'ldap_base', 'ldap_base_users', - 'ldap_base_groups', 'ldap_userlist_filter', - 'ldap_login_filter', 'ldap_group_filter', 'ldap_display_name', - 'ldap_group_display_name', 'ldap_tls', - 'ldap_turn_off_cert_check', 'ldap_nocase', 'ldap_quota_def', - 'ldap_quota_attr', 'ldap_email_attr', - 'ldap_group_member_assoc_attribute', 'ldap_cache_ttl', - 'home_folder_naming_rule' - ); - -OCP\Util::addscript('user_ldap', 'settings'); -OCP\Util::addstyle('user_ldap', 'settings'); +OCP\Util::addScript('user_ldap', 'settings'); +OCP\Util::addScript('core', 'jquery.multiselect'); +OCP\Util::addStyle('user_ldap', 'settings'); +OCP\Util::addStyle('core', 'jquery.multiselect'); +OCP\Util::addStyle('core', 'jquery-ui-1.10.0.custom'); // fill template $tmpl = new OCP\Template('user_ldap', 'settings'); $prefixes = \OCA\user_ldap\lib\Helper::getServerConfigurationPrefixes(); $hosts = \OCA\user_ldap\lib\Helper::getServerConfigurationHosts(); -$tmpl->assign('serverConfigurationPrefixes', $prefixes); -$tmpl->assign('serverConfigurationHosts', $hosts); + +$wizardHtml = ''; +$toc = array(); + +$wControls = new OCP\Template('user_ldap', 'part.wizardcontrols'); +$wControls = $wControls->fetchPage(); +$sControls = new OCP\Template('user_ldap', 'part.settingcontrols'); +$sControls = $sControls->fetchPage(); + +$wizTabs = array(); +$wizTabs[] = array('tpl' => 'part.wizard-server', 'cap' => 'Server'); +$wizTabs[] = array('tpl' => 'part.wizard-userfilter', 'cap' => 'User Filter'); +$wizTabs[] = array('tpl' => 'part.wizard-loginfilter', 'cap' => 'Login Filter'); +$wizTabs[] = array('tpl' => 'part.wizard-groupfilter', 'cap' => 'Group Filter'); + +for($i = 0; $i < count($wizTabs); $i++) { + $tab = new OCP\Template('user_ldap', $wizTabs[$i]['tpl']); + if($i === 0) { + $tab->assign('serverConfigurationPrefixes', $prefixes); + $tab->assign('serverConfigurationHosts', $hosts); + } + $tab->assign('wizardControls', $wControls); + $wizardHtml .= $tab->fetchPage(); + $toc['#ldapWizard'.($i+1)] = $wizTabs[$i]['cap']; +} + +$tmpl->assign('tabs', $wizardHtml); +$tmpl->assign('toc', $toc); +$tmpl->assign('settingControls', $sControls); // assign default values -$defaults = \OCA\user_ldap\lib\Connection::getDefaults(); +$config = new \OCA\user_ldap\lib\Configuration('', false); +$defaults = $config->getDefaults(); foreach($defaults as $key => $default) { $tmpl->assign($key.'_default', $default); } diff --git a/apps/user_ldap/templates/part.settingcontrols.php b/apps/user_ldap/templates/part.settingcontrols.php new file mode 100644 index 00000000000..0cdb8ccf16f --- /dev/null +++ b/apps/user_ldap/templates/part.settingcontrols.php @@ -0,0 +1,12 @@ +<div class="ldapSettingControls"> + <input class="ldap_submit" value="<?php p($l->t('Save'));?>" type="submit"> + <button class="ldap_action_test_connection" name="ldap_action_test_connection"> + <?php p($l->t('Test Configuration'));?> + </button> + <a href="<?php p($theme->getDocBaseUrl()); ?>/server/5.0/admin_manual/auth_ldap.html" + target="_blank"> + <img src="<?php print_unescaped(OCP\Util::imagePath('', 'actions/info.png')); ?>" + style="height:1.75ex" /> + <?php p($l->t('Help'));?> + </a> +</div>
\ No newline at end of file diff --git a/apps/user_ldap/templates/part.wizard-groupfilter.php b/apps/user_ldap/templates/part.wizard-groupfilter.php new file mode 100644 index 00000000000..0cc4dfa572a --- /dev/null +++ b/apps/user_ldap/templates/part.wizard-groupfilter.php @@ -0,0 +1,42 @@ +<fieldset id="ldapWizard4"> + <div> + <p> + <?php p($l->t('Limit the access to %s to groups meeting this criteria:', $theme->getName()));?> + </p> + <p> + <label for="ldap_groupfilter_objectclass"> + <?php p($l->t('only those object classes:'));?> + </label> + + <select id="ldap_groupfilter_objectclass" multiple="multiple" + name="ldap_groupfilter_objectclass"> + </select> + </p> + <p> + <label for="ldap_groupfilter_groups"> + <?php p($l->t('only from those groups:'));?> + </label> + + <select id="ldap_groupfilter_groups" multiple="multiple" + name="ldap_groupfilter_groups"> + </select> + </p> + <p> + <label><a id='toggleRawGroupFilter'>↓ <?php p($l->t('Edit raw filter instead'));?></a></label> + </p> + <p id="rawGroupFilterContainer" class="invisible"> + <input type="text" id="ldap_group_filter" name="ldap_group_filter" + class="lwautosave" + placeholder="<?php p($l->t('Raw LDAP filter'));?>" + title="<?php p($l->t('The filter specifies which LDAP groups shall have access to the %s instance.', $theme->getName()));?>" + /> + </p> + <p> + <div class="ldapWizardInfo invisible"> </div> + </p> + <p> + <span id="ldap_group_count">0 <?php p($l->t('groups found'));?></span> + </p> + <?php print_unescaped($_['wizardControls']); ?> + </div> +</fieldset>
\ No newline at end of file diff --git a/apps/user_ldap/templates/part.wizard-loginfilter.php b/apps/user_ldap/templates/part.wizard-loginfilter.php new file mode 100644 index 00000000000..dc5d61e9f77 --- /dev/null +++ b/apps/user_ldap/templates/part.wizard-loginfilter.php @@ -0,0 +1,47 @@ +<fieldset id="ldapWizard3"> + <div> + <p> + <?php p($l->t('What attribute shall be used as login name:'));?> + </p> + <p> + <label for="ldap_loginfilter_username"> + <?php p($l->t('LDAP Username:'));?> + </label> + + <input type="checkbox" id="ldap_loginfilter_username" + name="ldap_loginfilter_username" value="1" class="lwautosave" /> + </p> + <p> + <label for="ldap_loginfilter_email"> + <?php p($l->t('LDAP Email Address:'));?> + </label> + + <input type="checkbox" id="ldap_loginfilter_email" + name="ldap_loginfilter_email" value="1" class="lwautosave" /> + </p> + <p> + <label for="ldap_loginfilter_attributes"> + <?php p($l->t('Other Attributes:'));?> + </label> + + <select id="ldap_loginfilter_attributes" multiple="multiple" + name="ldap_loginfilter_attributes"> + </select> + </p> + <p> + <label><a id='toggleRawLoginFilter'>↓ <?php p($l->t('Edit raw filter instead'));?></a></label> + </p> + <p id="rawLoginFilterContainer" class="invisible"> + <input type="text" id="ldap_login_filter" name="ldap_login_filter" + class="lwautosave" + placeholder="<?php p($l->t('Raw LDAP filter'));?>" + title="<?php p($l->t('Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: "uid=%%uid"'));?>" + /> + </p> + <p> + <div class="ldapWizardInfo invisible"> </div> + </p> + + <?php print_unescaped($_['wizardControls']); ?> + </div> +</fieldset>
\ No newline at end of file diff --git a/apps/user_ldap/templates/part.wizard-server.php b/apps/user_ldap/templates/part.wizard-server.php new file mode 100644 index 00000000000..0312c17ab7b --- /dev/null +++ b/apps/user_ldap/templates/part.wizard-server.php @@ -0,0 +1,71 @@ +<fieldset id="ldapWizard1"> + <p> + <select id="ldap_serverconfig_chooser" name="ldap_serverconfig_chooser"> + <?php if(count($_['serverConfigurationPrefixes']) === 0 ) { + ?> + <option value="" selected>1. Server</option>'); + <?php + } else { + $i = 1; + $sel = ' selected'; + foreach($_['serverConfigurationPrefixes'] as $prefix) { + ?> + <option value="<?php p($prefix); ?>"<?php p($sel); $sel = ''; ?>><?php p($i++); ?>. Server: <?php p($_['serverConfigurationHosts'][$prefix]); ?></option> + <?php + } + } + ?> + <option value="NEW"><?php p($l->t('Add Server Configuration'));?></option> + </select> + <button id="ldap_action_delete_configuration" + name="ldap_action_delete_configuration">Delete Configuration</button> + </p> + + <div class="hostPortCombinator"> + <div class="tablerow"> + <div class="tablecell"> + <div class="table"> + <input type="text" class="host tablecell lwautosave" id="ldap_host" + name="ldap_host" + placeholder="<?php p($l->t('Host'));?>" + title="<?php p($l->t('You can omit the protocol, except you require SSL. Then start with ldaps://'));?>" + /> + <span> + <input type="number" id="ldap_port" name="ldap_port" + class="lwautosave" + placeholder="<?php p($l->t('Port'));?>" /> + </span> + </div> + </div> + </div> + <div class="tablerow"> + <input type="text" id="ldap_dn" name="ldap_dn" + class="tablecell lwautosave" + placeholder="<?php p($l->t('User DN'));?>" autocomplete="off" + title="<?php p($l->t('The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty.'));?>" + /> + </div> + + <div class="tablerow"> + <input type="password" id="ldap_agent_password" + class="tablecell lwautosave" name="ldap_agent_password" + placeholder="<?php p($l->t('Password'));?>" autocomplete="off" + title="<?php p($l->t('For anonymous access, leave DN and Password empty.'));?>" + /> + </div> + + <div class="tablerow"> + <textarea id="ldap_base" name="ldap_base" + class="tablecell lwautosave" + placeholder="<?php p($l->t('One Base DN per line'));?>" + title="<?php p($l->t('You can specify Base DN for users and groups in the Advanced tab'));?>"> + </textarea> + </div> + + <div class="tablerow"> + <div class="tablecell ldapWizardInfo invisible"> + </div> + </div> + </div> + <?php print_unescaped($_['wizardControls']); ?> + </fieldset>
\ No newline at end of file diff --git a/apps/user_ldap/templates/part.wizard-userfilter.php b/apps/user_ldap/templates/part.wizard-userfilter.php new file mode 100644 index 00000000000..c1d522ce2a6 --- /dev/null +++ b/apps/user_ldap/templates/part.wizard-userfilter.php @@ -0,0 +1,42 @@ +<fieldset id="ldapWizard2"> + <div> + <p> + <?php p($l->t('Limit the access to %s to users meeting this criteria:', $theme->getName()));?> + </p> + <p> + <label for="ldap_userfilter_objectclass"> + <?php p($l->t('only those object classes:'));?> + </label> + + <select id="ldap_userfilter_objectclass" multiple="multiple" + name="ldap_userfilter_objectclass"> + </select> + </p> + <p> + <label for="ldap_userfilter_groups"> + <?php p($l->t('only from those groups:'));?> + </label> + + <select id="ldap_userfilter_groups" multiple="multiple" + name="ldap_userfilter_groups"> + </select> + </p> + <p> + <label><a id='toggleRawUserFilter'>↓ <?php p($l->t('Edit raw filter instead'));?></a></label> + </p> + <p id="rawUserFilterContainer" class="invisible"> + <input type="text" id="ldap_userlist_filter" name="ldap_userlist_filter" + class="lwautosave" + placeholder="<?php p($l->t('Raw LDAP filter'));?>" + title="<?php p($l->t('The filter specifies which LDAP users shall have access to the %s instance.', $theme->getName()));?>" + /> + </p> + <p> + <div class="ldapWizardInfo invisible"> </div> + </p> + <p> + <span id="ldap_user_count">0 <?php p($l->t('users found'));?></span> + </p> + <?php print_unescaped($_['wizardControls']); ?> + </div> +</fieldset>
\ No newline at end of file diff --git a/apps/user_ldap/templates/part.wizardcontrols.php b/apps/user_ldap/templates/part.wizardcontrols.php new file mode 100644 index 00000000000..f17b362c737 --- /dev/null +++ b/apps/user_ldap/templates/part.wizardcontrols.php @@ -0,0 +1,16 @@ +<div class="ldapWizardControls"> + <span class="ldap_config_state_indicator"></span> <span class="ldap_config_state_indicator_sign"></span> + <button class="ldap_action_back invisible" name="ldap_action_back" + type="button"> + <?php p($l->t('Back'));?> + </button> + <button class="ldap_action_continue" name="ldap_action_continue" type="button"> + <?php p($l->t('Continue'));?> + </button> + <a href="<?php p($theme->getDocBaseUrl()); ?>/server/5.0/admin_manual/auth_ldap.html" + target="_blank"> + <img src="<?php print_unescaped(OCP\Util::imagePath('', 'actions/info.png')); ?>" + style="height:1.75ex" /> + <span class="ldap_grey"><?php p($l->t('Help'));?></span> + </a> +</div>
\ No newline at end of file diff --git a/apps/user_ldap/templates/settings.php b/apps/user_ldap/templates/settings.php index e214d57fb1d..3ccc7a860f5 100644 --- a/apps/user_ldap/templates/settings.php +++ b/apps/user_ldap/templates/settings.php @@ -1,9 +1,11 @@ <form id="ldap" action="#" method="post"> <div id="ldapSettings" class="personalblock"> <ul> - <li><a href="#ldapSettings-1">LDAP Basic</a></li> - <li><a href="#ldapSettings-2">Advanced</a></li> - <li><a href="#ldapSettings-3">Expert</a></li> + <?php foreach($_['toc'] as $id => $title) { ?> + <li id="<?php p($id); ?>"><a href="<?php p($id); ?>"><?php p($title); ?></a></li> + <?php } ?> + <li class="ldapSettingsTabs"><a href="#ldapSettings-2">Expert</a></li> + <li class="ldapSettingsTabs"><a href="#ldapSettings-1">Advanced</a></li> </ul> <?php if(OCP\App::isEnabled('user_webdavauth')) { print_unescaped('<p class="ldapwarning">'.$l->t('<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them.').'</p>'); @@ -12,65 +14,15 @@ print_unescaped('<p class="ldapwarning">'.$l->t('<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it.').'</p>'); } ?> + <?php print_unescaped($_['tabs']); ?> <fieldset id="ldapSettings-1"> - <p><label for="ldap_serverconfig_chooser"><?php p($l->t('Server configuration'));?></label> - <select id="ldap_serverconfig_chooser" name="ldap_serverconfig_chooser"> - <?php if(count($_['serverConfigurationPrefixes']) === 0 ) { - ?> - <option value="" selected>1. Server</option>'); - <?php - } else { - $i = 1; - $sel = ' selected'; - foreach($_['serverConfigurationPrefixes'] as $prefix) { - ?> - <option value="<?php p($prefix); ?>"<?php p($sel); $sel = ''; ?>><?php p($i++); ?>. Server: <?php p($_['serverConfigurationHosts'][$prefix]); ?></option> - <?php - } - } - ?> - <option value="NEW"><?php p($l->t('Add Server Configuration'));?></option> - </select> - <button id="ldap_action_delete_configuration" - name="ldap_action_delete_configuration">Delete Configuration</button> - </p> - <p><label for="ldap_host"><?php p($l->t('Host'));?></label> - <input type="text" id="ldap_host" name="ldap_host" data-default="<?php p($_['ldap_host_default']); ?>" - title="<?php p($l->t('You can omit the protocol, except you require SSL. Then start with ldaps://'));?>"></p> - <p><label for="ldap_base"><?php p($l->t('Base DN'));?></label> - <textarea id="ldap_base" name="ldap_base" placeholder="<?php p($l->t('One Base DN per line'));?>" - title="<?php p($l->t('You can specify Base DN for users and groups in the Advanced tab'));?>" - data-default="<?php p($_['ldap_base_default']); ?>" ></textarea></p> - <p><label for="ldap_dn"><?php p($l->t('User DN'));?></label> - <input type="text" id="ldap_dn" name="ldap_dn" data-default="<?php p($_['ldap_dn_default']); ?>" - title="<?php p($l->t('The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty.'));?>" /></p> - <p><label for="ldap_agent_password"><?php p($l->t('Password'));?></label> - <input type="password" id="ldap_agent_password" name="ldap_agent_password" - data-default="<?php p($_['ldap_agent_password_default']); ?>" - title="<?php p($l->t('For anonymous access, leave DN and Password empty.'));?>" /></p> - <p><label for="ldap_login_filter"><?php p($l->t('User Login Filter'));?></label> - <input type="text" id="ldap_login_filter" name="ldap_login_filter" - data-default="<?php p($_['ldap_login_filter_default']); ?>" - title="<?php p($l->t('Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: "uid=%%uid"'));?>" /></p> - <p><label for="ldap_userlist_filter"><?php p($l->t('User List Filter'));?></label> - <input type="text" id="ldap_userlist_filter" name="ldap_userlist_filter" - data-default="<?php p($_['ldap_userlist_filter_default']); ?>" - title="<?php p($l->t('Defines the filter to apply, when retrieving users (no placeholders). Example: "objectClass=person"'));?>" /></p> - <p><label for="ldap_group_filter"><?php p($l->t('Group Filter'));?></label> - <input type="text" id="ldap_group_filter" name="ldap_group_filter" - data-default="<?php p($_['ldap_group_filter_default']); ?>" - title="<?php p($l->t('Defines the filter to apply, when retrieving groups (no placeholders). Example: "objectClass=posixGroup"'));?>" /></p> - </fieldset> - <fieldset id="ldapSettings-2"> <div id="ldapAdvancedAccordion"> <h3><?php p($l->t('Connection Settings'));?></h3> <div> <p><label for="ldap_configuration_active"><?php p($l->t('Configuration Active'));?></label><input type="checkbox" id="ldap_configuration_active" name="ldap_configuration_active" value="1" data-default="<?php p($_['ldap_configuration_active_default']); ?>" title="<?php p($l->t('When unchecked, this configuration will be skipped.'));?>" /></p> - <p><label for="ldap_port"><?php p($l->t('Port'));?></label><input type="number" id="ldap_port" name="ldap_port" data-default="<?php p($_['ldap_port_default']); ?>" /></p> <p><label for="ldap_backup_host"><?php p($l->t('Backup (Replica) Host'));?></label><input type="text" id="ldap_backup_host" name="ldap_backup_host" data-default="<?php p($_['ldap_backup_host_default']); ?>" title="<?php p($l->t('Give an optional backup host. It must be a replica of the main LDAP/AD server.'));?>"></p> <p><label for="ldap_backup_port"><?php p($l->t('Backup (Replica) Port'));?></label><input type="number" id="ldap_backup_port" name="ldap_backup_port" data-default="<?php p($_['ldap_backup_port_default']); ?>" /></p> <p><label for="ldap_override_main_server"><?php p($l->t('Disable Main Server'));?></label><input type="checkbox" id="ldap_override_main_server" name="ldap_override_main_server" value="1" data-default="<?php p($_['ldap_override_main_server_default']); ?>" title="<?php p($l->t('Only connect to the replica server.'));?>" /></p> - <p><label for="ldap_tls"><?php p($l->t('Use TLS'));?></label><input type="checkbox" id="ldap_tls" name="ldap_tls" value="1" data-default="<?php p($_['ldap_tls_default']); ?>" title="<?php p($l->t('Do not use it additionally for LDAPS connections, it will fail.'));?>" /></p> <p><label for="ldap_nocase"><?php p($l->t('Case insensitve LDAP server (Windows)'));?></label><input type="checkbox" id="ldap_nocase" name="ldap_nocase" data-default="<?php p($_['ldap_nocase_default']); ?>" value="1"<?php if (isset($_['ldap_nocase']) && ($_['ldap_nocase'])) p(' checked'); ?>></p> <p><label for="ldap_turn_off_cert_check"><?php p($l->t('Turn off SSL certificate validation.'));?></label><input type="checkbox" id="ldap_turn_off_cert_check" name="ldap_turn_off_cert_check" title="<?php p($l->t('Not recommended, use it for testing only! If connection only works with this option, import the LDAP server\'s SSL certificate in your %s server.', $theme->getName() ));?>" data-default="<?php p($_['ldap_turn_off_cert_check_default']); ?>" value="1"><br/></p> <p><label for="ldap_cache_ttl"><?php p($l->t('Cache Time-To-Live'));?></label><input type="number" id="ldap_cache_ttl" name="ldap_cache_ttl" title="<?php p($l->t('in seconds. A change empties the cache.'));?>" data-default="<?php p($_['ldap_cache_ttl_default']); ?>" /></p> @@ -93,19 +45,21 @@ <p><label for="home_folder_naming_rule"><?php p($l->t('User Home Folder Naming Rule'));?></label><input type="text" id="home_folder_naming_rule" name="home_folder_naming_rule" title="<?php p($l->t('Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute.'));?>" data-default="<?php p($_['home_folder_naming_rule_default']); ?>" /></p> </div> </div> + <?php print_unescaped($_['settingControls']); ?> </fieldset> - <fieldset id="ldapSettings-3"> + <fieldset id="ldapSettings-2"> <p><strong><?php p($l->t('Internal Username'));?></strong></p> <p class="ldapIndent"><?php p($l->t('By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. To achieve a similar behavior as before ownCloud 5 enter the user display name attribute in the following field. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users.'));?></p> <p class="ldapIndent"><label for="ldap_expert_username_attr"><?php p($l->t('Internal Username Attribute:'));?></label><input type="text" id="ldap_expert_username_attr" name="ldap_expert_username_attr" data-default="<?php p($_['ldap_expert_username_attr_default']); ?>" /></p> <p><strong><?php p($l->t('Override UUID detection'));?></strong></p> <p class="ldapIndent"><?php p($l->t('By default, the UUID attribute is automatically detected. The UUID attribute is used to doubtlessly identify LDAP users and groups. Also, the internal username will be created based on the UUID, if not specified otherwise above. You can override the setting and pass an attribute of your choice. You must make sure that the attribute of your choice can be fetched for both users and groups and it is unique. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users and groups.'));?></p> - <p class="ldapIndent"><label for="ldap_expert_uuid_attr"><?php p($l->t('UUID Attribute:'));?></label><input type="text" id="ldap_expert_uuid_attr" name="ldap_expert_uuid_attr" data-default="<?php p($_['ldap_expert_uuid_attr_default']); ?>" /></p> + <p class="ldapIndent"><label for="ldap_expert_uuid_user_attr"><?php p($l->t('UUID Attribute for Users:'));?></label><input type="text" id="ldap_expert_uuid_user_attr" name="ldap_expert_uuid_user_attr" data-default="<?php p($_['ldap_expert_uuid_user_attr_default']); ?>" /></p> + <p class="ldapIndent"><label for="ldap_expert_uuid_group_attr"><?php p($l->t('UUID Attribute for Groups:'));?></label><input type="text" id="ldap_expert_uuid_group_attr" name="ldap_expert_uuid_group_attr" data-default="<?php p($_['ldap_expert_uuid_group_attr_default']); ?>" /></p> <p><strong><?php p($l->t('Username-LDAP User Mapping'));?></strong></p> <p class="ldapIndent"><?php p($l->t('Usernames are used to store and assign (meta) data. In order to precisely identify and recognize users, each LDAP user will have a internal username. This requires a mapping from username to LDAP user. The created username is mapped to the UUID of the LDAP user. Additionally the DN is cached as well to reduce LDAP interaction, but it is not used for identification. If the DN changes, the changes will be found. The internal username is used all over. Clearing the mappings will have leftovers everywhere. Clearing the mappings is not configuration sensitive, it affects all LDAP configurations! Never clear the mappings in a production environment, only in a testing or experimental stage.'));?></p> <p class="ldapIndent"><button id="ldap_action_clear_user_mappings" name="ldap_action_clear_user_mappings"><?php p($l->t('Clear Username-LDAP User Mapping'));?></button><br/><button id="ldap_action_clear_group_mappings" name="ldap_action_clear_group_mappings"><?php p($l->t('Clear Groupname-LDAP Group Mapping'));?></button></p> + <?php print_unescaped($_['settingControls']); ?> </fieldset> - <input id="ldap_submit" type="submit" value="Save" /> <button id="ldap_action_test_connection" name="ldap_action_test_connection"><?php p($l->t('Test Configuration'));?></button> <a href="<?php p($theme->getDocBaseUrl()); ?>/server/5.0/admin_manual/auth_ldap.html" target="_blank"><img src="<?php print_unescaped(OCP\Util::imagePath('', 'actions/info.png')); ?>" style="height:1.75ex" /> <?php p($l->t('Help'));?></a> </div> </form> diff --git a/apps/user_ldap/tests/user_ldap.php b/apps/user_ldap/tests/user_ldap.php index 6b9b8b3e185..9193a005ae5 100644 --- a/apps/user_ldap/tests/user_ldap.php +++ b/apps/user_ldap/tests/user_ldap.php @@ -408,4 +408,58 @@ class Test_User_Ldap_Direct extends \PHPUnit_Framework_TestCase { //no test for getDisplayNames, because it just invokes getUsers and //getDisplayName + + public function testCountUsers() { + $access = $this->getAccessMock(); + + $access->connection->expects($this->once()) + ->method('__get') + ->will($this->returnCallback(function($name) { + if($name === 'ldapLoginFilter') { + return 'uid=%uid'; + } + return null; + })); + + $access->expects($this->once()) + ->method('countUsers') + ->will($this->returnCallback(function($filter, $a, $b, $c) { + if($filter !== 'uid=*') { + return false; + } + return 5; + })); + + $backend = new UserLDAP($access); + + $result = $backend->countUsers(); + $this->assertEquals(5, $result); + } + + public function testCountUsersFailing() { + $access = $this->getAccessMock(); + + $access->connection->expects($this->once()) + ->method('__get') + ->will($this->returnCallback(function($name) { + if($name === 'ldapLoginFilter') { + return 'invalidFilter'; + } + return null; + })); + + $access->expects($this->once()) + ->method('countUsers') + ->will($this->returnCallback(function($filter, $a, $b, $c) { + if($filter !== 'uid=*') { + return false; + } + return 5; + })); + + $backend = new UserLDAP($access); + + $result = $backend->countUsers(); + $this->assertFalse($result); + } }
\ No newline at end of file diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php index 6f52bbdf233..a19af86086c 100644 --- a/apps/user_ldap/user_ldap.php +++ b/apps/user_ldap/user_ldap.php @@ -70,6 +70,74 @@ class USER_LDAP extends BackendUtility implements \OCP\UserInterface { } /** + * @brief reads jpegPhoto and set is as avatar if available + * @param $uid string ownCloud user name + * @param $dn string the user's LDAP DN + * @return void + */ + private function updateAvatar($uid, $dn) { + $hasLoggedIn = \OCP\Config::getUserValue($uid, 'user_ldap', + 'firstLoginAccomplished', 0); + $lastChecked = \OCP\Config::getUserValue($uid, 'user_ldap', + 'lastJpegPhotoLookup', 0); + if(($hasLoggedIn !== '1') || (time() - intval($lastChecked)) < 86400 ) { + //update only once a day + return; + } + + $jpegPhoto = $this->access->readAttribute($dn, 'jpegPhoto'); + \OCP\Config::setUserValue($uid, 'user_ldap', 'lastJpegPhotoLookup', time()); + if(!$jpegPhoto || !is_array($jpegPhoto) || !isset($jpegPhoto[0])) { + //not set, nothing left to do; + return; + } + + $image = new \OCP\Image(); + $image->loadFromBase64(base64_encode($jpegPhoto[0])); + + if(!$image->valid()) { + \OCP\Util::writeLog('user_ldap', 'jpegPhoto data invalid for '.$dn, + \OCP\Util::ERROR); + return; + } + //make sure it is a square and not bigger than 128x128 + $size = min(array($image->width(), $image->height(), 128)); + if(!$image->centerCrop($size)) { + \OCP\Util::writeLog('user_ldap', + 'croping image for avatar failed for '.$dn, + \OCP\Util::ERROR); + return; + } + + if(!\OC\Files\Filesystem::$loaded) { + \OC_Util::setupFS($uid); + } + + $avatarManager = \OC::$server->getAvatarManager(); + $avatar = $avatarManager->getAvatar($uid); + $avatar->set($image); + } + + /** + * @brief checks whether the user is allowed to change his avatar in ownCloud + * @param $uid string the ownCloud user name + * @return boolean either the user can or cannot + */ + public function canChangeAvatar($uid) { + $dn = $this->access->username2dn($uid); + if(!$dn) { + return false; + } + $jpegPhoto = $this->access->readAttribute($dn, 'jpegPhoto'); + if(!$jpegPhoto || !is_array($jpegPhoto) || !isset($jpegPhoto[0])) { + //The user is allowed to change his avatar in ownCloud only if no + //avatar is provided by LDAP + return true; + } + return false; + } + + /** * @brief Check if the password is correct * @param $uid The username * @param $password The password @@ -100,6 +168,10 @@ class USER_LDAP extends BackendUtility implements \OCP\UserInterface { return false; } + \OCP\Config::setUserValue($ocname, 'user_ldap', + 'firstLoginAccomplished', 1); + + $this->updateAvatar($ocname, $dn); //give back the display name return $ocname; } @@ -173,6 +245,7 @@ class USER_LDAP extends BackendUtility implements \OCP\UserInterface { $this->access->connection->writeToCache('userExists'.$uid, true); $this->updateQuota($dn); + $this->updateAvatar($uid, $dn); return true; } @@ -289,7 +362,9 @@ class USER_LDAP extends BackendUtility implements \OCP\UserInterface { public function implementsActions($actions) { return (bool)((OC_USER_BACKEND_CHECK_PASSWORD | OC_USER_BACKEND_GET_HOME - | OC_USER_BACKEND_GET_DISPLAYNAME) + | OC_USER_BACKEND_GET_DISPLAYNAME + | OC_USER_BACKEND_PROVIDE_AVATAR + | OC_USER_BACKEND_COUNT_USERS) & $actions); } @@ -299,4 +374,16 @@ class USER_LDAP extends BackendUtility implements \OCP\UserInterface { public function hasUserListings() { return true; } + + /** + * counts the users in LDAP + * + * @return int | bool + */ + public function countUsers() { + $filter = \OCP\Util::mb_str_replace( + '%uid', '*', $this->access->connection->ldapLoginFilter, 'UTF-8'); + $entries = $this->access->countUsers($filter); + return $entries; + } } diff --git a/apps/user_ldap/user_proxy.php b/apps/user_ldap/user_proxy.php index 092fdbf7c78..5ad127197f3 100644 --- a/apps/user_ldap/user_proxy.php +++ b/apps/user_ldap/user_proxy.php @@ -54,6 +54,7 @@ class User_Proxy extends lib\Proxy implements \OCP\UserInterface { protected function walkBackends($uid, $method, $parameters) { $cacheKey = $this->getUserCacheKey($uid); foreach($this->backends as $configPrefix => $backend) { +// print("walkBackend '$configPrefix'<br/>"); if($result = call_user_func_array(array($backend, $method), $parameters)) { $this->writeToCache($cacheKey, $configPrefix); return $result; @@ -67,16 +68,17 @@ class User_Proxy extends lib\Proxy implements \OCP\UserInterface { * @param $uid string, the uid connected to the request * @param $method string, the method of the user backend that shall be called * @param $parameters an array of parameters to be passed + * @param $passOnWhen the result matches this variable * @return mixed, the result of the method or false */ - protected function callOnLastSeenOn($uid, $method, $parameters) { + protected function callOnLastSeenOn($uid, $method, $parameters, $passOnWhen) { $cacheKey = $this->getUserCacheKey($uid); $prefix = $this->getFromCache($cacheKey); //in case the uid has been found in the past, try this stored connection first if(!is_null($prefix)) { if(isset($this->backends[$prefix])) { $result = call_user_func_array(array($this->backends[$prefix], $method), $parameters); - if(!$result) { + if($result === $passOnWhen) { //not found here, reset cache to null if user vanished //because sometimes methods return false with a reason $userExists = call_user_func_array( @@ -164,6 +166,15 @@ class User_Proxy extends lib\Proxy implements \OCP\UserInterface { } /** + * @brief checks whether the user is allowed to change his avatar in ownCloud + * @param $uid string the ownCloud user name + * @return boolean either the user can or cannot + */ + public function canChangeAvatar($uid) { + return $this->handleRequest($uid, 'canChangeAvatar', array($uid), true); + } + + /** * @brief Get a list of all display names * @returns array with all displayNames (value) and the corresponding uids (key) * @@ -199,4 +210,19 @@ class User_Proxy extends lib\Proxy implements \OCP\UserInterface { return $this->refBackend->hasUserListings(); } + /** + * @brief Count the number of users + * @returns int | bool + */ + public function countUsers() { + $users = false; + foreach($this->backends as $backend) { + $backendUsers = $backend->countUsers(); + if ($backendUsers !== false) { + $users += $backendUsers; + } + } + return $users; + } + } diff --git a/apps/user_webdavauth/l10n/el.php b/apps/user_webdavauth/l10n/el.php index 4a9ab3bafcc..e7403f9a8c3 100644 --- a/apps/user_webdavauth/l10n/el.php +++ b/apps/user_webdavauth/l10n/el.php @@ -1,6 +1,6 @@ <?php $TRANSLATIONS = array( -"WebDAV Authentication" => "Αυθεντικοποίηση μέσω WebDAV ", +"WebDAV Authentication" => "Πιστοποίηση μέσω WebDAV ", "Address: " => "Διεύθυνση:", "The user credentials will be sent to this address. This plugin checks the response and will interpret the HTTP statuscodes 401 and 403 as invalid credentials, and all other responses as valid credentials." => "Τα διαπιστευτήρια του χρήστη θα σταλούν σε αυτή την διεύθυνση. Αυτό το πρόσθετο ελέγχει την απόκριση και θα ερμηνεύσει τους κωδικούς κατάστασης HTTP 401 και 402 ως μη έγκυρα διαπιστευτήρια και όλες τις άλλες αποκρίσεις ως έγκυρα διαπιστευτήρια." ); diff --git a/apps/user_webdavauth/l10n/eo.php b/apps/user_webdavauth/l10n/eo.php index ddcac32ca1b..3a82bfdf41e 100644 --- a/apps/user_webdavauth/l10n/eo.php +++ b/apps/user_webdavauth/l10n/eo.php @@ -1,5 +1,6 @@ <?php $TRANSLATIONS = array( -"WebDAV Authentication" => "WebDAV-aŭtentigo" +"WebDAV Authentication" => "WebDAV-aŭtentigo", +"Address: " => "Adreso:" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_webdavauth/l10n/es_MX.php b/apps/user_webdavauth/l10n/es_MX.php new file mode 100644 index 00000000000..951aabe24ae --- /dev/null +++ b/apps/user_webdavauth/l10n/es_MX.php @@ -0,0 +1,7 @@ +<?php +$TRANSLATIONS = array( +"WebDAV Authentication" => "Autenticación mediante WevDAV", +"Address: " => "Dirección:", +"The user credentials will be sent to this address. This plugin checks the response and will interpret the HTTP statuscodes 401 and 403 as invalid credentials, and all other responses as valid credentials." => "Las credenciales de usuario se enviarán a esta dirección. Este complemento verifica la respuesta e interpretará los códigos de respuesta HTTP 401 y 403 como credenciales inválidas y todas las otras respuestas como credenciales válidas." +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_webdavauth/l10n/et_EE.php b/apps/user_webdavauth/l10n/et_EE.php index 34b07c654a5..2727cc98dc9 100644 --- a/apps/user_webdavauth/l10n/et_EE.php +++ b/apps/user_webdavauth/l10n/et_EE.php @@ -2,6 +2,6 @@ $TRANSLATIONS = array( "WebDAV Authentication" => "WebDAV autentimine", "Address: " => "Aadress:", -"The user credentials will be sent to this address. This plugin checks the response and will interpret the HTTP statuscodes 401 and 403 as invalid credentials, and all other responses as valid credentials." => "ownCloud saadab kasutajatunnused sellel aadressil. See vidin kontrollib vastust ning tuvastab HTTP vastuskoodid 401 ja 403 kui vigased, ning kõik teised vastused kui korrektsed kasutajatunnused." +"The user credentials will be sent to this address. This plugin checks the response and will interpret the HTTP statuscodes 401 and 403 as invalid credentials, and all other responses as valid credentials." => "ownCloud saadab kasutajatunnused sellel aadressil. See vidin kontrollib vastust ning tuvastab ning tõlgendab HTTP olekukoodid 401 ja 403 valedeks andmeteks ning kõik teised vastused korrektseteks andmeteks." ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/user_webdavauth/l10n/ko.php b/apps/user_webdavauth/l10n/ko.php index 2d2c4d70e73..19565f28522 100644 --- a/apps/user_webdavauth/l10n/ko.php +++ b/apps/user_webdavauth/l10n/ko.php @@ -1,5 +1,7 @@ <?php $TRANSLATIONS = array( -"WebDAV Authentication" => "WebDAV 인증" +"WebDAV Authentication" => "WebDAV 인증", +"Address: " => "주소:", +"The user credentials will be sent to this address. This plugin checks the response and will interpret the HTTP statuscodes 401 and 403 as invalid credentials, and all other responses as valid credentials." => "ownCloud에서 이 URL로 사용자 인증 정보를 보냅니다. 이 플러그인은 응답을 확인하여 HTTP 상태 코드 401이나 403이 돌아온 경우에 잘못된 인증 정보로 간주합니다. 다른 모든 상태 코드는 올바른 인증 정보로 간주합니다." ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/user_webdavauth/l10n/mk.php b/apps/user_webdavauth/l10n/mk.php index 245a5101341..6ebe36423b2 100644 --- a/apps/user_webdavauth/l10n/mk.php +++ b/apps/user_webdavauth/l10n/mk.php @@ -1,3 +1,5 @@ -<?php $TRANSLATIONS = array( -"URL: http://" => "URL: http://" +<?php +$TRANSLATIONS = array( +"Address: " => "Адреса:" ); +$PLURAL_FORMS = "nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;"; diff --git a/apps/user_webdavauth/l10n/ms_MY.php b/apps/user_webdavauth/l10n/ms_MY.php new file mode 100644 index 00000000000..a9266aa56ca --- /dev/null +++ b/apps/user_webdavauth/l10n/ms_MY.php @@ -0,0 +1,7 @@ +<?php +$TRANSLATIONS = array( +"WebDAV Authentication" => "Pengesahan ", +"Address: " => "Alamat:", +"The user credentials will be sent to this address. This plugin checks the response and will interpret the HTTP statuscodes 401 and 403 as invalid credentials, and all other responses as valid credentials." => "Butiran pengguna akan dihantar ke alamat ini. Plugin ini memeriksa maklum balas dan akan mentafsir kod status HTTP 401 dan 403 sebagai butiran tidak sah, dan semua maklum balas lain sebagai butiran yang sah." +); +$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/user_webdavauth/l10n/sl.php b/apps/user_webdavauth/l10n/sl.php index f58232b37bd..3bf3068c55f 100644 --- a/apps/user_webdavauth/l10n/sl.php +++ b/apps/user_webdavauth/l10n/sl.php @@ -1,5 +1,7 @@ <?php $TRANSLATIONS = array( -"WebDAV Authentication" => "Overitev WebDAV" +"WebDAV Authentication" => "Overitev WebDAV", +"Address: " => "Naslov:", +"The user credentials will be sent to this address. This plugin checks the response and will interpret the HTTP statuscodes 401 and 403 as invalid credentials, and all other responses as valid credentials." => "Uporabniška poverila bodo poslana na naveden naslov. Vstavek preveri odziv in kodi stanja 401 in 403 obravnava kot neveljavna poverila, vse ostale odzive pa kot veljavna." ); $PLURAL_FORMS = "nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);"; diff --git a/apps/user_webdavauth/l10n/tr.php b/apps/user_webdavauth/l10n/tr.php index 907fb88b864..0ca8b0ad55f 100644 --- a/apps/user_webdavauth/l10n/tr.php +++ b/apps/user_webdavauth/l10n/tr.php @@ -1,5 +1,7 @@ <?php $TRANSLATIONS = array( -"WebDAV Authentication" => "WebDAV Kimlik doğrulaması" +"WebDAV Authentication" => "WebDAV Kimlik doğrulaması", +"Address: " => "Adres:", +"The user credentials will be sent to this address. This plugin checks the response and will interpret the HTTP statuscodes 401 and 403 as invalid credentials, and all other responses as valid credentials." => "Kullanıcı kimlik bilgileri bu adrese gönderilecek. Bu eklenti yanıtı kontrol edecek ve 401 ile 403 HTTP durum kodlarını geçersiz kimlik bilgileri olarak, diğer yanıtları ise doğru kimlik bilgileri olarak algılayacaktır." ); $PLURAL_FORMS = "nplurals=2; plural=(n > 1);"; diff --git a/apps/user_webdavauth/l10n/uk.php b/apps/user_webdavauth/l10n/uk.php index dff8b308c5d..00d26cb252c 100644 --- a/apps/user_webdavauth/l10n/uk.php +++ b/apps/user_webdavauth/l10n/uk.php @@ -1,6 +1,7 @@ <?php $TRANSLATIONS = array( "WebDAV Authentication" => "Аутентифікація WebDAV", -"Address: " => "Адреса:" +"Address: " => "Адреса:", +"The user credentials will be sent to this address. This plugin checks the response and will interpret the HTTP statuscodes 401 and 403 as invalid credentials, and all other responses as valid credentials." => "Облікові дані користувача буде надіслано на цю адресу. Цей плагін перевіряє відповідь і буде інтерпретувати коди статусу HTTP 401 і 403, як неправильні облікові дані, а всі інші відповіді, вважатимуться правильними." ); $PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"; diff --git a/apps/user_webdavauth/l10n/zh_HK.php b/apps/user_webdavauth/l10n/zh_HK.php new file mode 100644 index 00000000000..61a0270fb70 --- /dev/null +++ b/apps/user_webdavauth/l10n/zh_HK.php @@ -0,0 +1,7 @@ +<?php +$TRANSLATIONS = array( +"WebDAV Authentication" => "WebDAV 認證", +"Address: " => "位址:", +"The user credentials will be sent to this address. This plugin checks the response and will interpret the HTTP statuscodes 401 and 403 as invalid credentials, and all other responses as valid credentials." => "使用者憑證將會被傳送到此位址。此外掛程式將會檢查回應,HTTP狀態碼 401與403將會被理解為無效憑證,而所有其他的回應將會被理解為有效憑證。" +); +$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/user_webdavauth/l10n/zh_TW.php b/apps/user_webdavauth/l10n/zh_TW.php index 013a1652f32..61a0270fb70 100644 --- a/apps/user_webdavauth/l10n/zh_TW.php +++ b/apps/user_webdavauth/l10n/zh_TW.php @@ -1,7 +1,7 @@ <?php $TRANSLATIONS = array( "WebDAV Authentication" => "WebDAV 認證", -"Address: " => "為址", -"The user credentials will be sent to this address. This plugin checks the response and will interpret the HTTP statuscodes 401 and 403 as invalid credentials, and all other responses as valid credentials." => "使用者憑證將會被傳送到此位址。此外掛程式將會檢查回應,HTTP statuscodes 401與403將會被理解為無效憑證,而所有其他的回應將會被理解為有效憑證。" +"Address: " => "位址:", +"The user credentials will be sent to this address. This plugin checks the response and will interpret the HTTP statuscodes 401 and 403 as invalid credentials, and all other responses as valid credentials." => "使用者憑證將會被傳送到此位址。此外掛程式將會檢查回應,HTTP狀態碼 401與403將會被理解為無效憑證,而所有其他的回應將會被理解為有效憑證。" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; |