diff options
266 files changed, 7146 insertions, 1905 deletions
diff --git a/apps/accessibility/lib/Controller/AccessibilityController.php b/apps/accessibility/lib/Controller/AccessibilityController.php index 5a5ff5b8a2f..6d0684cd439 100644 --- a/apps/accessibility/lib/Controller/AccessibilityController.php +++ b/apps/accessibility/lib/Controller/AccessibilityController.php @@ -258,7 +258,7 @@ class AccessibilityController extends Controller { * @return string */ private function invertSvgIconsColor(string $css) { - return str_replace(['/000', '/fff', '/***'], ['/***', '/000', '/fff'], $css); + return str_replace(['color=000', 'color=fff', 'color=***'], ['color=***', 'color=000', 'color=fff'], $css); } /** diff --git a/apps/dav/lib/CalDAV/Schedule/IMipPlugin.php b/apps/dav/lib/CalDAV/Schedule/IMipPlugin.php index 6f303acba33..3ff3ed0c569 100644 --- a/apps/dav/lib/CalDAV/Schedule/IMipPlugin.php +++ b/apps/dav/lib/CalDAV/Schedule/IMipPlugin.php @@ -170,7 +170,7 @@ class IMipPlugin extends SabreIMipPlugin { $vevent = $iTipMessage->message->VEVENT; $attendee = $this->getCurrentAttendee($iTipMessage); - $defaultLang = $this->config->getUserValue($this->userId, 'core', 'lang', $this->l10nFactory->findLanguage()); + $defaultLang = $this->l10nFactory->findLanguage(); $lang = $this->getAttendeeLangOrDefault($defaultLang, $attendee); $l10n = $this->l10nFactory->get('dav', $lang); diff --git a/apps/dav/lib/CardDAV/AddressBookImpl.php b/apps/dav/lib/CardDAV/AddressBookImpl.php index 5034b16ed2f..1aedd5d5643 100644 --- a/apps/dav/lib/CardDAV/AddressBookImpl.php +++ b/apps/dav/lib/CardDAV/AddressBookImpl.php @@ -88,16 +88,26 @@ class AddressBookImpl implements IAddressBook { /** * @param string $pattern which should match within the $searchProperties * @param array $searchProperties defines the properties within the query pattern should match - * @param array $options - for future use. One should always have options! + * @param array $options Options to define the output format + * - types boolean (since 15.0.0) If set to true, fields that come with a TYPE property will be an array + * example: ['id' => 5, 'FN' => 'Thomas Tanghus', 'EMAIL' => ['type => 'HOME', 'value' => 'g@h.i']] + * @return array an array of contacts which are arrays of key-value-pairs + * example result: + * [ + * ['id' => 0, 'FN' => 'Thomas Müller', 'EMAIL' => 'a@b.c', 'GEO' => '37.386013;-122.082932'], + * ['id' => 5, 'FN' => 'Thomas Tanghus', 'EMAIL' => ['d@e.f', 'g@h.i']] + * ] * @return array an array of contacts which are arrays of key-value-pairs * @since 5.0.0 */ public function search($pattern, $searchProperties, $options) { $results = $this->backend->search($this->getKey(), $pattern, $searchProperties); + $withTypes = \array_key_exists('types', $options) && $options['types'] === true; + $vCards = []; foreach ($results as $result) { - $vCards[] = $this->vCard2Array($result['uri'], $this->readCard($result['carddata'])); + $vCards[] = $this->vCard2Array($result['uri'], $this->readCard($result['carddata']), $withTypes); } return $vCards; @@ -220,7 +230,7 @@ class AddressBookImpl implements IAddressBook { * @param VCard $vCard * @return array */ - protected function vCard2Array($uri, VCard $vCard) { + protected function vCard2Array($uri, VCard $vCard, $withTypes = false) { $result = [ 'URI' => $uri, ]; @@ -255,15 +265,28 @@ class AddressBookImpl implements IAddressBook { $result[$property->name] = []; } - $result[$property->name][] = $property->getValue(); + $type = $this->getTypeFromProperty($property); + if ($withTypes) { + $result[$property->name][] = [ + 'type' => $type, + 'value' => $property->getValue() + ]; + } else { + $result[$property->name][] = $property->getValue(); + } + } else { $result[$property->name] = $property->getValue(); } } - if ($this->addressBookInfo['principaluri'] === 'principals/system/system' && - $this->addressBookInfo['uri'] === 'system') { + if ( + $this->addressBookInfo['principaluri'] === 'principals/system/system' && ( + $this->addressBookInfo['uri'] === 'system' || + $this->addressBookInfo['{DAV:}displayname'] === $this->urlGenerator->getBaseUrl() + ) + ) { $result['isLocalSystemBook'] = true; } return $result; diff --git a/apps/dav/lib/Connector/Sabre/File.php b/apps/dav/lib/Connector/Sabre/File.php index 9e927ff85e5..57c072fda47 100644 --- a/apps/dav/lib/Connector/Sabre/File.php +++ b/apps/dav/lib/Connector/Sabre/File.php @@ -164,14 +164,19 @@ class File extends Node implements IFile { $this->changeLock(ILockingProvider::LOCK_EXCLUSIVE); } - $target = $partStorage->fopen($internalPartPath, 'wb'); - if ($target === false) { - \OC::$server->getLogger()->error('\OC\Files\Filesystem::fopen() failed', ['app' => 'webdav']); - // because we have no clue about the cause we can only throw back a 500/Internal Server Error - throw new Exception('Could not write file contents'); + if ($partStorage->instanceOfStorage(Storage\IWriteStreamStorage::class)) { + $count = $partStorage->writeStream($internalPartPath, $data); + $result = $count > 0; + } else { + $target = $partStorage->fopen($internalPartPath, 'wb'); + if ($target === false) { + \OC::$server->getLogger()->error('\OC\Files\Filesystem::fopen() failed', ['app' => 'webdav']); + // because we have no clue about the cause we can only throw back a 500/Internal Server Error + throw new Exception('Could not write file contents'); + } + list($count, $result) = \OC_Helper::streamCopy($data, $target); + fclose($target); } - list($count, $result) = \OC_Helper::streamCopy($data, $target); - fclose($target); if ($result === false) { $expected = -1; @@ -185,7 +190,7 @@ class File extends Node implements IFile { // double check if the file was fully received // compare expected and actual size if (isset($_SERVER['CONTENT_LENGTH']) && $_SERVER['REQUEST_METHOD'] === 'PUT') { - $expected = (int) $_SERVER['CONTENT_LENGTH']; + $expected = (int)$_SERVER['CONTENT_LENGTH']; if ($count !== $expected) { throw new BadRequest('expected filesize ' . $expected . ' got ' . $count); } @@ -219,7 +224,7 @@ class File extends Node implements IFile { $renameOkay = $storage->moveFromStorage($partStorage, $internalPartPath, $internalPath); $fileExists = $storage->file_exists($internalPath); if ($renameOkay === false || $fileExists === false) { - \OC::$server->getLogger()->error('renaming part file to final file failed ($run: ' . ( $run ? 'true' : 'false' ) . ', $renameOkay: ' . ( $renameOkay ? 'true' : 'false' ) . ', $fileExists: ' . ( $fileExists ? 'true' : 'false' ) . ')', ['app' => 'webdav']); + \OC::$server->getLogger()->error('renaming part file to final file failed $renameOkay: ' . ($renameOkay ? 'true' : 'false') . ', $fileExists: ' . ($fileExists ? 'true' : 'false') . ')', ['app' => 'webdav']); throw new Exception('Could not rename part file to final file'); } } catch (ForbiddenException $ex) { @@ -246,7 +251,7 @@ class File extends Node implements IFile { $this->header('X-OC-MTime: accepted'); } } - + if ($view) { $this->emitPostHooks($exists); } @@ -443,7 +448,7 @@ class File extends Node implements IFile { //detect aborted upload if (isset ($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'PUT') { if (isset($_SERVER['CONTENT_LENGTH'])) { - $expected = (int) $_SERVER['CONTENT_LENGTH']; + $expected = (int)$_SERVER['CONTENT_LENGTH']; if ($bytesWritten !== $expected) { $chunk_handler->remove($info['index']); throw new BadRequest( diff --git a/apps/dav/tests/unit/Connector/Sabre/FileTest.php b/apps/dav/tests/unit/Connector/Sabre/FileTest.php index 5e7a6374206..edb61edc6ed 100644 --- a/apps/dav/tests/unit/Connector/Sabre/FileTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/FileTest.php @@ -164,7 +164,7 @@ class FileTest extends \Test\TestCase { public function testSimplePutFails($thrownException, $expectedException, $checkPreviousClass = true) { // setup $storage = $this->getMockBuilder(Local::class) - ->setMethods(['fopen']) + ->setMethods(['writeStream']) ->setConstructorArgs([['datadir' => \OC::$server->getTempManager()->getTemporaryFolder()]]) ->getMock(); \OC\Files\Filesystem::mount($storage, [], $this->user . '/'); @@ -182,11 +182,11 @@ class FileTest extends \Test\TestCase { if ($thrownException !== null) { $storage->expects($this->once()) - ->method('fopen') + ->method('writeStream') ->will($this->throwException($thrownException)); } else { $storage->expects($this->once()) - ->method('fopen') + ->method('writeStream') ->will($this->returnValue(false)); } diff --git a/apps/files/css/files.scss b/apps/files/css/files.scss index a643cb6258f..580bab32d6d 100644 --- a/apps/files/css/files.scss +++ b/apps/files/css/files.scss @@ -316,6 +316,7 @@ table td.filename .thumbnail { background-size: 32px; margin-left: 9px; margin-top: 9px; + border-radius: var(--border-radius); cursor: pointer; position: absolute; z-index: 4; @@ -755,7 +756,8 @@ table.dragshadow td.size { row-gap: 15px; margin: 15px 0; - tr { + // ensure search still filters tr with .hidden + tr:not(.hidden) { display: block; position: relative; height: $grid-size + 44px - $grid-pad; diff --git a/apps/files/js/detailsview.js b/apps/files/js/detailsview.js index cd602961c0a..bac2a5ebd21 100644 --- a/apps/files/js/detailsview.js +++ b/apps/files/js/detailsview.js @@ -174,6 +174,9 @@ // hide other tabs $tabsContainer.find('.tab').addClass('hidden'); + $tabsContainer.attr('class', 'tabsContainer'); + $tabsContainer.addClass(tabView.getTabsContainerExtraClasses()); + // tab already rendered ? if (!$tabEl.length) { // render tab diff --git a/apps/files/js/detailtabview.js b/apps/files/js/detailtabview.js index a66cedbc15d..1e046f30246 100644 --- a/apps/files/js/detailtabview.js +++ b/apps/files/js/detailtabview.js @@ -41,6 +41,21 @@ }, /** + * Returns the extra CSS classes used by the tabs container when this + * tab is the selected one. + * + * In general you should not extend this method, as tabs should not + * modify the classes of its container; this is reserved as a last + * resort for very specific cases in which there is no other way to get + * the proper style or behaviour. + * + * @return {String} space-separated CSS classes + */ + getTabsContainerExtraClasses: function() { + return ''; + }, + + /** * Returns the tab label * * @return {String} label diff --git a/apps/files/l10n/cs.js b/apps/files/l10n/cs.js index cbd6c72d572..96b93d361e7 100644 --- a/apps/files/l10n/cs.js +++ b/apps/files/l10n/cs.js @@ -142,6 +142,7 @@ OC.L10N.register( "WebDAV" : "WebDAV", "Use this address to <a href=\"%s\" target=\"_blank\" rel=\"noreferrer noopener\">access your Files via WebDAV</a>" : "Použijte tuto adresu pro <a href=\"%s\" target=\"_blank\" rel=\"noreferrer noopener\">přístup k vašim souborům přes WebDAV</a>", "Cancel upload" : "Zrušit nahrávání", + "Toggle grid view" : "Přepnout zobrazení mřížky", "No files in here" : "Žádné soubory", "Upload some content or sync with your devices!" : "Nahrajte nějaký obsah nebo synchronizujte se svými přístroji!", "No entries found in this folder" : "V této složce nebylo nic nalezeno", diff --git a/apps/files/l10n/cs.json b/apps/files/l10n/cs.json index a8f82c5c5d7..cb01165503d 100644 --- a/apps/files/l10n/cs.json +++ b/apps/files/l10n/cs.json @@ -140,6 +140,7 @@ "WebDAV" : "WebDAV", "Use this address to <a href=\"%s\" target=\"_blank\" rel=\"noreferrer noopener\">access your Files via WebDAV</a>" : "Použijte tuto adresu pro <a href=\"%s\" target=\"_blank\" rel=\"noreferrer noopener\">přístup k vašim souborům přes WebDAV</a>", "Cancel upload" : "Zrušit nahrávání", + "Toggle grid view" : "Přepnout zobrazení mřížky", "No files in here" : "Žádné soubory", "Upload some content or sync with your devices!" : "Nahrajte nějaký obsah nebo synchronizujte se svými přístroji!", "No entries found in this folder" : "V této složce nebylo nic nalezeno", diff --git a/apps/files_external/js/app.js b/apps/files_external/js/app.js index d3f738dcf8a..4406882cd21 100644 --- a/apps/files_external/js/app.js +++ b/apps/files_external/js/app.js @@ -8,16 +8,16 @@ * */ -if (!OCA.External) { +if (!OCA.Files_External) { /** * @namespace */ - OCA.External = {}; + OCA.Files_External = {}; } /** * @namespace */ -OCA.External.App = { +OCA.Files_External.App = { fileList: null, @@ -26,7 +26,7 @@ OCA.External.App = { return this.fileList; } - this.fileList = new OCA.External.FileList( + this.fileList = new OCA.Files_External.FileList( $el, { fileActions: this._createFileActions() @@ -67,10 +67,10 @@ OCA.External.App = { $(document).ready(function() { $('#app-content-extstoragemounts').on('show', function(e) { - OCA.External.App.initList($(e.target)); + OCA.Files_External.App.initList($(e.target)); }); $('#app-content-extstoragemounts').on('hide', function() { - OCA.External.App.removeList(); + OCA.Files_External.App.removeList(); }); /* Status Manager */ @@ -82,27 +82,27 @@ $(document).ready(function() { if (e.dir === '/') { var mount_point = e.previousDir.split('/', 2)[1]; // Every time that we return to / root folder from a mountpoint, mount_point status is rechecked - OCA.External.StatusManager.getMountPointList(function() { - OCA.External.StatusManager.recheckConnectivityForMount([mount_point], true); + OCA.Files_External.StatusManager.getMountPointList(function() { + OCA.Files_External.StatusManager.recheckConnectivityForMount([mount_point], true); }); } }) .on('fileActionsReady', function(e){ if ($.isArray(e.$files)) { - if (OCA.External.StatusManager.mountStatus === null || - OCA.External.StatusManager.mountPointList === null || - _.size(OCA.External.StatusManager.mountStatus) !== _.size(OCA.External.StatusManager.mountPointList)) { + if (OCA.Files_External.StatusManager.mountStatus === null || + OCA.Files_External.StatusManager.mountPointList === null || + _.size(OCA.Files_External.StatusManager.mountStatus) !== _.size(OCA.Files_External.StatusManager.mountPointList)) { // Will be the very first check when the files view will be loaded - OCA.External.StatusManager.launchFullConnectivityCheckOneByOne(); + OCA.Files_External.StatusManager.launchFullConnectivityCheckOneByOne(); } else { // When we change between general files view and external files view - OCA.External.StatusManager.getMountPointList(function(){ + OCA.Files_External.StatusManager.getMountPointList(function(){ var fileNames = []; $.each(e.$files, function(key, value){ fileNames.push(value.attr('data-file')); }); // Recheck if launched but work from cache - OCA.External.StatusManager.recheckConnectivityForMount(fileNames, false); + OCA.Files_External.StatusManager.recheckConnectivityForMount(fileNames, false); }); } } diff --git a/apps/files_external/js/mountsfilelist.js b/apps/files_external/js/mountsfilelist.js index 90b90e38745..034c29c05c2 100644 --- a/apps/files_external/js/mountsfilelist.js +++ b/apps/files_external/js/mountsfilelist.js @@ -10,7 +10,7 @@ (function() { /** - * @class OCA.External.FileList + * @class OCA.Files_External.FileList * @augments OCA.Files.FileList * * @classdesc External storage file list. @@ -27,7 +27,7 @@ }; FileList.prototype = _.extend({}, OCA.Files.FileList.prototype, - /** @lends OCA.External.FileList.prototype */ { + /** @lends OCA.Files_External.FileList.prototype */ { appName: 'External storages', _allowSelection: false, @@ -43,7 +43,7 @@ }, /** - * @param {OCA.External.MountPointInfo} fileData + * @param {OCA.Files_External.MountPointInfo} fileData */ _createRow: function(fileData) { // TODO: hook earlier and render the whole row here @@ -138,12 +138,12 @@ /** * Mount point info attributes. * - * @typedef {Object} OCA.External.MountPointInfo + * @typedef {Object} OCA.Files_External.MountPointInfo * * @property {String} name mount point name * @property {String} scope mount point scope "personal" or "system" * @property {String} backend external storage backend name */ - OCA.External.FileList = FileList; + OCA.Files_External.FileList = FileList; })(); diff --git a/apps/files_external/js/oauth1.js b/apps/files_external/js/oauth1.js index 79248a3e3b2..56e674b213b 100644 --- a/apps/files_external/js/oauth1.js +++ b/apps/files_external/js/oauth1.js @@ -4,7 +4,7 @@ $(document).ready(function() { $tr.find('.configuration input.auth-param').attr('disabled', 'disabled').addClass('disabled-success'); } - OCA.External.Settings.mountConfig.whenSelectAuthMechanism(function($tr, authMechanism, scheme, onCompletion) { + OCA.Files_External.Settings.mountConfig.whenSelectAuthMechanism(function($tr, authMechanism, scheme, onCompletion) { if (authMechanism === 'oauth1::oauth1') { var config = $tr.find('.configuration'); config.append($(document.createElement('input')) @@ -34,7 +34,7 @@ $(document).ready(function() { $(token).val(result.access_token); $(token_secret).val(result.access_token_secret); $(configured).val('true'); - OCA.External.Settings.mountConfig.saveStorageConfig($tr, function(status) { + OCA.Files_External.Settings.mountConfig.saveStorageConfig($tr, function(status) { if (status) { displayGranted($tr); } @@ -64,7 +64,7 @@ $(document).ready(function() { $(configured).val('false'); $(token).val(result.data.request_token); $(token_secret).val(result.data.request_token_secret); - OCA.External.Settings.mountConfig.saveStorageConfig(tr, function() { + OCA.Files_External.Settings.mountConfig.saveStorageConfig(tr, function() { window.location = result.data.url; }); } else { diff --git a/apps/files_external/js/oauth2.js b/apps/files_external/js/oauth2.js index 13b5162694e..fb7160d6684 100644 --- a/apps/files_external/js/oauth2.js +++ b/apps/files_external/js/oauth2.js @@ -4,7 +4,7 @@ $(document).ready(function() { $tr.find('.configuration input.auth-param').attr('disabled', 'disabled').addClass('disabled-success'); } - OCA.External.Settings.mountConfig.whenSelectAuthMechanism(function($tr, authMechanism, scheme, onCompletion) { + OCA.Files_External.Settings.mountConfig.whenSelectAuthMechanism(function($tr, authMechanism, scheme, onCompletion) { if (authMechanism === 'oauth2::oauth2') { var config = $tr.find('.configuration'); config.append($(document.createElement('input')) @@ -43,7 +43,7 @@ $(document).ready(function() { if (result && result.status == 'success') { $(token).val(result.data.token); $(configured).val('true'); - OCA.External.Settings.mountConfig.saveStorageConfig($tr, function(status) { + OCA.Files_External.Settings.mountConfig.saveStorageConfig($tr, function(status) { if (status) { displayGranted($tr); } @@ -80,7 +80,7 @@ $(document).ready(function() { if (result && result.status == 'success') { $(configured).val('false'); $(token).val('false'); - OCA.External.Settings.mountConfig.saveStorageConfig(tr, function(status) { + OCA.Files_External.Settings.mountConfig.saveStorageConfig(tr, function(status) { window.location = result.data.url; }); } else { diff --git a/apps/files_external/js/public_key.js b/apps/files_external/js/public_key.js index 6856c7d021f..9b9ca6038c8 100644 --- a/apps/files_external/js/public_key.js +++ b/apps/files_external/js/public_key.js @@ -1,6 +1,6 @@ $(document).ready(function() { - OCA.External.Settings.mountConfig.whenSelectAuthMechanism(function($tr, authMechanism, scheme, onCompletion) { + OCA.Files_External.Settings.mountConfig.whenSelectAuthMechanism(function($tr, authMechanism, scheme, onCompletion) { if (scheme === 'publickey' && authMechanism === 'publickey::rsa') { var config = $tr.find('.configuration'); if ($(config).find('[name="public_key_generate"]').length === 0) { @@ -53,7 +53,7 @@ $(document).ready(function() { if (result && result.status === 'success') { $(config).find('[data-parameter="public_key"]').val(result.data.public_key).keyup(); $(config).find('[data-parameter="private_key"]').val(result.data.private_key); - OCA.External.Settings.mountConfig.saveStorageConfig(tr, function() { + OCA.Files_External.Settings.mountConfig.saveStorageConfig(tr, function() { // Nothing to do }); } else { diff --git a/apps/files_external/js/rollingqueue.js b/apps/files_external/js/rollingqueue.js index 53e11cb1219..df3797ada89 100644 --- a/apps/files_external/js/rollingqueue.js +++ b/apps/files_external/js/rollingqueue.js @@ -124,14 +124,14 @@ var RollingQueue = function (functionList, queueWindow, callback) { }; }; -if (!OCA.External) { - OCA.External = {}; +if (!OCA.Files_External) { + OCA.Files_External = {}; } -if (!OCA.External.StatusManager) { - OCA.External.StatusManager = {}; +if (!OCA.Files_External.StatusManager) { + OCA.Files_External.StatusManager = {}; } -OCA.External.StatusManager.RollingQueue = RollingQueue; +OCA.Files_External.StatusManager.RollingQueue = RollingQueue; })(); diff --git a/apps/files_external/js/settings.js b/apps/files_external/js/settings.js index 2d495281527..adf3f766202 100644 --- a/apps/files_external/js/settings.js +++ b/apps/files_external/js/settings.js @@ -163,7 +163,7 @@ function addSelect2 ($elements, userListLimit) { } /** - * @class OCA.External.Settings.StorageConfig + * @class OCA.Files_External.Settings.StorageConfig * * @classdesc External storage config */ @@ -185,7 +185,7 @@ StorageConfig.Visibility = { DEFAULT: 3 }; /** - * @memberof OCA.External.Settings + * @memberof OCA.Files_External.Settings */ StorageConfig.prototype = { _url: null, @@ -348,8 +348,8 @@ StorageConfig.prototype = { }; /** - * @class OCA.External.Settings.GlobalStorageConfig - * @augments OCA.External.Settings.StorageConfig + * @class OCA.Files_External.Settings.GlobalStorageConfig + * @augments OCA.Files_External.Settings.StorageConfig * * @classdesc Global external storage config */ @@ -359,10 +359,10 @@ var GlobalStorageConfig = function(id) { this.applicableGroups = []; }; /** - * @memberOf OCA.External.Settings + * @memberOf OCA.Files_External.Settings */ GlobalStorageConfig.prototype = _.extend({}, StorageConfig.prototype, - /** @lends OCA.External.Settings.GlobalStorageConfig.prototype */ { + /** @lends OCA.Files_External.Settings.GlobalStorageConfig.prototype */ { _url: 'apps/files_external/globalstorages', /** @@ -402,8 +402,8 @@ GlobalStorageConfig.prototype = _.extend({}, StorageConfig.prototype, }); /** - * @class OCA.External.Settings.UserStorageConfig - * @augments OCA.External.Settings.StorageConfig + * @class OCA.Files_External.Settings.UserStorageConfig + * @augments OCA.Files_External.Settings.StorageConfig * * @classdesc User external storage config */ @@ -411,13 +411,13 @@ var UserStorageConfig = function(id) { this.id = id; }; UserStorageConfig.prototype = _.extend({}, StorageConfig.prototype, - /** @lends OCA.External.Settings.UserStorageConfig.prototype */ { + /** @lends OCA.Files_External.Settings.UserStorageConfig.prototype */ { _url: 'apps/files_external/userstorages' }); /** - * @class OCA.External.Settings.UserGlobalStorageConfig - * @augments OCA.External.Settings.StorageConfig + * @class OCA.Files_External.Settings.UserGlobalStorageConfig + * @augments OCA.Files_External.Settings.StorageConfig * * @classdesc User external storage config */ @@ -425,13 +425,13 @@ var UserGlobalStorageConfig = function (id) { this.id = id; }; UserGlobalStorageConfig.prototype = _.extend({}, StorageConfig.prototype, - /** @lends OCA.External.Settings.UserStorageConfig.prototype */ { + /** @lends OCA.Files_External.Settings.UserStorageConfig.prototype */ { _url: 'apps/files_external/userglobalstorages' }); /** - * @class OCA.External.Settings.MountOptionsDropdown + * @class OCA.Files_External.Settings.MountOptionsDropdown * * @classdesc Dropdown for mount options * @@ -440,7 +440,7 @@ UserGlobalStorageConfig.prototype = _.extend({}, StorageConfig.prototype, var MountOptionsDropdown = function() { }; /** - * @memberof OCA.External.Settings + * @memberof OCA.Files_External.Settings */ MountOptionsDropdown.prototype = { /** @@ -462,7 +462,7 @@ MountOptionsDropdown.prototype = { MountOptionsDropdown._last.hide(); } - var $el = $(OCA.External.Templates.mountOptionsDropDown({ + var $el = $(OCA.Files_External.Templates.mountOptionsDropDown({ mountOptionsEncodingLabel: t('files_external', 'Compatibility with Mac NFD encoding (slow)'), mountOptionsEncryptLabel: t('files_external', 'Enable encryption'), mountOptionsPreviewsLabel: t('files_external', 'Enable previews'), @@ -549,7 +549,7 @@ MountOptionsDropdown.prototype = { }; /** - * @class OCA.External.Settings.MountConfigListView + * @class OCA.Files_External.Settings.MountConfigListView * * @classdesc Mount configuration list view * @@ -574,7 +574,7 @@ MountConfigListView.ParameterTypes = { }; /** - * @memberOf OCA.External.Settings + * @memberOf OCA.Files_External.Settings */ MountConfigListView.prototype = _.extend({ @@ -633,9 +633,9 @@ MountConfigListView.prototype = _.extend({ this.$el = $el; this._isPersonal = ($el.data('admin') !== true); if (this._isPersonal) { - this._storageConfigClass = OCA.External.Settings.UserStorageConfig; + this._storageConfigClass = OCA.Files_External.Settings.UserStorageConfig; } else { - this._storageConfigClass = OCA.External.Settings.GlobalStorageConfig; + this._storageConfigClass = OCA.Files_External.Settings.GlobalStorageConfig; } if (options && !_.isUndefined(options.userListLimit)) { @@ -1008,7 +1008,7 @@ MountConfigListView.prototype = _.extend({ * Gets the storage model from the given row * * @param $tr row element - * @return {OCA.External.StorageConfig} storage model instance + * @return {OCA.Files_External.StorageConfig} storage model instance */ getStorageConfig: function($tr) { var storageId = $tr.data('id'); @@ -1367,13 +1367,13 @@ $(document).ready(function() { }); // global instance - OCA.External.Settings.mountConfig = mountConfigListView; + OCA.Files_External.Settings.mountConfig = mountConfigListView; /** * Legacy * * @namespace - * @deprecated use OCA.External.Settings.mountConfig instead + * @deprecated use OCA.Files_External.Settings.mountConfig instead */ OC.MountConfig = { saveStorage: _.bind(mountConfigListView.saveStorageConfig, mountConfigListView) @@ -1382,14 +1382,14 @@ $(document).ready(function() { // export -OCA.External = OCA.External || {}; +OCA.Files_External = OCA.Files_External || {}; /** * @namespace */ -OCA.External.Settings = OCA.External.Settings || {}; +OCA.Files_External.Settings = OCA.Files_External.Settings || {}; -OCA.External.Settings.GlobalStorageConfig = GlobalStorageConfig; -OCA.External.Settings.UserStorageConfig = UserStorageConfig; -OCA.External.Settings.MountConfigListView = MountConfigListView; +OCA.Files_External.Settings.GlobalStorageConfig = GlobalStorageConfig; +OCA.Files_External.Settings.UserStorageConfig = UserStorageConfig; +OCA.Files_External.Settings.MountConfigListView = MountConfigListView; })(); diff --git a/apps/files_external/js/statusmanager.js b/apps/files_external/js/statusmanager.js index b8b5e1a9364..b4e89bd6232 100644 --- a/apps/files_external/js/statusmanager.js +++ b/apps/files_external/js/statusmanager.js @@ -14,15 +14,15 @@ /** @global Handlebars */ -if (!OCA.External) { - OCA.External = {}; +if (!OCA.Files_External) { + OCA.Files_External = {}; } -if (!OCA.External.StatusManager) { - OCA.External.StatusManager = {}; +if (!OCA.Files_External.StatusManager) { + OCA.Files_External.StatusManager = {}; } -OCA.External.StatusManager = { +OCA.Files_External.StatusManager = { mountStatus: null, mountPointList: null, @@ -209,18 +209,18 @@ OCA.External.StatusManager = { var mountPoint = mountData.mount_point; if (mountStatus.status > 0) { - var trElement = FileList.findFileEl(OCA.External.StatusManager.Utils.jqSelEscape(mountPoint)); + var trElement = FileList.findFileEl(OCA.Files_External.StatusManager.Utils.jqSelEscape(mountPoint)); - var route = OCA.External.StatusManager.Utils.getIconRoute(trElement) + '-error'; + var route = OCA.Files_External.StatusManager.Utils.getIconRoute(trElement) + '-error'; - if (OCA.External.StatusManager.Utils.isCorrectViewAndRootFolder()) { - OCA.External.StatusManager.Utils.showIconError(mountPoint, $.proxy(OCA.External.StatusManager.manageMountPointError, OCA.External.StatusManager), route); + if (OCA.Files_External.StatusManager.Utils.isCorrectViewAndRootFolder()) { + OCA.Files_External.StatusManager.Utils.showIconError(mountPoint, $.proxy(OCA.Files_External.StatusManager.manageMountPointError, OCA.Files_External.StatusManager), route); } return false; } else { - if (OCA.External.StatusManager.Utils.isCorrectViewAndRootFolder()) { - OCA.External.StatusManager.Utils.restoreFolder(mountPoint); - OCA.External.StatusManager.Utils.toggleLink(mountPoint, true, true); + if (OCA.Files_External.StatusManager.Utils.isCorrectViewAndRootFolder()) { + OCA.Files_External.StatusManager.Utils.restoreFolder(mountPoint); + OCA.Files_External.StatusManager.Utils.toggleLink(mountPoint, true, true); } return true; } @@ -235,7 +235,7 @@ OCA.External.StatusManager = { processMountList: function (mountList) { var elementList = null; $.each(mountList, function (name, value) { - var trElement = $('#fileList tr[data-file=\"' + OCA.External.StatusManager.Utils.jqSelEscape(value.mount_point) + '\"]'); //FileList.findFileEl(OCA.External.StatusManager.Utils.jqSelEscape(value.mount_point)); + var trElement = $('#fileList tr[data-file=\"' + OCA.Files_External.StatusManager.Utils.jqSelEscape(value.mount_point) + '\"]'); //FileList.findFileEl(OCA.Files_External.StatusManager.Utils.jqSelEscape(value.mount_point)); trElement.attr('data-external-backend', value.backend); if (elementList) { elementList = elementList.add(trElement); @@ -245,14 +245,14 @@ OCA.External.StatusManager = { }); if (elementList instanceof $) { - if (OCA.External.StatusManager.Utils.isCorrectViewAndRootFolder()) { + if (OCA.Files_External.StatusManager.Utils.isCorrectViewAndRootFolder()) { // Put their custom icon - OCA.External.StatusManager.Utils.changeFolderIcon(elementList); + OCA.Files_External.StatusManager.Utils.changeFolderIcon(elementList); // Save default view - OCA.External.StatusManager.Utils.storeDefaultFolderIconAndBgcolor(elementList); + OCA.Files_External.StatusManager.Utils.storeDefaultFolderIconAndBgcolor(elementList); // Disable row until check status elementList.addClass('externalDisabledRow'); - OCA.External.StatusManager.Utils.toggleLink(elementList.find('a.name'), false, false); + OCA.Files_External.StatusManager.Utils.toggleLink(elementList.find('a.name'), false, false); } } }, @@ -289,7 +289,7 @@ OCA.External.StatusManager = { ajaxQueue.push(queueElement); }); - var rolQueue = new OCA.External.StatusManager.RollingQueue(ajaxQueue, 4, function () { + var rolQueue = new OCA.Files_External.StatusManager.RollingQueue(ajaxQueue, 4, function () { if (!self.notificationHasShown) { var showNotification = false; $.each(self.mountStatus, function (key, value) { @@ -335,7 +335,7 @@ OCA.External.StatusManager = { }; ajaxQueue.push(queueElement); }); - new OCA.External.StatusManager.RollingQueue(ajaxQueue, 4).runQueue(); + new OCA.Files_External.StatusManager.RollingQueue(ajaxQueue, 4).runQueue(); }, @@ -392,7 +392,7 @@ OCA.External.StatusManager = { * @param mountData */ showCredentialsDialog: function (mountPoint, mountData) { - var dialog = $(OCA.External.Templates.credentialsDialog({ + var dialog = $(OCA.Files_External.Templates.credentialsDialog({ credentials_text: t('files_external', 'Please enter the credentials for the {mount} mount', { 'mount': mountPoint }), @@ -422,7 +422,7 @@ OCA.External.StatusManager = { OC.Notification.show(t('files_external', 'Credentials saved'), {type: 'error'}); dialog.ocdialog('close'); /* Trigger status check again */ - OCA.External.StatusManager.recheckConnectivityForMount([OC.basename(data.mountPoint)], true); + OCA.Files_External.StatusManager.recheckConnectivityForMount([OC.basename(data.mountPoint)], true); }, error: function () { $('.oc-dialog-close').show(); @@ -461,11 +461,11 @@ OCA.External.StatusManager = { } }; -OCA.External.StatusManager.Utils = { +OCA.Files_External.StatusManager.Utils = { showIconError: function (folder, clickAction, errorImageUrl) { var imageUrl = "url(" + errorImageUrl + ")"; - var trFolder = $('#fileList tr[data-file=\"' + OCA.External.StatusManager.Utils.jqSelEscape(folder) + '\"]'); //FileList.findFileEl(OCA.External.StatusManager.Utils.jqSelEscape(folder)); + var trFolder = $('#fileList tr[data-file=\"' + OCA.Files_External.StatusManager.Utils.jqSelEscape(folder) + '\"]'); //FileList.findFileEl(OCA.Files_External.StatusManager.Utils.jqSelEscape(folder)); this.changeFolderIcon(folder, imageUrl); this.toggleLink(folder, false, clickAction); trFolder.addClass('externalErroredRow'); @@ -479,7 +479,7 @@ OCA.External.StatusManager.Utils = { if (folder instanceof $) { trFolder = folder; } else { - trFolder = $('#fileList tr[data-file=\"' + OCA.External.StatusManager.Utils.jqSelEscape(folder) + '\"]'); //FileList.findFileEl(OCA.External.StatusManager.Utils.jqSelEscape(folder)); //$('#fileList tr[data-file=\"' + OCA.External.StatusManager.Utils.jqSelEscape(folder) + '\"]'); + trFolder = $('#fileList tr[data-file=\"' + OCA.Files_External.StatusManager.Utils.jqSelEscape(folder) + '\"]'); //FileList.findFileEl(OCA.Files_External.StatusManager.Utils.jqSelEscape(folder)); //$('#fileList tr[data-file=\"' + OCA.Files_External.StatusManager.Utils.jqSelEscape(folder) + '\"]'); } trFolder.each(function () { var thisElement = $(this); @@ -505,8 +505,8 @@ OCA.External.StatusManager.Utils = { if (folder instanceof $) { trFolder = folder; } else { - // can't use here FileList.findFileEl(OCA.External.StatusManager.Utils.jqSelEscape(folder)); return incorrect instance of filelist - trFolder = $('#fileList tr[data-file=\"' + OCA.External.StatusManager.Utils.jqSelEscape(folder) + '\"]'); + // can't use here FileList.findFileEl(OCA.Files_External.StatusManager.Utils.jqSelEscape(folder)); return incorrect instance of filelist + trFolder = $('#fileList tr[data-file=\"' + OCA.Files_External.StatusManager.Utils.jqSelEscape(folder) + '\"]'); } trFolder.removeClass('externalErroredRow').removeClass('externalDisabledRow'); var tdChilds = trFolder.find("td.filename div.thumbnail"); @@ -526,14 +526,14 @@ OCA.External.StatusManager.Utils = { if (filename instanceof $) { //trElementList $.each(filename, function (index) { - route = OCA.External.StatusManager.Utils.getIconRoute($(this)); + route = OCA.Files_External.StatusManager.Utils.getIconRoute($(this)); $(this).attr("data-icon", route); $(this).find('td.filename div.thumbnail').css('background-image', "url(" + route + ")").css('display', 'none').css('display', 'inline'); }); } else { file = $("#fileList tr[data-file=\"" + this.jqSelEscape(filename) + "\"] > td.filename div.thumbnail"); var parentTr = file.parents('tr:first'); - route = OCA.External.StatusManager.Utils.getIconRoute(parentTr); + route = OCA.Files_External.StatusManager.Utils.getIconRoute(parentTr); parentTr.attr("data-icon", route); file.css('background-image', "url(" + route + ")").css('display', 'none').css('display', 'inline'); } diff --git a/apps/files_external/js/templates.js b/apps/files_external/js/templates.js index 067b3f5f5d7..cf1522334c5 100644 --- a/apps/files_external/js/templates.js +++ b/apps/files_external/js/templates.js @@ -1,5 +1,5 @@ (function() { - var template = Handlebars.template, templates = OCA.External.Templates = OCA.External.Templates || {}; + var template = Handlebars.template, templates = OCA.Files_External.Templates = OCA.Files_External.Templates || {}; templates['credentialsDialog'] = template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) { var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression; diff --git a/apps/files_external/tests/appSpec.js b/apps/files_external/tests/appSpec.js index 43902d1c1d0..a834d96e2c0 100644 --- a/apps/files_external/tests/appSpec.js +++ b/apps/files_external/tests/appSpec.js @@ -19,8 +19,8 @@ * */ -describe('OCA.External.App tests', function() { - var App = OCA.External.App; +describe('OCA.Files_External.App tests', function() { + var App = OCA.Files_External.App; var fileList; beforeEach(function() { diff --git a/apps/files_external/tests/js/mountsfilelistSpec.js b/apps/files_external/tests/js/mountsfilelistSpec.js index feea68cf346..fe2fd8dec84 100644 --- a/apps/files_external/tests/js/mountsfilelistSpec.js +++ b/apps/files_external/tests/js/mountsfilelistSpec.js @@ -8,7 +8,7 @@ * */ -describe('OCA.External.FileList tests', function() { +describe('OCA.Files_External.FileList tests', function() { var testFiles, alertStub, notificationStub, fileList; beforeEach(function() { @@ -62,7 +62,7 @@ describe('OCA.External.FileList tests', function() { var ocsResponse; beforeEach(function() { - fileList = new OCA.External.FileList( + fileList = new OCA.Files_External.FileList( $('#app-content-container') ); diff --git a/apps/files_external/tests/js/settingsSpec.js b/apps/files_external/tests/js/settingsSpec.js index 57ad4550993..e004871650c 100644 --- a/apps/files_external/tests/js/settingsSpec.js +++ b/apps/files_external/tests/js/settingsSpec.js @@ -8,7 +8,7 @@ * */ -describe('OCA.External.Settings tests', function() { +describe('OCA.Files_External.Settings tests', function() { var clock; var select2Stub; var select2ApplicableUsers; @@ -156,7 +156,7 @@ describe('OCA.External.Settings tests', function() { beforeEach(function() { var $el = $('#externalStorage'); - view = new OCA.External.Settings.MountConfigListView($el, {encryptionEnabled: false}); + view = new OCA.Files_External.Settings.MountConfigListView($el, {encryptionEnabled: false}); }); afterEach(function() { view = null; diff --git a/apps/files_sharing/css/sharetabview.scss b/apps/files_sharing/css/sharetabview.scss index 14be9562228..0d277c58bd7 100644 --- a/apps/files_sharing/css/sharetabview.scss +++ b/apps/files_sharing/css/sharetabview.scss @@ -4,6 +4,10 @@ .share-autocomplete-item { display: flex; + + &.merged { + margin-left: 32px; + } .autocomplete-item-text { margin-left: 10px; margin-right: 10px; @@ -12,6 +16,27 @@ overflow: hidden; line-height: 32px; vertical-align: middle; + flex-grow: 1; + .ui-state-highlight { + border: none; + margin: 0; + } + } + &.with-description { + .autocomplete-item-text { + line-height: 100%; + } + } + .autocomplete-item-details { + display: block; + line-height: 130%; + font-size: 90%; + opacity: 0.7; + } + + .icon { + opacity: .7; + margin-right: 7px; } } @@ -204,8 +229,8 @@ } .ui-autocomplete { - /* limit dropdown height to 4 1/2 entries */ - max-height: calc(36px * 4.5);; + /* limit dropdown height to 6 1/2 entries */ + max-height: calc(36px * 6.5); overflow-y: auto; overflow-x: hidden; z-index: 1550 !important; diff --git a/apps/files_sharing/l10n/es.js b/apps/files_sharing/l10n/es.js index 43f9c5f3ce7..62f2d8c7320 100644 --- a/apps/files_sharing/l10n/es.js +++ b/apps/files_sharing/l10n/es.js @@ -89,7 +89,7 @@ OC.L10N.register( "Public upload disabled by the administrator" : "La subida pública está deshabilitado por el administrador", "Public upload is only possible for publicly shared folders" : "La subida publica solo es posible para las carpetas publicas compartidas", "Invalid date, date format must be YYYY-MM-DD" : "Fecha inválida, el formato de las fechas debe ser YYYY-MM-DD", - "Sharing %1$s failed because the back end does not allow shares from type %2$s" : "Compartir %1$s ha fallado porque el motor no permite compartidos del tipo %2$s", + "Sharing %1$s failed because the back end does not allow shares from type %2$s" : "Compartir %1$s ha fallado porque el backend no permite compartidos del tipo %2$s", "Sharing %s sending the password by Nextcloud Talk failed because Nextcloud Talk is not enabled" : "Compartir %s enviando la contraseña por Nextcloud Talk ha falllado porque Nextcloud Talk no está activado", "You cannot share to a Circle if the app is not enabled" : "No puede compartir a un Circulo si la aplicación no esta activada", "Please specify a valid circle" : "Por favor especifique un circulo valido", diff --git a/apps/files_sharing/l10n/es.json b/apps/files_sharing/l10n/es.json index 00fa8870b72..89899478a58 100644 --- a/apps/files_sharing/l10n/es.json +++ b/apps/files_sharing/l10n/es.json @@ -87,7 +87,7 @@ "Public upload disabled by the administrator" : "La subida pública está deshabilitado por el administrador", "Public upload is only possible for publicly shared folders" : "La subida publica solo es posible para las carpetas publicas compartidas", "Invalid date, date format must be YYYY-MM-DD" : "Fecha inválida, el formato de las fechas debe ser YYYY-MM-DD", - "Sharing %1$s failed because the back end does not allow shares from type %2$s" : "Compartir %1$s ha fallado porque el motor no permite compartidos del tipo %2$s", + "Sharing %1$s failed because the back end does not allow shares from type %2$s" : "Compartir %1$s ha fallado porque el backend no permite compartidos del tipo %2$s", "Sharing %s sending the password by Nextcloud Talk failed because Nextcloud Talk is not enabled" : "Compartir %s enviando la contraseña por Nextcloud Talk ha falllado porque Nextcloud Talk no está activado", "You cannot share to a Circle if the app is not enabled" : "No puede compartir a un Circulo si la aplicación no esta activada", "Please specify a valid circle" : "Por favor especifique un circulo valido", diff --git a/apps/files_sharing/l10n/is.js b/apps/files_sharing/l10n/is.js index cc1cc03ae39..b7edef7359e 100644 --- a/apps/files_sharing/l10n/is.js +++ b/apps/files_sharing/l10n/is.js @@ -90,13 +90,16 @@ OC.L10N.register( "Public upload is only possible for publicly shared folders" : "Opinber innsending er einungis möguleg í möppur sem er deilt opinberlega", "Invalid date, date format must be YYYY-MM-DD" : "Ógild dagsetning, dagsetningasniðið verður að vera ÁÁÁÁ-MM-DD", "Sharing %1$s failed because the back end does not allow shares from type %2$s" : "Deiling %1$s mistókst, því bakvinnslukerfið leyfir ekki sameignir af gerðinni %2$s", + "Sharing %s sending the password by Nextcloud Talk failed because Nextcloud Talk is not enabled" : "Deiling á %s með því að senda lykilorð með Nextcloud Talk mistókst því að Nextcloud Talk er ekki virkt", "You cannot share to a Circle if the app is not enabled" : "Þú getur ekki deilt með hring ef forritið er ekki virkt", "Please specify a valid circle" : "Settu inn gildan hring", + "Sharing %s failed because the back end does not support room shares" : "Deiling %s mistókst því bakvinnslukerfið leyfir ekki spjallsvæðasameignir", "Unknown share type" : "Óþekkt tegund sameignar", "Not a directory" : "Er ekki mappa", "Could not lock path" : "Gat ekki læst slóð", "Wrong or no update parameter given" : "Rangt eða ekkert uppfærsluviðfang gefið", "Can't change permissions for public share links" : "Ekki tókst að breyta aðgangsheimildum fyrir opinbera deilingartengla", + "Sharing sending the password by Nextcloud Talk failed because Nextcloud Talk is not enabled" : "Deiling með því að senda lykilorð með Nextcloud Talk mistókst því að Nextcloud Talk er ekki virkt", "Cannot increase permissions" : "Get ekki aukið aðgangsheimildir", "shared by %s" : "Deilt af %s", "Direct link" : "Beinn tengill", diff --git a/apps/files_sharing/l10n/is.json b/apps/files_sharing/l10n/is.json index c984df71929..0a9ba701676 100644 --- a/apps/files_sharing/l10n/is.json +++ b/apps/files_sharing/l10n/is.json @@ -88,13 +88,16 @@ "Public upload is only possible for publicly shared folders" : "Opinber innsending er einungis möguleg í möppur sem er deilt opinberlega", "Invalid date, date format must be YYYY-MM-DD" : "Ógild dagsetning, dagsetningasniðið verður að vera ÁÁÁÁ-MM-DD", "Sharing %1$s failed because the back end does not allow shares from type %2$s" : "Deiling %1$s mistókst, því bakvinnslukerfið leyfir ekki sameignir af gerðinni %2$s", + "Sharing %s sending the password by Nextcloud Talk failed because Nextcloud Talk is not enabled" : "Deiling á %s með því að senda lykilorð með Nextcloud Talk mistókst því að Nextcloud Talk er ekki virkt", "You cannot share to a Circle if the app is not enabled" : "Þú getur ekki deilt með hring ef forritið er ekki virkt", "Please specify a valid circle" : "Settu inn gildan hring", + "Sharing %s failed because the back end does not support room shares" : "Deiling %s mistókst því bakvinnslukerfið leyfir ekki spjallsvæðasameignir", "Unknown share type" : "Óþekkt tegund sameignar", "Not a directory" : "Er ekki mappa", "Could not lock path" : "Gat ekki læst slóð", "Wrong or no update parameter given" : "Rangt eða ekkert uppfærsluviðfang gefið", "Can't change permissions for public share links" : "Ekki tókst að breyta aðgangsheimildum fyrir opinbera deilingartengla", + "Sharing sending the password by Nextcloud Talk failed because Nextcloud Talk is not enabled" : "Deiling með því að senda lykilorð með Nextcloud Talk mistókst því að Nextcloud Talk er ekki virkt", "Cannot increase permissions" : "Get ekki aukið aðgangsheimildir", "shared by %s" : "Deilt af %s", "Direct link" : "Beinn tengill", diff --git a/apps/files_sharing/lib/Controller/ShareAPIController.php b/apps/files_sharing/lib/Controller/ShareAPIController.php index ff19c35e2b5..a935189491e 100644 --- a/apps/files_sharing/lib/Controller/ShareAPIController.php +++ b/apps/files_sharing/lib/Controller/ShareAPIController.php @@ -252,6 +252,7 @@ class ShareAPIController extends OCSController { $result['mail_send'] = $share->getMailSend() ? 1 : 0; + $result['hide_download'] = $share->getHideDownload() ? 1 : 0; return $result; } @@ -745,6 +746,7 @@ class ShareAPIController extends OCSController { * @param string $publicUpload * @param string $expireDate * @param string $note + * @param string $hideDownload * @return DataResponse * @throws LockedException * @throws NotFoundException @@ -759,7 +761,8 @@ class ShareAPIController extends OCSController { string $sendPasswordByTalk = null, string $publicUpload = null, string $expireDate = null, - string $note = null + string $note = null, + string $hideDownload = null ): DataResponse { try { $share = $this->getShareById($id); @@ -773,7 +776,7 @@ class ShareAPIController extends OCSController { throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist')); } - if ($permissions === null && $password === null && $sendPasswordByTalk === null && $publicUpload === null && $expireDate === null && $note === null) { + if ($permissions === null && $password === null && $sendPasswordByTalk === null && $publicUpload === null && $expireDate === null && $note === null && $hideDownload === null) { throw new OCSBadRequestException($this->l->t('Wrong or no update parameter given')); } @@ -786,6 +789,13 @@ class ShareAPIController extends OCSController { */ if ($share->getShareType() === Share::SHARE_TYPE_LINK) { + // Update hide download state + if ($hideDownload === 'true') { + $share->setHideDownload(true); + } else if ($hideDownload === 'false') { + $share->setHideDownload(false); + } + $newPermissions = null; if ($publicUpload === 'true') { $newPermissions = Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE; diff --git a/apps/files_sharing/lib/Controller/ShareController.php b/apps/files_sharing/lib/Controller/ShareController.php index 1e3cbb51028..1a92000a5f6 100644 --- a/apps/files_sharing/lib/Controller/ShareController.php +++ b/apps/files_sharing/lib/Controller/ShareController.php @@ -321,6 +321,7 @@ class ShareController extends AuthPublicShareController { $shareTmpl['dir'] = ''; $shareTmpl['nonHumanFileSize'] = $share->getNode()->getSize(); $shareTmpl['fileSize'] = \OCP\Util::humanFileSize($share->getNode()->getSize()); + $shareTmpl['hideDownload'] = $share->getHideDownload(); // Show file list $hideFileList = false; @@ -444,12 +445,14 @@ class ShareController extends AuthPublicShareController { $response = new PublicTemplateResponse($this->appName, 'public', $shareTmpl); $response->setHeaderTitle($shareTmpl['filename']); $response->setHeaderDetails($this->l10n->t('shared by %s', [$shareTmpl['displayName']])); - $response->setHeaderActions([ - new SimpleMenuAction('download', $this->l10n->t('Download'), 'icon-download-white', $shareTmpl['downloadURL'], 0), - new SimpleMenuAction('download', $this->l10n->t('Download'), 'icon-download', $shareTmpl['downloadURL'], 10, $shareTmpl['fileSize']), - new LinkMenuAction($this->l10n->t('Direct link'), 'icon-public', $shareTmpl['previewURL']), - new ExternalShareMenuAction($this->l10n->t('Add to your Nextcloud'), 'icon-external', $shareTmpl['owner'], $shareTmpl['displayName'], $shareTmpl['filename']), - ]); + if (!$share->getHideDownload()) { + $response->setHeaderActions([ + new SimpleMenuAction('download', $this->l10n->t('Download'), 'icon-download-white', $shareTmpl['downloadURL'], 0), + new SimpleMenuAction('download', $this->l10n->t('Download'), 'icon-download', $shareTmpl['downloadURL'], 10, $shareTmpl['fileSize']), + new LinkMenuAction($this->l10n->t('Direct link'), 'icon-public', $shareTmpl['previewURL']), + new ExternalShareMenuAction($this->l10n->t('Add to your Nextcloud'), 'icon-external', $shareTmpl['owner'], $shareTmpl['displayName'], $shareTmpl['filename']), + ]); + } $response->setContentSecurityPolicy($csp); diff --git a/apps/files_sharing/templates/public.php b/apps/files_sharing/templates/public.php index da80f8d1377..4487e63f2de 100644 --- a/apps/files_sharing/templates/public.php +++ b/apps/files_sharing/templates/public.php @@ -11,13 +11,16 @@ <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"> +<?php if (!$_['hideDownload']): ?> + <input type="hidden" name="downloadURL" value="<?php p($_['downloadURL']) ?>" id="downloadURL"> +<?php endif; ?> <input type="hidden" name="previewURL" value="<?php p($_['previewURL']) ?>" id="previewURL"> <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"> <input type="hidden" name="previewSupported" value="<?php p($_['previewSupported'] ? 'true' : 'false'); ?>" id="previewSupported"> <input type="hidden" name="mimetypeIcon" value="<?php p(\OC::$server->getMimeTypeDetector()->mimeTypeIcon($_['mimetype'])); ?>" id="mimetypeIcon"> +<input type="hidden" name="hideDownload" value="<?php p($_['hideDownload'] ? 'true' : 'false'); ?>" id="hideDownload"> <?php $upload_max_filesize = OC::$server->getIniWrapper()->getBytes('upload_max_filesize'); $post_max_size = OC::$server->getIniWrapper()->getBytes('post_max_size'); @@ -58,7 +61,7 @@ $maxUploadFilesize = min($upload_max_filesize, $post_max_size); <!-- Preview frame is filled via JS to support SVG images for modern browsers --> <div id="imgframe"></div> <?php endif; ?> - <?php if ($_['previewURL'] === $_['downloadURL']): ?> + <?php if ($_['previewURL'] === $_['downloadURL'] && !$_['hideDownload']): ?> <div class="directDownload"> <a href="<?php p($_['downloadURL']); ?>" id="downloadFile" class="button"> <span class="icon icon-download"></span> @@ -97,4 +100,4 @@ $maxUploadFilesize = min($upload_max_filesize, $post_max_size); data-url="<?php p(\OC::$server->getURLGenerator()->linkTo('files', 'ajax/upload.php')); ?>" /> </div> <?php endif; ?> -</div>
\ No newline at end of file +</div> diff --git a/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php b/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php index 15c4071bc46..bd263de3f62 100644 --- a/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php +++ b/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php @@ -353,6 +353,7 @@ class ShareAPIControllerTest extends TestCase { 'note' => 'personal note', 'displayname_file_owner' => 'ownerDisplay', 'mimetype' => 'myMimeType', + 'hide_download' => 0, ]; $data[] = [$share, $expected]; @@ -397,6 +398,7 @@ class ShareAPIControllerTest extends TestCase { 'note' => 'personal note', 'displayname_file_owner' => 'ownerDisplay', 'mimetype' => 'myFolderMimeType', + 'hide_download' => 0, ]; $data[] = [$share, $expected]; @@ -445,6 +447,7 @@ class ShareAPIControllerTest extends TestCase { 'note' => 'personal note', 'displayname_file_owner' => 'ownerDisplay', 'mimetype' => 'myFolderMimeType', + 'hide_download' => 0, ]; $data[] = [$share, $expected]; @@ -2175,6 +2178,7 @@ class ShareAPIControllerTest extends TestCase { 'note' => 'personal note', 'mail_send' => 0, 'mimetype' => 'myMimeType', + 'hide_download' => 0, ], $share, [], false ]; // User backend up @@ -2204,6 +2208,7 @@ class ShareAPIControllerTest extends TestCase { 'share_with_displayname' => 'recipientDN', 'mail_send' => 0, 'mimetype' => 'myMimeType', + 'hide_download' => 0, ], $share, [ ['owner', $owner], ['initiator', $initiator], @@ -2249,6 +2254,7 @@ class ShareAPIControllerTest extends TestCase { 'share_with_displayname' => 'recipient', 'mail_send' => 0, 'mimetype' => 'myMimeType', + 'hide_download' => 0, ], $share, [], false ]; @@ -2292,6 +2298,7 @@ class ShareAPIControllerTest extends TestCase { 'share_with_displayname' => 'recipientGroupDisplayName', 'mail_send' => 0, 'mimetype' => 'myMimeType', + 'hide_download' => 0, ], $share, [], false ]; @@ -2333,6 +2340,7 @@ class ShareAPIControllerTest extends TestCase { 'share_with_displayname' => 'recipientGroup2', 'mail_send' => 0, 'mimetype' => 'myMimeType', + 'hide_download' => 0, ], $share, [], false ]; @@ -2377,6 +2385,7 @@ class ShareAPIControllerTest extends TestCase { 'mail_send' => 0, 'url' => 'myLink', 'mimetype' => 'myMimeType', + 'hide_download' => 0, ], $share, [], false ]; @@ -2418,6 +2427,7 @@ class ShareAPIControllerTest extends TestCase { 'share_with_displayname' => 'foobar', 'mail_send' => 0, 'mimetype' => 'myFolderMimeType', + 'hide_download' => 0, ], $share, [], false ]; @@ -2462,6 +2472,7 @@ class ShareAPIControllerTest extends TestCase { 'share_with_avatar' => 'path/to/the/avatar', 'mail_send' => 0, 'mimetype' => 'myFolderMimeType', + 'hide_download' => 0, ], $share, [], false ]; @@ -2504,6 +2515,7 @@ class ShareAPIControllerTest extends TestCase { 'share_with_avatar' => '', 'mail_send' => 0, 'mimetype' => 'myFolderMimeType', + 'hide_download' => 0, ], $share, [], false ]; @@ -2546,6 +2558,7 @@ class ShareAPIControllerTest extends TestCase { 'share_with_avatar' => '', 'mail_send' => 0, 'mimetype' => 'myFolderMimeType', + 'hide_download' => 0, ], $share, [], false ]; @@ -2603,7 +2616,8 @@ class ShareAPIControllerTest extends TestCase { 'mail_send' => 0, 'mimetype' => 'myFolderMimeType', 'password' => 'password', - 'send_password_by_talk' => false + 'send_password_by_talk' => false, + 'hide_download' => 0, ], $share, [], false ]; @@ -2647,7 +2661,8 @@ class ShareAPIControllerTest extends TestCase { 'mail_send' => 0, 'mimetype' => 'myFolderMimeType', 'password' => 'password', - 'send_password_by_talk' => true + 'send_password_by_talk' => true, + 'hide_download' => 0, ], $share, [], false ]; @@ -2787,6 +2802,7 @@ class ShareAPIControllerTest extends TestCase { 'share_with_displayname' => '', 'mail_send' => 0, 'mimetype' => 'myMimeType', + 'hide_download' => 0, ], $share, false, [] ]; @@ -2828,6 +2844,7 @@ class ShareAPIControllerTest extends TestCase { 'share_with_displayname' => 'recipientRoomName', 'mail_send' => 0, 'mimetype' => 'myMimeType', + 'hide_download' => 0, ], $share, true, [ 'share_with_displayname' => 'recipientRoomName' ] diff --git a/apps/files_sharing/tests/Controller/ShareControllerTest.php b/apps/files_sharing/tests/Controller/ShareControllerTest.php index a01560d0288..c5306cbc0ce 100644 --- a/apps/files_sharing/tests/Controller/ShareControllerTest.php +++ b/apps/files_sharing/tests/Controller/ShareControllerTest.php @@ -287,7 +287,8 @@ class ShareControllerTest extends \Test\TestCase { 'shareUrl' => null, 'previewImage' => null, 'previewURL' => 'downloadURL', - 'note' => $note + 'note' => $note, + 'hideDownload' => false ); $csp = new \OCP\AppFramework\Http\ContentSecurityPolicy(); @@ -306,6 +307,120 @@ class ShareControllerTest extends \Test\TestCase { $this->assertEquals($expectedResponse, $response); } + public function testShowShareHideDownload() { + $note = 'personal note'; + + $this->shareController->setToken('token'); + + $owner = $this->getMockBuilder(IUser::class)->getMock(); + $owner->method('getDisplayName')->willReturn('ownerDisplay'); + $owner->method('getUID')->willReturn('ownerUID'); + + $file = $this->getMockBuilder('OCP\Files\File')->getMock(); + $file->method('getName')->willReturn('file1.txt'); + $file->method('getMimetype')->willReturn('text/plain'); + $file->method('getSize')->willReturn(33); + $file->method('isReadable')->willReturn(true); + $file->method('isShareable')->willReturn(true); + + $share = \OC::$server->getShareManager()->newShare(); + $share->setId(42); + $share->setPassword('password') + ->setShareOwner('ownerUID') + ->setNode($file) + ->setNote($note) + ->setTarget('/file1.txt') + ->setHideDownload(true); + + $this->session->method('exists')->with('public_link_authenticated')->willReturn(true); + $this->session->method('get')->with('public_link_authenticated')->willReturn('42'); + + // Even if downloads are disabled the "downloadURL" parameter is + // provided to the template, as it is needed to preview audio and GIF + // files. + $this->urlGenerator->expects($this->at(0)) + ->method('linkToRouteAbsolute') + ->with('files_sharing.sharecontroller.downloadShare', ['token' => 'token']) + ->willReturn('downloadURL'); + + $this->previewManager->method('isMimeSupported')->with('text/plain')->willReturn(true); + + $this->config->method('getSystemValue') + ->willReturnMap( + [ + ['max_filesize_animated_gifs_public_sharing', 10, 10], + ['enable_previews', true, true], + ['preview_max_x', 1024, 1024], + ['preview_max_y', 1024, 1024], + ] + ); + $shareTmpl['maxSizeAnimateGif'] = $this->config->getSystemValue('max_filesize_animated_gifs_public_sharing', 10); + $shareTmpl['previewEnabled'] = $this->config->getSystemValue('enable_previews', true); + + $this->shareManager + ->expects($this->once()) + ->method('getShareByToken') + ->with('token') + ->willReturn($share); + $this->config + ->expects($this->once()) + ->method('getAppValue') + ->with('core', 'shareapi_public_link_disclaimertext', null) + ->willReturn('My disclaimer text'); + + $this->userManager->method('get')->with('ownerUID')->willReturn($owner); + + $this->eventDispatcher->expects($this->once()) + ->method('dispatch') + ->with('OCA\Files_Sharing::loadAdditionalScripts'); + + $this->l10n->expects($this->any()) + ->method('t') + ->will($this->returnCallback(function($text, $parameters) { + return vsprintf($text, $parameters); + })); + + $response = $this->shareController->showShare(); + $sharedTmplParams = array( + 'displayName' => 'ownerDisplay', + 'owner' => 'ownerUID', + 'filename' => 'file1.txt', + 'directory_path' => '/file1.txt', + 'mimetype' => 'text/plain', + 'dirToken' => 'token', + 'sharingToken' => 'token', + 'server2serversharing' => true, + 'protected' => 'true', + 'dir' => '', + 'downloadURL' => 'downloadURL', + 'fileSize' => '33 B', + 'nonHumanFileSize' => 33, + 'maxSizeAnimateGif' => 10, + 'previewSupported' => true, + 'previewEnabled' => true, + 'previewMaxX' => 1024, + 'previewMaxY' => 1024, + 'hideFileList' => false, + 'shareOwner' => 'ownerDisplay', + 'disclaimer' => 'My disclaimer text', + 'shareUrl' => null, + 'previewImage' => null, + 'previewURL' => 'downloadURL', + 'note' => $note, + 'hideDownload' => true + ); + + $csp = new \OCP\AppFramework\Http\ContentSecurityPolicy(); + $csp->addAllowedFrameDomain('\'self\''); + $expectedResponse = new PublicTemplateResponse($this->appName, 'public', $sharedTmplParams); + $expectedResponse->setContentSecurityPolicy($csp); + $expectedResponse->setHeaderTitle($sharedTmplParams['filename']); + $expectedResponse->setHeaderDetails('shared by ' . $sharedTmplParams['displayName']); + $expectedResponse->setHeaderActions([]); + + $this->assertEquals($expectedResponse, $response); + } + /** * @expectedException \OCP\Files\NotFoundException */ diff --git a/apps/files_trashbin/lib/Trash/TrashItem.php b/apps/files_trashbin/lib/Trash/TrashItem.php index cd7079bcf26..40ceb59abaa 100644 --- a/apps/files_trashbin/lib/Trash/TrashItem.php +++ b/apps/files_trashbin/lib/Trash/TrashItem.php @@ -169,4 +169,8 @@ class TrashItem implements ITrashItem { public function getChecksum() { return $this->fileInfo->getChecksum(); } + + public function getExtension(): string { + return $this->fileInfo->getExtension(); + } } diff --git a/apps/files_versions/l10n/es.js b/apps/files_versions/l10n/es.js index 9a18c7a7abd..13e46f592ba 100644 --- a/apps/files_versions/l10n/es.js +++ b/apps/files_versions/l10n/es.js @@ -5,12 +5,12 @@ OC.L10N.register( "Failed to revert {file} to revision {timestamp}." : "No se ha podido restaurar {file} a versión {timestamp}.", "_%n byte_::_%n bytes_" : ["%n byte","%n bytes"], "Restore" : "Recuperar", - "No other versions available" : "No hay otras versiones disponibles", + "No other versions available" : "No hay más versiones disponibles", "This application automatically maintains older versions of files that are changed." : "Esta aplicación mantiene automáticamente versiones antiguas de los archivos que cambian.", - "This application automatically maintains older versions of files that are changed. When enabled, a hidden versions folder is provisioned in every user’s directory and is used to store old file versions. A user can revert to an older version through the web interface at any time, with the replaced file becoming a version. The app automatically manages the versions folder to ensure the user doesn’t run out of Quota because of versions.\n\t\tIn addition to the expiry of versions, the versions app makes certain never to use more than 50% of the user’s currently available free space. If stored versions exceed this limit, the app will delete the oldest versions first until it meets this limit. More information is available in the Versions documentation." : "Esta aplicación mantiene automáticamente versiones antiguas de los archivos que cambian. Al activarse, se crea una carpeta oculta de versiones que se usa para almacenar versiones antiguas de archivos. Un usuario puede volver a una versión anterior a través de la interfaz web en cualquier momento, con el archivo reemplazado convirtiéndose en una versión. La app maneja automáticamente la carpeta de versiones para asegurarse de que el usuario no se queda sin espacio debido a las versiones.\n\nAdemás de la expiración de versiones, la app de versiones se asegura de no usar nunca más del 50% del espacio libre actualmente disponible para un usuario. Si las versiones almacenadas exceden este límite, la app borrará las versiones más antiguas hasta alcanzar este límite. Más información disponible en la documentación de Versiones.", + "This application automatically maintains older versions of files that are changed. When enabled, a hidden versions folder is provisioned in every user’s directory and is used to store old file versions. A user can revert to an older version through the web interface at any time, with the replaced file becoming a version. The app automatically manages the versions folder to ensure the user doesn’t run out of Quota because of versions.\n\t\tIn addition to the expiry of versions, the versions app makes certain never to use more than 50% of the user’s currently available free space. If stored versions exceed this limit, the app will delete the oldest versions first until it meets this limit. More information is available in the Versions documentation." : "Esta aplicación mantiene automáticamente versiones antiguas de los archivos que cambian. Al activarse, se crea una carpeta oculta de versiones que se usa para almacenar versiones antiguas de archivos. Un usuario puede volver a una versión anterior a través de la interfaz web en cualquier momento, con el archivo reemplazado convirtiéndose en una versión. La app maneja automáticamente la carpeta de versiones para asegurarse de que el usuario no se queda sin espacio debido a las versiones.\n\n\t\tAdemás de la caducidad de versiones, la app de versiones se asegura de no usar nunca más del 50% del espacio libre actualmente disponible para un usuario. Si las versiones almacenadas exceden este límite, la app borrará las versiones más antiguas hasta alcanzar este límite. Más información disponible en la documentación de Versiones.", "Could not revert: %s" : "No se puede restaurar: %s", "No earlier versions available" : "No hay versiones previas disponibles", "More versions …" : "Más versiones ...", - "This application automatically maintains older versions of files that are changed. When enabled, a hidden versions folder is provisioned in every user’s directory and is used to store old file versions. A user can revert to an older version through the web interface at any time, with the replaced file becoming a version. The app automatically manages the versions folder to ensure the user doesn’t run out of Quota because of versions.\nIn addition to the expiry of versions, the versions app makes certain never to use more than 50% of the user’s currently available free space. If stored versions exceed this limit, the app will delete the oldest versions first until it meets this limit. More information is available in the Versions documentation." : "Esta aplicación mantiene automáticamente versiones antiguas de los archivos que cambian. Al activarse, se crea una carpeta oculta de versiones que se usa para almacenar versiones antiguas de archivos. Un usuario puede volver a una versión anterior a través de la interfaz web en cualquier momento, con el archivo reemplazado convirtiéndose en una versión. La app maneja automáticamente la carpeta de versiones para asegurarse de que el usuario no se queda sin espacio debido a las versiones.Además de la expiración de versiones, la app de versiones se asegura de no usar nunca más del 50% del espacio libre actualmente disponible para un usuario. Si las versiones almacenadas exceden este límite, la app borrará las versiones más antiguas hasta alcanzar este límite. Más información disponible en la documentación de Versiones." + "This application automatically maintains older versions of files that are changed. When enabled, a hidden versions folder is provisioned in every user’s directory and is used to store old file versions. A user can revert to an older version through the web interface at any time, with the replaced file becoming a version. The app automatically manages the versions folder to ensure the user doesn’t run out of Quota because of versions.\nIn addition to the expiry of versions, the versions app makes certain never to use more than 50% of the user’s currently available free space. If stored versions exceed this limit, the app will delete the oldest versions first until it meets this limit. More information is available in the Versions documentation." : "Esta aplicación mantiene automáticamente versiones antiguas de los archivos que cambian. Al activarse, se crea una carpeta oculta de versiones que se usa para almacenar versiones antiguas de archivos. Un usuario puede volver a una versión anterior a través de la interfaz web en cualquier momento, con el archivo reemplazado convirtiéndose en una versión. La app maneja automáticamente la carpeta de versiones para asegurarse de que el usuario no se queda sin espacio debido a las versiones.\nAdemás de la caducidad de versiones, la app de versiones se asegura de no usar nunca más del 50% del espacio libre actualmente disponible para un usuario. Si las versiones almacenadas exceden este límite, la app borrará las versiones más antiguas hasta alcanzar este límite. Más información disponible en la documentación de Versiones." }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_versions/l10n/es.json b/apps/files_versions/l10n/es.json index 347002f6d19..667eec5a9a2 100644 --- a/apps/files_versions/l10n/es.json +++ b/apps/files_versions/l10n/es.json @@ -3,12 +3,12 @@ "Failed to revert {file} to revision {timestamp}." : "No se ha podido restaurar {file} a versión {timestamp}.", "_%n byte_::_%n bytes_" : ["%n byte","%n bytes"], "Restore" : "Recuperar", - "No other versions available" : "No hay otras versiones disponibles", + "No other versions available" : "No hay más versiones disponibles", "This application automatically maintains older versions of files that are changed." : "Esta aplicación mantiene automáticamente versiones antiguas de los archivos que cambian.", - "This application automatically maintains older versions of files that are changed. When enabled, a hidden versions folder is provisioned in every user’s directory and is used to store old file versions. A user can revert to an older version through the web interface at any time, with the replaced file becoming a version. The app automatically manages the versions folder to ensure the user doesn’t run out of Quota because of versions.\n\t\tIn addition to the expiry of versions, the versions app makes certain never to use more than 50% of the user’s currently available free space. If stored versions exceed this limit, the app will delete the oldest versions first until it meets this limit. More information is available in the Versions documentation." : "Esta aplicación mantiene automáticamente versiones antiguas de los archivos que cambian. Al activarse, se crea una carpeta oculta de versiones que se usa para almacenar versiones antiguas de archivos. Un usuario puede volver a una versión anterior a través de la interfaz web en cualquier momento, con el archivo reemplazado convirtiéndose en una versión. La app maneja automáticamente la carpeta de versiones para asegurarse de que el usuario no se queda sin espacio debido a las versiones.\n\nAdemás de la expiración de versiones, la app de versiones se asegura de no usar nunca más del 50% del espacio libre actualmente disponible para un usuario. Si las versiones almacenadas exceden este límite, la app borrará las versiones más antiguas hasta alcanzar este límite. Más información disponible en la documentación de Versiones.", + "This application automatically maintains older versions of files that are changed. When enabled, a hidden versions folder is provisioned in every user’s directory and is used to store old file versions. A user can revert to an older version through the web interface at any time, with the replaced file becoming a version. The app automatically manages the versions folder to ensure the user doesn’t run out of Quota because of versions.\n\t\tIn addition to the expiry of versions, the versions app makes certain never to use more than 50% of the user’s currently available free space. If stored versions exceed this limit, the app will delete the oldest versions first until it meets this limit. More information is available in the Versions documentation." : "Esta aplicación mantiene automáticamente versiones antiguas de los archivos que cambian. Al activarse, se crea una carpeta oculta de versiones que se usa para almacenar versiones antiguas de archivos. Un usuario puede volver a una versión anterior a través de la interfaz web en cualquier momento, con el archivo reemplazado convirtiéndose en una versión. La app maneja automáticamente la carpeta de versiones para asegurarse de que el usuario no se queda sin espacio debido a las versiones.\n\n\t\tAdemás de la caducidad de versiones, la app de versiones se asegura de no usar nunca más del 50% del espacio libre actualmente disponible para un usuario. Si las versiones almacenadas exceden este límite, la app borrará las versiones más antiguas hasta alcanzar este límite. Más información disponible en la documentación de Versiones.", "Could not revert: %s" : "No se puede restaurar: %s", "No earlier versions available" : "No hay versiones previas disponibles", "More versions …" : "Más versiones ...", - "This application automatically maintains older versions of files that are changed. When enabled, a hidden versions folder is provisioned in every user’s directory and is used to store old file versions. A user can revert to an older version through the web interface at any time, with the replaced file becoming a version. The app automatically manages the versions folder to ensure the user doesn’t run out of Quota because of versions.\nIn addition to the expiry of versions, the versions app makes certain never to use more than 50% of the user’s currently available free space. If stored versions exceed this limit, the app will delete the oldest versions first until it meets this limit. More information is available in the Versions documentation." : "Esta aplicación mantiene automáticamente versiones antiguas de los archivos que cambian. Al activarse, se crea una carpeta oculta de versiones que se usa para almacenar versiones antiguas de archivos. Un usuario puede volver a una versión anterior a través de la interfaz web en cualquier momento, con el archivo reemplazado convirtiéndose en una versión. La app maneja automáticamente la carpeta de versiones para asegurarse de que el usuario no se queda sin espacio debido a las versiones.Además de la expiración de versiones, la app de versiones se asegura de no usar nunca más del 50% del espacio libre actualmente disponible para un usuario. Si las versiones almacenadas exceden este límite, la app borrará las versiones más antiguas hasta alcanzar este límite. Más información disponible en la documentación de Versiones." + "This application automatically maintains older versions of files that are changed. When enabled, a hidden versions folder is provisioned in every user’s directory and is used to store old file versions. A user can revert to an older version through the web interface at any time, with the replaced file becoming a version. The app automatically manages the versions folder to ensure the user doesn’t run out of Quota because of versions.\nIn addition to the expiry of versions, the versions app makes certain never to use more than 50% of the user’s currently available free space. If stored versions exceed this limit, the app will delete the oldest versions first until it meets this limit. More information is available in the Versions documentation." : "Esta aplicación mantiene automáticamente versiones antiguas de los archivos que cambian. Al activarse, se crea una carpeta oculta de versiones que se usa para almacenar versiones antiguas de archivos. Un usuario puede volver a una versión anterior a través de la interfaz web en cualquier momento, con el archivo reemplazado convirtiéndose en una versión. La app maneja automáticamente la carpeta de versiones para asegurarse de que el usuario no se queda sin espacio debido a las versiones.\nAdemás de la caducidad de versiones, la app de versiones se asegura de no usar nunca más del 50% del espacio libre actualmente disponible para un usuario. Si las versiones almacenadas exceden este límite, la app borrará las versiones más antiguas hasta alcanzar este límite. Más información disponible en la documentación de Versiones." },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/oauth2/lib/Controller/OauthApiController.php b/apps/oauth2/lib/Controller/OauthApiController.php index 2083741fa0c..73fed3654d5 100644 --- a/apps/oauth2/lib/Controller/OauthApiController.php +++ b/apps/oauth2/lib/Controller/OauthApiController.php @@ -22,8 +22,9 @@ namespace OCA\OAuth2\Controller; use OC\Authentication\Exceptions\InvalidTokenException; -use OC\Authentication\Token\ExpiredTokenException; +use OC\Authentication\Exceptions\ExpiredTokenException; use OC\Authentication\Token\IProvider as TokenProvider; +use OC\Security\Bruteforce\Throttler; use OCA\OAuth2\Db\AccessTokenMapper; use OCA\OAuth2\Db\ClientMapper; use OCA\OAuth2\Exceptions\AccessTokenNotFoundException; @@ -49,6 +50,8 @@ class OauthApiController extends Controller { private $secureRandom; /** @var ITimeFactory */ private $time; + /** @var Throttler */ + private $throttler; /** * @param string $appName @@ -59,6 +62,7 @@ class OauthApiController extends Controller { * @param TokenProvider $tokenProvider * @param ISecureRandom $secureRandom * @param ITimeFactory $time + * @param Throttler $throttler */ public function __construct($appName, IRequest $request, @@ -67,7 +71,8 @@ class OauthApiController extends Controller { ClientMapper $clientMapper, TokenProvider $tokenProvider, ISecureRandom $secureRandom, - ITimeFactory $time) { + ITimeFactory $time, + Throttler $throttler) { parent::__construct($appName, $request); $this->crypto = $crypto; $this->accessTokenMapper = $accessTokenMapper; @@ -75,6 +80,7 @@ class OauthApiController extends Controller { $this->tokenProvider = $tokenProvider; $this->secureRandom = $secureRandom; $this->time = $time; + $this->throttler = $throttler; } /** @@ -164,6 +170,8 @@ class OauthApiController extends Controller { $accessToken->setEncryptedToken($this->crypto->encrypt($newToken, $newCode)); $this->accessTokenMapper->update($accessToken); + $this->throttler->resetDelay($this->request->getRemoteAddress(), 'login', ['user' => $appToken->getUID()]); + return new JSONResponse( [ 'access_token' => $newToken, diff --git a/apps/oauth2/tests/Controller/OauthApiControllerTest.php b/apps/oauth2/tests/Controller/OauthApiControllerTest.php index 10748485971..f5a8138fa2d 100644 --- a/apps/oauth2/tests/Controller/OauthApiControllerTest.php +++ b/apps/oauth2/tests/Controller/OauthApiControllerTest.php @@ -22,11 +22,10 @@ namespace OCA\OAuth2\Tests\Controller; use OC\Authentication\Exceptions\InvalidTokenException; +use OC\Authentication\Exceptions\ExpiredTokenException; use OC\Authentication\Token\DefaultToken; -use OC\Authentication\Token\DefaultTokenMapper; -use OC\Authentication\Token\ExpiredTokenException; use OC\Authentication\Token\IProvider as TokenProvider; -use OC\Authentication\Token\IToken; +use OC\Security\Bruteforce\Throttler; use OCA\OAuth2\Controller\OauthApiController; use OCA\OAuth2\Db\AccessToken; use OCA\OAuth2\Db\AccessTokenMapper; @@ -57,6 +56,8 @@ class OauthApiControllerTest extends TestCase { private $secureRandom; /** @var ITimeFactory|\PHPUnit_Framework_MockObject_MockObject */ private $time; + /** @var Throttler|\PHPUnit_Framework_MockObject_MockObject */ + private $throttler; /** @var OauthApiController */ private $oauthApiController; @@ -70,6 +71,7 @@ class OauthApiControllerTest extends TestCase { $this->tokenProvider = $this->createMock(TokenProvider::class); $this->secureRandom = $this->createMock(ISecureRandom::class); $this->time = $this->createMock(ITimeFactory::class); + $this->throttler = $this->createMock(Throttler::class); $this->oauthApiController = new OauthApiController( 'oauth2', @@ -79,7 +81,8 @@ class OauthApiControllerTest extends TestCase { $this->clientMapper, $this->tokenProvider, $this->secureRandom, - $this->time + $this->time, + $this->throttler ); } @@ -286,6 +289,17 @@ class OauthApiControllerTest extends TestCase { 'user_id' => 'userId', ]); + $this->request->method('getRemoteAddress') + ->willReturn('1.2.3.4'); + + $this->throttler->expects($this->once()) + ->method('resetDelay') + ->with( + '1.2.3.4', + 'login', + ['user' => 'userId'] + ); + $this->assertEquals($expected, $this->oauthApiController->getToken('refresh_token', null, 'validrefresh', 'clientId', 'clientSecret')); } @@ -370,6 +384,17 @@ class OauthApiControllerTest extends TestCase { $this->request->server['PHP_AUTH_USER'] = 'clientId'; $this->request->server['PHP_AUTH_PW'] = 'clientSecret'; + $this->request->method('getRemoteAddress') + ->willReturn('1.2.3.4'); + + $this->throttler->expects($this->once()) + ->method('resetDelay') + ->with( + '1.2.3.4', + 'login', + ['user' => 'userId'] + ); + $this->assertEquals($expected, $this->oauthApiController->getToken('refresh_token', null, 'validrefresh', null, null)); } @@ -451,6 +476,17 @@ class OauthApiControllerTest extends TestCase { 'user_id' => 'userId', ]); + $this->request->method('getRemoteAddress') + ->willReturn('1.2.3.4'); + + $this->throttler->expects($this->once()) + ->method('resetDelay') + ->with( + '1.2.3.4', + 'login', + ['user' => 'userId'] + ); + $this->assertEquals($expected, $this->oauthApiController->getToken('refresh_token', null, 'validrefresh', 'clientId', 'clientSecret')); } } diff --git a/apps/sharebymail/tests/CapabilitiesTest.php b/apps/sharebymail/tests/CapabilitiesTest.php new file mode 100644 index 00000000000..b1545994199 --- /dev/null +++ b/apps/sharebymail/tests/CapabilitiesTest.php @@ -0,0 +1,51 @@ +<?php +/** + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCA\ShareByMail\Tests; + +use OCA\ShareByMail\Capabilities; +use Test\TestCase; + +class CapabilitiesTest extends TestCase { + /** @var Capabilities */ + private $capabilities; + + public function setUp() { + parent::setUp(); + + $this->capabilities = new Capabilities(); + } + + public function testGetCapabilities() { + $capabilities = [ + 'files_sharing' => + [ + 'sharebymail' => + [ + 'enabled' => true, + 'upload_files_drop' => ['enabled' => true], + 'password' => ['enabled' => true], + 'expire_date' => ['enabled' => true] + ] + ] + ]; + + $this->assertSame($capabilities, $this->capabilities->getCapabilities()); + } +} diff --git a/apps/systemtags/tests/Activity/SettingTest.php b/apps/systemtags/tests/Activity/SettingTest.php new file mode 100644 index 00000000000..40fcea750a6 --- /dev/null +++ b/apps/systemtags/tests/Activity/SettingTest.php @@ -0,0 +1,72 @@ +<?php +/** + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCA\SystemTags\Tests\Activity; + +use OCA\SystemTags\Activity\Setting; +use OCP\IL10N; +use Test\TestCase; + +class SettingTest extends TestCase { + /** @var IL10N|\PHPUnit_Framework_MockObject_MockObject */ + private $l; + /** @var Setting */ + private $setting; + + public function setUp() { + parent::setUp(); + $this->l = $this->createMock(IL10N::class); + + $this->setting = new Setting($this->l); + } + + public function testGetIdentifier() { + $this->assertSame('systemtags', $this->setting->getIdentifier()); + } + + public function testGetName() { + $this->l + ->expects($this->once()) + ->method('t') + ->with('<strong>System tags</strong> for a file have been modified') + ->willReturn('<strong>System tags</strong> for a file have been modified'); + + $this->assertSame('<strong>System tags</strong> for a file have been modified', $this->setting->getName()); + } + + public function testGetPriority() { + $this->assertSame(50, $this->setting->getPriority()); + } + + public function testCanChangeStream() { + $this->assertSame(true, $this->setting->canChangeStream()); + } + + public function testIsDefaultEnabledStream() { + $this->assertSame(true, $this->setting->isDefaultEnabledStream()); + } + + public function testCanChangeMail() { + $this->assertSame(true, $this->setting->canChangeMail()); + } + + public function testIsDefaultEnabledMail() { + $this->assertSame(false, $this->setting->isDefaultEnabledMail()); + } +} diff --git a/apps/user_ldap/lib/Access.php b/apps/user_ldap/lib/Access.php index e05bc539a77..d0d51ae8c85 100644 --- a/apps/user_ldap/lib/Access.php +++ b/apps/user_ldap/lib/Access.php @@ -624,9 +624,9 @@ class Access extends LDAPUtility implements IUserTools { $this->connection->setConfiguration(['ldapCacheTTL' => $originalTTL]); $altName = $this->createAltInternalOwnCloudName($intName, $isUser); - if(is_string($altName) && $mapper->map($fdn, $altName, $uuid)) { - if($this->ncUserManager instanceof PublicEmitter && $isUser) { - $this->ncUserManager->emit('\OC\User', 'assignedUserId', [$intName]); + if (is_string($altName) && $mapper->map($fdn, $altName, $uuid)) { + if ($this->ncUserManager instanceof PublicEmitter && $isUser) { + $this->ncUserManager->emit('\OC\User', 'assignedUserId', [$altName]); } $newlyMapped = true; return $altName; diff --git a/apps/user_ldap/lib/User/Manager.php b/apps/user_ldap/lib/User/Manager.php index c48193c7ad9..9f2f3649777 100644 --- a/apps/user_ldap/lib/User/Manager.php +++ b/apps/user_ldap/lib/User/Manager.php @@ -197,6 +197,13 @@ class Manager { ); } + // remove possible empty attributes + $attributes = array_values( + array_filter($attributes, function ($attributeName) { + return !empty($attributeName); + }) + ); + return $attributes; } diff --git a/apps/user_ldap/lib/User/User.php b/apps/user_ldap/lib/User/User.php index 02764a72eca..f4be19a7ad5 100644 --- a/apps/user_ldap/lib/User/User.php +++ b/apps/user_ldap/lib/User/User.php @@ -414,14 +414,23 @@ class User { * * @param string $displayName * @param string $displayName2 - * @returns string the effective display name + * @return string the effective display name */ public function composeAndStoreDisplayName($displayName, $displayName2 = '') { $displayName2 = (string)$displayName2; if($displayName2 !== '') { $displayName .= ' (' . $displayName2 . ')'; } - $this->store('displayName', $displayName); + $oldName = $this->config->getUserValue($this->uid, 'user_ldap', 'displayName', null); + if ($oldName !== $displayName) { + $this->store('displayName', $displayName); + $user = $this->userManager->get($this->getUsername()); + if (!empty($oldName) && $user instanceof \OC\User\User) { + // if it was empty, it would be a new record, not a change emitting the trigger could + // potentially cause a UniqueConstraintViolationException, depending on some factors. + $user->triggerChange('displayName', $displayName); + } + } return $displayName; } diff --git a/apps/user_ldap/tests/User/ManagerTest.php b/apps/user_ldap/tests/User/ManagerTest.php index 5399aa95a6a..104a70ff700 100644 --- a/apps/user_ldap/tests/User/ManagerTest.php +++ b/apps/user_ldap/tests/User/ManagerTest.php @@ -256,12 +256,17 @@ class ManagerTest extends \Test\TestCase { $manager->setLdapAccess($access); $connection = $access->getConnection(); - $connection->setConfiguration(['ldapEmailAttribute' => 'mail', 'ldapUserAvatarRule' => 'default']); + $connection->setConfiguration([ + 'ldapEmailAttribute' => 'mail', + 'ldapUserAvatarRule' => 'default', + 'ldapQuotaAttribute' => '', + ]); $attributes = $manager->getAttributes($minimal); $this->assertTrue(in_array('dn', $attributes)); $this->assertTrue(in_array($access->getConnection()->ldapEmailAttribute, $attributes)); + $this->assertFalse(in_array('', $attributes)); $this->assertSame(!$minimal, in_array('jpegphoto', $attributes)); $this->assertSame(!$minimal, in_array('thumbnailphoto', $attributes)); } diff --git a/apps/user_ldap/tests/User/UserTest.php b/apps/user_ldap/tests/User/UserTest.php index 837c72a3a31..6ff9defe47b 100644 --- a/apps/user_ldap/tests/User/UserTest.php +++ b/apps/user_ldap/tests/User/UserTest.php @@ -998,23 +998,58 @@ class UserTest extends \Test\TestCase { public function displayNameProvider() { return [ - ['Roland Deschain', '', 'Roland Deschain'], - ['Roland Deschain', null, 'Roland Deschain'], - ['Roland Deschain', 'gunslinger@darktower.com', 'Roland Deschain (gunslinger@darktower.com)'], + ['Roland Deschain', '', 'Roland Deschain', false], + ['Roland Deschain', '', 'Roland Deschain', true], + ['Roland Deschain', null, 'Roland Deschain', false], + ['Roland Deschain', 'gunslinger@darktower.com', 'Roland Deschain (gunslinger@darktower.com)', false], + ['Roland Deschain', 'gunslinger@darktower.com', 'Roland Deschain (gunslinger@darktower.com)', true], ]; } /** * @dataProvider displayNameProvider */ - public function testComposeAndStoreDisplayName($part1, $part2, $expected) { + public function testComposeAndStoreDisplayName($part1, $part2, $expected, $expectTriggerChange) { $this->config->expects($this->once()) ->method('setUserValue'); + $oldName = $expectTriggerChange ? 'xxGunslingerxx' : null; + $this->config->expects($this->once()) + ->method('getUserValue') + ->with($this->user->getUsername(), 'user_ldap', 'displayName', null) + ->willReturn($oldName); + + $ncUserObj = $this->createMock(\OC\User\User::class); + if ($expectTriggerChange) { + $ncUserObj->expects($this->once()) + ->method('triggerChange') + ->with('displayName', $expected); + } else { + $ncUserObj->expects($this->never()) + ->method('triggerChange'); + } + $this->userManager->expects($this->once()) + ->method('get') + ->willReturn($ncUserObj); $displayName = $this->user->composeAndStoreDisplayName($part1, $part2); $this->assertSame($expected, $displayName); } + public function testComposeAndStoreDisplayNameNoOverwrite() { + $displayName = 'Randall Flagg'; + $this->config->expects($this->never()) + ->method('setUserValue'); + $this->config->expects($this->once()) + ->method('getUserValue') + ->willReturn($displayName); + + $this->userManager->expects($this->never()) + ->method('get'); // Implicit: no triggerChange can be called + + $composedDisplayName = $this->user->composeAndStoreDisplayName($displayName); + $this->assertSame($composedDisplayName, $displayName); + } + public function testHandlePasswordExpiryWarningDefaultPolicy() { $this->connection->expects($this->any()) ->method('__get') diff --git a/apps/workflowengine/lib/Check/FileMimeType.php b/apps/workflowengine/lib/Check/FileMimeType.php index bd94ec9d5bc..5f572f5aa9d 100644 --- a/apps/workflowengine/lib/Check/FileMimeType.php +++ b/apps/workflowengine/lib/Check/FileMimeType.php @@ -76,6 +76,11 @@ class FileMimeType extends AbstractStringCheck { return $this->mimeType[$this->storage->getId()][$this->path]; } + if ($this->storage->is_dir($this->path)) { + $this->mimeType[$this->storage->getId()][$this->path] = 'httpd/unix-directory'; + return $this->mimeType[$this->storage->getId()][$this->path]; + } + if ($this->isWebDAVRequest()) { // Creating a folder if ($this->request->getMethod() === 'MKCOL') { diff --git a/build/compile-handlebars-templates.sh b/build/compile-handlebars-templates.sh index 65ad4da12cf..b73b7d8f460 100755 --- a/build/compile-handlebars-templates.sh +++ b/build/compile-handlebars-templates.sh @@ -32,7 +32,7 @@ handlebars -n OCA.WorkflowEngine.Templates apps/workflowengine/js/templates -f a handlebars -n OCA.Sharing.Templates apps/files_sharing/js/templates -f apps/files_sharing/js/templates.js # Files external -handlebars -n OCA.External.Templates apps/files_external/js/templates -f apps/files_external/js/templates.js +handlebars -n OCA.Files_External.Templates apps/files_external/js/templates -f apps/files_external/js/templates.js if [[ $(git diff --name-only) ]]; then echo "Please submit your compiled handlebars templates" diff --git a/build/package-lock.json b/build/package-lock.json index afac3aee8bb..5248f3228cd 100644 --- a/build/package-lock.json +++ b/build/package-lock.json @@ -60,28 +60,12 @@ "negotiator": "0.6.1" } }, - "addressparser": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/addressparser/-/addressparser-1.0.1.tgz", - "integrity": "sha1-R6++GiqSYhkdtoOOT9HTm0CCF0Y=", - "dev": true, - "optional": true - }, "after": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", "dev": true }, - "agent-base": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", - "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", - "dev": true, - "requires": { - "es6-promisify": "^5.0.0" - } - }, "ajv": { "version": "5.5.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", @@ -100,42 +84,6 @@ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", "dev": true }, - "amqplib": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.5.2.tgz", - "integrity": "sha512-l9mCs6LbydtHqRniRwYkKdqxVa6XMz3Vw1fh+2gJaaVgTM6Jk3o8RccAKWKtlhT1US5sWrFh+KKxsVUALURSIA==", - "dev": true, - "optional": true, - "requires": { - "bitsyntax": "~0.0.4", - "bluebird": "^3.4.6", - "buffer-more-ints": "0.0.2", - "readable-stream": "1.x >=1.1.9", - "safe-buffer": "^5.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "1.1.14", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true, - "optional": true - } - } - }, "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", @@ -252,13 +200,6 @@ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", "dev": true }, - "ast-types": { - "version": "0.11.6", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.11.6.tgz", - "integrity": "sha512-nHiuV14upVGl7MWwFUYbzJ6YlfwWS084CU9EA8HajfYQjMSli5TQi3UTRygGF58LFWVkXxS1rbgRhROEqlQkXg==", - "dev": true, - "optional": true - }, "async": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", @@ -310,28 +251,6 @@ "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", "dev": true }, - "axios": { - "version": "0.15.3", - "resolved": "http://registry.npmjs.org/axios/-/axios-0.15.3.tgz", - "integrity": "sha1-LJ1jiy4ZGgjqHWzJiOrda6W9wFM=", - "dev": true, - "optional": true, - "requires": { - "follow-redirects": "1.0.0" - }, - "dependencies": { - "follow-redirects": { - "version": "1.0.0", - "resolved": "http://registry.npmjs.org/follow-redirects/-/follow-redirects-1.0.0.tgz", - "integrity": "sha1-jjQpjL0uF28lTv/sdaHHjMhJ/Tc=", - "dev": true, - "optional": true, - "requires": { - "debug": "^2.2.0" - } - } - } - }, "babylon": { "version": "7.0.0-beta.19", "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.19.tgz", @@ -441,67 +360,9 @@ "integrity": "sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==", "dev": true }, - "bitsyntax": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/bitsyntax/-/bitsyntax-0.0.4.tgz", - "integrity": "sha1-6xDMb4K4xJDj6FaY8H6D1G4MuoI=", - "dev": true, - "optional": true, - "requires": { - "buffer-more-ints": "0.0.2" - } - }, - "bl": { - "version": "1.1.2", - "resolved": "http://registry.npmjs.org/bl/-/bl-1.1.2.tgz", - "integrity": "sha1-/cqHGplxOqANGeO7ukHER4emU5g=", - "dev": true, - "optional": true, - "requires": { - "readable-stream": "~2.0.5" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", - "dev": true, - "optional": true - }, - "readable-stream": { - "version": "2.0.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", - "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~0.10.x", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true, - "optional": true - } - } - }, "blob": { "version": "0.0.4", - "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz", + "resolved": "http://registry.npmjs.org/blob/-/blob-0.0.4.tgz", "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=", "dev": true }, @@ -538,15 +399,6 @@ "type-is": "~1.6.16" } }, - "boom": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", - "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", - "dev": true, - "requires": { - "hoek": "2.x.x" - } - }, "bower": { "version": "1.8.4", "resolved": "https://registry.npmjs.org/bower/-/bower-1.8.4.tgz", @@ -620,28 +472,6 @@ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", "dev": true }, - "buffer-more-ints": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-0.0.2.tgz", - "integrity": "sha1-JrOIXRD6E9t/wBquOquHAZngEkw=", - "dev": true - }, - "buildmail": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/buildmail/-/buildmail-4.0.1.tgz", - "integrity": "sha1-h393OLeHKYccmhBeO4N9K+EaenI=", - "dev": true, - "optional": true, - "requires": { - "addressparser": "1.0.1", - "libbase64": "0.1.0", - "libmime": "3.0.0", - "libqp": "1.1.0", - "nodemailer-fetch": "1.6.0", - "nodemailer-shared": "1.1.0", - "punycode": "1.4.1" - } - }, "builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", @@ -751,9 +581,9 @@ } }, "circular-json": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.7.tgz", - "integrity": "sha512-/pXoV1JA847qRKPrHbBK6YIBGFF8GOP4wzSgUOA7q0ew0vAv0iJswP+2/nZQ9uzA3Azi7eTrg9L2yzXc/7ZMIA==", + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.9.tgz", + "integrity": "sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ==", "dev": true }, "class-utils": { @@ -937,16 +767,6 @@ "which": "^1.2.9" } }, - "cryptiles": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", - "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", - "dev": true, - "optional": true, - "requires": { - "boom": "2.x.x" - } - }, "currently-unhandled": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", @@ -971,13 +791,6 @@ "assert-plus": "^1.0.0" } }, - "data-uri-to-buffer": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz", - "integrity": "sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ==", - "dev": true, - "optional": true - }, "date-format": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/date-format/-/date-format-1.2.0.tgz", @@ -1062,18 +875,6 @@ } } }, - "degenerator": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-1.0.4.tgz", - "integrity": "sha1-/PSQo37OJmRk2cxDGrmMWBnO0JU=", - "dev": true, - "optional": true, - "requires": { - "ast-types": "0.x.x", - "escodegen": "1.x.x", - "esprima": "3.x.x" - } - }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -1116,13 +917,6 @@ "void-elements": "^2.0.0" } }, - "double-ended-queue": { - "version": "2.1.0-0", - "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", - "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=", - "dev": true, - "optional": true - }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -1146,9 +940,9 @@ "dev": true }, "engine.io": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.1.5.tgz", - "integrity": "sha512-D06ivJkYxyRrcEe0bTpNnBQNgP9d3xog+qZlLbui8EsMr/DouQpf5o9FzJnWYHEYE0YsFHllUv2R1dkgYZXHcA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.2.0.tgz", + "integrity": "sha512-mRbgmAtQ4GAlKwuPnnAvXXwdPhEx+jkc0OBCLrXuD/CRvwNK3AxRSnqK4FSqmAMRRHryVJP8TopOvmEaA64fKw==", "dev": true, "requires": { "accepts": "~1.3.4", @@ -1156,7 +950,6 @@ "cookie": "0.3.1", "debug": "~3.1.0", "engine.io-parser": "~2.1.0", - "uws": "~9.14.0", "ws": "~3.3.1" }, "dependencies": { @@ -1172,9 +965,9 @@ } }, "engine.io-client": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.1.6.tgz", - "integrity": "sha512-hnuHsFluXnsKOndS4Hv6SvUrgdYx1pk2NqfaDMW+GWdgfU3+/V25Cj7I8a0x92idSpa5PIhJRKxPvp9mnoLsfg==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz", + "integrity": "sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw==", "dev": true, "requires": { "component-emitter": "1.2.1", @@ -1235,15 +1028,6 @@ "integrity": "sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg==", "dev": true }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "dev": true, - "requires": { - "es6-promise": "^4.0.3" - } - }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -1256,33 +1040,6 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, - "escodegen": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.11.0.tgz", - "integrity": "sha512-IeMV45ReixHS53K/OmfKAIztN/igDHzTJUhZM3k1jMhIZWjk45SMwAtBsEXiJp3vSPmTcu6CXn7mDvFHRN66fw==", - "dev": true, - "optional": true, - "requires": { - "esprima": "^3.1.3", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" - } - }, - "esprima": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", - "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", - "dev": true - }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true, - "optional": true - }, "esutils": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", @@ -1519,13 +1276,6 @@ "pend": "~1.2.0" } }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, "fill-range": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", @@ -1714,12 +1464,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1734,17 +1486,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -1861,7 +1616,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -1873,6 +1629,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -1887,6 +1644,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -1894,12 +1652,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.2.4", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -1918,6 +1678,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -1998,7 +1759,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -2010,6 +1772,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -2131,6 +1894,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -2214,39 +1978,6 @@ "rimraf": "2" } }, - "ftp": { - "version": "0.3.10", - "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz", - "integrity": "sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=", - "dev": true, - "optional": true, - "requires": { - "readable-stream": "1.1.x", - "xregexp": "2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "1.1.14", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true, - "optional": true - } - } - }, "gauge": { "version": "2.7.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", @@ -2272,26 +2003,6 @@ "globule": "^1.0.0" } }, - "generate-function": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", - "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", - "dev": true, - "optional": true, - "requires": { - "is-property": "^1.0.2" - } - }, - "generate-object-property": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", - "dev": true, - "optional": true, - "requires": { - "is-property": "^1.0.0" - } - }, "get-caller-file": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", @@ -2304,21 +2015,6 @@ "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", "dev": true }, - "get-uri": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-2.0.2.tgz", - "integrity": "sha512-ZD325dMZOgerGqF/rF6vZXyFGTAay62svjQIT+X/oU2PtxYpFxvSkbsdi+oxIrsNxlZVd4y8wUDqkaExWTI/Cw==", - "dev": true, - "optional": true, - "requires": { - "data-uri-to-buffer": "1", - "debug": "2", - "extend": "3", - "file-uri-to-path": "1", - "ftp": "~0.3.10", - "readable-stream": "2" - } - }, "get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", @@ -2500,36 +2196,6 @@ "pinkie-promise": "^2.0.0" } }, - "hawk": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", - "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", - "dev": true, - "optional": true, - "requires": { - "boom": "2.x.x", - "cryptiles": "2.x.x", - "hoek": "2.x.x", - "sntp": "1.x.x" - } - }, - "hipchat-notifier": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/hipchat-notifier/-/hipchat-notifier-1.1.0.tgz", - "integrity": "sha1-ttJJdVQ3wZEII2d5nTupoPI7Ix4=", - "dev": true, - "optional": true, - "requires": { - "lodash": "^4.0.0", - "request": "^2.0.0" - } - }, - "hoek": { - "version": "2.16.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", - "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", - "dev": true - }, "hosted-git-info": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", @@ -2559,27 +2225,6 @@ "requires-port": "^1.0.0" } }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "dev": true, - "requires": { - "agent-base": "4", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -2591,57 +2236,6 @@ "sshpk": "^1.7.0" } }, - "httpntlm": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/httpntlm/-/httpntlm-1.6.1.tgz", - "integrity": "sha1-rQFScUOi6Hc8+uapb1hla7UqNLI=", - "dev": true, - "requires": { - "httpreq": ">=0.4.22", - "underscore": "~1.7.0" - }, - "dependencies": { - "underscore": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz", - "integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=", - "dev": true - } - } - }, - "httpreq": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/httpreq/-/httpreq-0.4.24.tgz", - "integrity": "sha1-QzX/2CzZaWaKOUZckprGHWOTYn8=", - "dev": true - }, - "https-proxy-agent": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", - "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", - "dev": true, - "requires": { - "agent-base": "^4.1.0", - "debug": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - } - } - }, "iconv-lite": { "version": "0.4.23", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", @@ -2672,13 +2266,6 @@ "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", "dev": true }, - "inflection": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.12.0.tgz", - "integrity": "sha1-ogCTVlbW9fa8TcdQLhrstwMihBY=", - "dev": true, - "optional": true - }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -2701,12 +2288,6 @@ "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", "dev": true }, - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "dev": true - }, "is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", @@ -2835,27 +2416,6 @@ "is-extglob": "^2.1.1" } }, - "is-my-ip-valid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", - "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", - "dev": true, - "optional": true - }, - "is-my-json-valid": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.19.0.tgz", - "integrity": "sha512-mG0f/unGX1HZ5ep4uhRaPOS8EkAY8/j6mDRMJrutq4CqhoJWYp7qAlonIPy3TV7p3ju4TK9fo/PbnoksWmsp5Q==", - "dev": true, - "optional": true, - "requires": { - "generate-function": "^2.0.0", - "generate-object-property": "^1.1.0", - "is-my-ip-valid": "^1.0.0", - "jsonpointer": "^4.0.0", - "xtend": "^4.0.0" - } - }, "is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", @@ -2885,12 +2445,6 @@ "isobject": "^3.0.1" } }, - "is-property": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", - "dev": true - }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", @@ -3148,13 +2702,6 @@ "graceful-fs": "^4.1.6" } }, - "jsonpointer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", - "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", - "dev": true, - "optional": true - }, "jsonschema": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.2.4.tgz", @@ -3180,9 +2727,9 @@ "dev": true }, "karma": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/karma/-/karma-2.0.5.tgz", - "integrity": "sha512-rECezBeY7mjzGUWhFlB7CvPHgkHJLXyUmWg+6vHCEsdWNUTnmiS6jRrIMcJEWgU2DUGZzGWG0bTRVky8fsDTOA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/karma/-/karma-3.1.1.tgz", + "integrity": "sha512-NetT3wPCQMNB36uiL9LLyhrOt8SQwrEKt0xD3+KpTCfm0VxVyUJdPL5oTq2Ic5ouemgL/Iz4wqXEbF3zea9kQQ==", "dev": true, "requires": { "bluebird": "^3.3.0", @@ -3200,15 +2747,15 @@ "http-proxy": "^1.13.0", "isbinaryfile": "^3.0.0", "lodash": "^4.17.4", - "log4js": "^2.5.3", - "mime": "^1.3.4", + "log4js": "^3.0.0", + "mime": "^2.3.1", "minimatch": "^3.0.2", "optimist": "^0.6.1", "qjobs": "^1.1.4", "range-parser": "^1.2.0", "rimraf": "^2.6.0", "safe-buffer": "^5.0.1", - "socket.io": "2.0.4", + "socket.io": "2.1.1", "source-map": "^0.6.1", "tmp": "0.0.33", "useragent": "2.2.1" @@ -3317,37 +2864,6 @@ "type-check": "~0.3.2" } }, - "libbase64": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/libbase64/-/libbase64-0.1.0.tgz", - "integrity": "sha1-YjUag5VjrF/1vSbxL2Dpgwu3UeY=", - "dev": true - }, - "libmime": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/libmime/-/libmime-3.0.0.tgz", - "integrity": "sha1-UaGp50SOy9Ms2lRCFnW7IbwJPaY=", - "dev": true, - "requires": { - "iconv-lite": "0.4.15", - "libbase64": "0.1.0", - "libqp": "1.1.0" - }, - "dependencies": { - "iconv-lite": { - "version": "0.4.15", - "resolved": "http://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz", - "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es=", - "dev": true - } - } - }, - "libqp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/libqp/-/libqp-1.1.0.tgz", - "integrity": "sha1-9ebgatdLeU+1tbZpiL9yjvHe2+g=", - "dev": true - }, "load-json-file": { "version": "1.1.0", "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", @@ -3398,23 +2914,15 @@ "dev": true }, "log4js": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-2.11.0.tgz", - "integrity": "sha512-z1XdwyGFg8/WGkOyF6DPJjivCWNLKrklGdViywdYnSKOvgtEBo2UyEMZS5sD2mZrQlU3TvO8wDWLc8mzE1ncBQ==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-3.0.6.tgz", + "integrity": "sha512-ezXZk6oPJCWL483zj64pNkMuY/NcRX5MPiB0zE6tjZM137aeusrOnW1ecxgF9cmwMWkBMhjteQxBPoZBh9FDxQ==", "dev": true, "requires": { - "amqplib": "^0.5.2", - "axios": "^0.15.3", - "circular-json": "^0.5.4", + "circular-json": "^0.5.5", "date-format": "^1.2.0", "debug": "^3.1.0", - "hipchat-notifier": "^1.1.0", - "loggly": "^1.1.0", - "mailgun-js": "^0.18.0", - "nodemailer": "^2.5.0", - "redis": "^2.7.1", - "semver": "^5.5.0", - "slack-node": "~0.2.0", + "rfdc": "^1.1.2", "streamroller": "0.7.0" }, "dependencies": { @@ -3435,146 +2943,6 @@ } } }, - "loggly": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/loggly/-/loggly-1.1.1.tgz", - "integrity": "sha1-Cg/B0/o6XsRP3HuJe+uipGlc6+4=", - "dev": true, - "optional": true, - "requires": { - "json-stringify-safe": "5.0.x", - "request": "2.75.x", - "timespan": "2.3.x" - }, - "dependencies": { - "assert-plus": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", - "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", - "dev": true, - "optional": true - }, - "aws-sign2": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", - "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", - "dev": true, - "optional": true - }, - "caseless": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", - "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=", - "dev": true, - "optional": true - }, - "form-data": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.0.0.tgz", - "integrity": "sha1-bwrrrcxdoWwT4ezBETfYX5uIOyU=", - "dev": true, - "optional": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.5", - "mime-types": "^2.1.11" - } - }, - "har-validator": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", - "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", - "dev": true, - "optional": true, - "requires": { - "chalk": "^1.1.1", - "commander": "^2.9.0", - "is-my-json-valid": "^2.12.4", - "pinkie-promise": "^2.0.0" - } - }, - "http-signature": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", - "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", - "dev": true, - "optional": true, - "requires": { - "assert-plus": "^0.2.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "node-uuid": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", - "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=", - "dev": true, - "optional": true - }, - "oauth-sign": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", - "dev": true, - "optional": true - }, - "qs": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.3.tgz", - "integrity": "sha1-HPyyXBCpsrSDBT/zn138kjOQjP4=", - "dev": true, - "optional": true - }, - "request": { - "version": "2.75.0", - "resolved": "http://registry.npmjs.org/request/-/request-2.75.0.tgz", - "integrity": "sha1-0rgmiihtoT6qXQGt9dGMyQ9lfZM=", - "dev": true, - "optional": true, - "requires": { - "aws-sign2": "~0.6.0", - "aws4": "^1.2.1", - "bl": "~1.1.2", - "caseless": "~0.11.0", - "combined-stream": "~1.0.5", - "extend": "~3.0.0", - "forever-agent": "~0.6.1", - "form-data": "~2.0.0", - "har-validator": "~2.0.6", - "hawk": "~3.1.3", - "http-signature": "~1.1.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.7", - "node-uuid": "~1.4.7", - "oauth-sign": "~0.8.1", - "qs": "~6.2.0", - "stringstream": "~0.0.4", - "tough-cookie": "~2.3.0", - "tunnel-agent": "~0.4.1" - } - }, - "tough-cookie": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", - "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", - "dev": true, - "optional": true, - "requires": { - "punycode": "^1.4.1" - } - }, - "tunnel-agent": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", - "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", - "dev": true, - "optional": true - } - } - }, "lolex": { "version": "2.7.5", "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz", @@ -3601,47 +2969,6 @@ "yallist": "^2.1.2" } }, - "mailcomposer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/mailcomposer/-/mailcomposer-4.0.1.tgz", - "integrity": "sha1-DhxEsqB890DuF9wUm6AJ8Zyt/rQ=", - "dev": true, - "optional": true, - "requires": { - "buildmail": "4.0.1", - "libmime": "3.0.0" - } - }, - "mailgun-js": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/mailgun-js/-/mailgun-js-0.18.1.tgz", - "integrity": "sha512-lvuMP14u24HS2uBsJEnzSyPMxzU2b99tQsIx1o6QNjqxjk8b3WvR+vq5oG1mjqz/IBYo+5gF+uSoDS0RkMVHmg==", - "dev": true, - "optional": true, - "requires": { - "async": "~2.6.0", - "debug": "~3.1.0", - "form-data": "~2.3.0", - "inflection": "~1.12.0", - "is-stream": "^1.1.0", - "path-proxy": "~1.0.0", - "promisify-call": "^2.0.2", - "proxy-agent": "~3.0.0", - "tsscmp": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, "map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", @@ -3671,7 +2998,7 @@ }, "media-typer": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", "dev": true }, @@ -3723,9 +3050,9 @@ } }, "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz", + "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==", "dev": true }, "mime-db": { @@ -3833,13 +3160,6 @@ "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", "dev": true }, - "netmask": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/netmask/-/netmask-1.0.6.tgz", - "integrity": "sha1-ICl+idhvb2QA8lDZ9Pa0wZRfzTU=", - "dev": true, - "optional": true - }, "nise": { "version": "1.4.6", "resolved": "https://registry.npmjs.org/nise/-/nise-1.4.6.tgz", @@ -3919,98 +3239,6 @@ "true-case-path": "^1.0.2" } }, - "nodemailer": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-2.7.2.tgz", - "integrity": "sha1-8kLmSa7q45tsftdA73sGHEBNMPk=", - "dev": true, - "optional": true, - "requires": { - "libmime": "3.0.0", - "mailcomposer": "4.0.1", - "nodemailer-direct-transport": "3.3.2", - "nodemailer-shared": "1.1.0", - "nodemailer-smtp-pool": "2.8.2", - "nodemailer-smtp-transport": "2.7.2", - "socks": "1.1.9" - }, - "dependencies": { - "smart-buffer": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-1.1.15.tgz", - "integrity": "sha1-fxFLW2X6s+KjWqd1uxLw0cZJvxY=", - "dev": true, - "optional": true - }, - "socks": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/socks/-/socks-1.1.9.tgz", - "integrity": "sha1-Yo1+TQSRJDVEWsC25Fk3bLPm1pE=", - "dev": true, - "optional": true, - "requires": { - "ip": "^1.1.2", - "smart-buffer": "^1.0.4" - } - } - } - }, - "nodemailer-direct-transport": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/nodemailer-direct-transport/-/nodemailer-direct-transport-3.3.2.tgz", - "integrity": "sha1-6W+vuQNYVglH5WkBfZfmBzilCoY=", - "dev": true, - "optional": true, - "requires": { - "nodemailer-shared": "1.1.0", - "smtp-connection": "2.12.0" - } - }, - "nodemailer-fetch": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/nodemailer-fetch/-/nodemailer-fetch-1.6.0.tgz", - "integrity": "sha1-ecSQihwPXzdbc/6IjamCj23JY6Q=", - "dev": true - }, - "nodemailer-shared": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/nodemailer-shared/-/nodemailer-shared-1.1.0.tgz", - "integrity": "sha1-z1mU4v0mjQD1zw+nZ6CBae2wfsA=", - "dev": true, - "requires": { - "nodemailer-fetch": "1.6.0" - } - }, - "nodemailer-smtp-pool": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/nodemailer-smtp-pool/-/nodemailer-smtp-pool-2.8.2.tgz", - "integrity": "sha1-LrlNbPhXgLG0clzoU7nL1ejajHI=", - "dev": true, - "optional": true, - "requires": { - "nodemailer-shared": "1.1.0", - "nodemailer-wellknown": "0.1.10", - "smtp-connection": "2.12.0" - } - }, - "nodemailer-smtp-transport": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/nodemailer-smtp-transport/-/nodemailer-smtp-transport-2.7.2.tgz", - "integrity": "sha1-A9ccdjFPFKx9vHvwM6am0W1n+3c=", - "dev": true, - "optional": true, - "requires": { - "nodemailer-shared": "1.1.0", - "nodemailer-wellknown": "0.1.10", - "smtp-connection": "2.12.0" - } - }, - "nodemailer-wellknown": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/nodemailer-wellknown/-/nodemailer-wellknown-0.1.10.tgz", - "integrity": "sha1-WG24EB2zDLRDjrVGc3pBqtDPE9U=", - "dev": true - }, "nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", @@ -4207,56 +3435,6 @@ "os-tmpdir": "^1.0.0" } }, - "pac-proxy-agent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-3.0.0.tgz", - "integrity": "sha512-AOUX9jES/EkQX2zRz0AW7lSx9jD//hQS8wFXBvcnd/J2Py9KaMJMqV/LPqJssj1tgGufotb2mmopGPR15ODv1Q==", - "dev": true, - "optional": true, - "requires": { - "agent-base": "^4.2.0", - "debug": "^3.1.0", - "get-uri": "^2.0.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1", - "pac-resolver": "^3.0.0", - "raw-body": "^2.2.0", - "socks-proxy-agent": "^4.0.1" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true, - "optional": true - } - } - }, - "pac-resolver": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-3.0.0.tgz", - "integrity": "sha512-tcc38bsjuE3XZ5+4vP96OfhOugrX+JcnpUbhfuc4LuXBLQhoTthOstZeoQJBDnQUDYzYmdImKsbz0xSl1/9qeA==", - "dev": true, - "optional": true, - "requires": { - "co": "^4.6.0", - "degenerator": "^1.0.4", - "ip": "^1.1.5", - "netmask": "^1.0.6", - "thunkify": "^2.1.2" - } - }, "parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", @@ -4317,25 +3495,6 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, - "path-proxy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/path-proxy/-/path-proxy-1.0.0.tgz", - "integrity": "sha1-GOijaFn8nS8aU7SN7hOFQ8Ag3l4=", - "dev": true, - "optional": true, - "requires": { - "inflection": "~1.3.0" - }, - "dependencies": { - "inflection": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.3.8.tgz", - "integrity": "sha1-y9Fg2p91sUw8xjV41POWeEvzAU4=", - "dev": true, - "optional": true - } - } - }, "path-to-regexp": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", @@ -4430,59 +3589,6 @@ "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", "dev": true }, - "promisify-call": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/promisify-call/-/promisify-call-2.0.4.tgz", - "integrity": "sha1-1IwtRWUszM1SgB3ey9UzptS9X7o=", - "dev": true, - "optional": true, - "requires": { - "with-callback": "^1.0.2" - } - }, - "proxy-agent": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-3.0.3.tgz", - "integrity": "sha512-PXVVVuH9tiQuxQltFJVSnXWuDtNr+8aNBP6XVDDCDiUuDN8eRCm+ii4/mFWmXWEA0w8jjJSlePa4LXlM4jIzNA==", - "dev": true, - "optional": true, - "requires": { - "agent-base": "^4.2.0", - "debug": "^3.1.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1", - "lru-cache": "^4.1.2", - "pac-proxy-agent": "^3.0.0", - "proxy-from-env": "^1.0.0", - "socks-proxy-agent": "^4.0.1" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true, - "optional": true - } - } - }, - "proxy-from-env": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", - "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=", - "dev": true, - "optional": true - }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", @@ -4596,32 +3702,6 @@ "strip-indent": "^1.0.1" } }, - "redis": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz", - "integrity": "sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A==", - "dev": true, - "optional": true, - "requires": { - "double-ended-queue": "^2.1.0-0", - "redis-commands": "^1.2.0", - "redis-parser": "^2.6.0" - } - }, - "redis-commands": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.4.0.tgz", - "integrity": "sha512-cu8EF+MtkwI4DLIT0x9P8qNTLFhQD4jLfxLR0cCNkeGzs87FN6879JOJwNQR/1zD7aSYNbU0hgsV9zGY71Itvw==", - "dev": true, - "optional": true - }, - "redis-parser": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz", - "integrity": "sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs=", - "dev": true, - "optional": true - }, "regex-not": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", @@ -4696,19 +3776,6 @@ "throttleit": "^1.0.0" } }, - "requestretry": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/requestretry/-/requestretry-1.13.0.tgz", - "integrity": "sha512-Lmh9qMvnQXADGAQxsXHP4rbgO6pffCfuR8XUBdP9aitJcLQJxhp7YZK4xAVYXnPJ5E52mwrfiKQtKonPL8xsmg==", - "dev": true, - "optional": true, - "requires": { - "extend": "^3.0.0", - "lodash": "^4.15.0", - "request": "^2.74.0", - "when": "^3.7.7" - } - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -4762,6 +3829,12 @@ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "dev": true }, + "rfdc": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.1.2.tgz", + "integrity": "sha512-92ktAgvZhBzYTIK0Mja9uen5q5J3NRVMoDkJL2VMwq6SXjVCgqvQeVP2XAaUY6HT+XpQYeLSjb3UoitBryKmdA==", + "dev": true + }, "rimraf": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", @@ -4893,32 +3966,6 @@ "type-detect": "^4.0.5" } }, - "slack-node": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/slack-node/-/slack-node-0.2.0.tgz", - "integrity": "sha1-3kuN3aqLeT9h29KTgQT9q/N9+jA=", - "dev": true, - "optional": true, - "requires": { - "requestretry": "^1.2.2" - } - }, - "smart-buffer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.0.1.tgz", - "integrity": "sha512-RFqinRVJVcCAL9Uh1oVqE6FZkqsyLiVOYEZ20TqIOjuX7iFVJ+zsbs4RIghnw/pTs7mZvt8ZHhvm1ZUrR4fykg==", - "dev": true - }, - "smtp-connection": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/smtp-connection/-/smtp-connection-2.12.0.tgz", - "integrity": "sha1-1275EnyyPCJZ7bHoNJwujV4tdME=", - "dev": true, - "requires": { - "httpntlm": "1.6.1", - "nodemailer-shared": "1.1.0" - } - }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -5032,27 +4079,29 @@ } } }, - "sntp": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", - "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", - "dev": true, - "optional": true, - "requires": { - "hoek": "2.x.x" - } - }, "socket.io": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.0.4.tgz", - "integrity": "sha1-waRZDO/4fs8TxyZS8Eb3FrKeYBQ=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.1.1.tgz", + "integrity": "sha512-rORqq9c+7W0DAK3cleWNSyfv/qKXV99hV4tZe+gGLfBECw3XEhBy7x85F3wypA9688LKjtwO9pX9L33/xQI8yA==", "dev": true, "requires": { - "debug": "~2.6.6", - "engine.io": "~3.1.0", + "debug": "~3.1.0", + "engine.io": "~3.2.0", + "has-binary2": "~1.0.2", "socket.io-adapter": "~1.1.0", - "socket.io-client": "2.0.4", - "socket.io-parser": "~3.1.1" + "socket.io-client": "2.1.1", + "socket.io-parser": "~3.2.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } } }, "socket.io-adapter": { @@ -5062,35 +4111,46 @@ "dev": true }, "socket.io-client": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.0.4.tgz", - "integrity": "sha1-CRilUkBtxeVAs4Dc2Xr8SmQzL44=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.1.1.tgz", + "integrity": "sha512-jxnFyhAuFxYfjqIgduQlhzqTcOEQSn+OHKVfAxWaNWa7ecP7xSNk2Dx/3UEsDcY7NcFafxvNvKPmmO7HTwTxGQ==", "dev": true, "requires": { "backo2": "1.0.2", "base64-arraybuffer": "0.1.5", "component-bind": "1.0.0", "component-emitter": "1.2.1", - "debug": "~2.6.4", - "engine.io-client": "~3.1.0", + "debug": "~3.1.0", + "engine.io-client": "~3.2.0", + "has-binary2": "~1.0.2", "has-cors": "1.1.0", "indexof": "0.0.1", "object-component": "0.0.3", "parseqs": "0.0.5", "parseuri": "0.0.5", - "socket.io-parser": "~3.1.1", + "socket.io-parser": "~3.2.0", "to-array": "0.1.4" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } } }, "socket.io-parser": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.1.3.tgz", - "integrity": "sha512-g0a2HPqLguqAczs3dMECuA1RgoGFPyvDqcbaDEdCWY9g59kdUAz3YRmaJBNKXflrHNwB7Q12Gkf/0CZXfdHR7g==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz", + "integrity": "sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA==", "dev": true, "requires": { "component-emitter": "1.2.1", "debug": "~3.1.0", - "has-binary2": "~1.0.2", "isarray": "2.0.1" }, "dependencies": { @@ -5111,26 +4171,6 @@ } } }, - "socks": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.2.1.tgz", - "integrity": "sha512-0GabKw7n9mI46vcNrVfs0o6XzWzjVa3h6GaSo2UPxtWAROXUWavfJWh1M4PR5tnE0dcnQXZIDFP4yrAysLze/w==", - "dev": true, - "requires": { - "ip": "^1.1.5", - "smart-buffer": "^4.0.1" - } - }, - "socks-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-4.0.1.tgz", - "integrity": "sha512-Kezx6/VBguXOsEe5oU3lXYyKMi4+gva72TwJ7pQY5JfqUx2nMk7NXA6z/mpNqIlfQjWYVfeuNvQjexiTaTn6Nw==", - "dev": true, - "requires": { - "agent-base": "~4.2.0", - "socks": "~2.2.0" - } - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -5305,13 +4345,6 @@ "safe-buffer": "~5.1.0" } }, - "stringstream": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz", - "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==", - "dev": true, - "optional": true - }, "strip-ansi": { "version": "3.0.1", "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -5383,20 +4416,6 @@ "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=", "dev": true }, - "thunkify": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/thunkify/-/thunkify-2.1.2.tgz", - "integrity": "sha1-+qDp0jDFGsyVyhOjYawFyn4EVT0=", - "dev": true, - "optional": true - }, - "timespan": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/timespan/-/timespan-2.3.0.tgz", - "integrity": "sha1-SQLOBAvRPYRcj1myfp1ZutbzmSk=", - "dev": true, - "optional": true - }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -5479,13 +4498,6 @@ "glob": "^7.1.2" } }, - "tsscmp": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz", - "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==", - "dev": true, - "optional": true - }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -5713,13 +4725,6 @@ "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", "dev": true }, - "uws": { - "version": "9.14.0", - "resolved": "https://registry.npmjs.org/uws/-/uws-9.14.0.tgz", - "integrity": "sha512-HNMztPP5A1sKuVFmdZ6BPVpBQd5bUjNC8EFMFiICK+oho/OQsAJy5hnIx4btMHiOk8j04f/DbIlqnEZ9d72dqg==", - "dev": true, - "optional": true - }, "validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -5747,13 +4752,6 @@ "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", "dev": true }, - "when": { - "version": "3.7.8", - "resolved": "https://registry.npmjs.org/when/-/when-3.7.8.tgz", - "integrity": "sha1-xxMLan6gRpPoQs3J56Hyqjmjn4I=", - "dev": true, - "optional": true - }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -5778,13 +4776,6 @@ "string-width": "^1.0.2 || 2" } }, - "with-callback": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/with-callback/-/with-callback-1.0.2.tgz", - "integrity": "sha1-oJYpuakgAo1yFAT7Q1vc/1yRvCE=", - "dev": true, - "optional": true - }, "wordwrap": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", @@ -5836,20 +4827,6 @@ "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=", "dev": true }, - "xregexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", - "integrity": "sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=", - "dev": true, - "optional": true - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true, - "optional": true - }, "y18n": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", diff --git a/build/package.json b/build/package.json index 420980c94cc..1325406b749 100644 --- a/build/package.json +++ b/build/package.json @@ -16,7 +16,7 @@ "jasmine-core": "~2.5.2", "jasmine-sinon": "^0.4.0", "jsdoc": "^3.5.5", - "karma": "^2.0.2", + "karma": "^3.1.1", "karma-coverage": "*", "karma-jasmine": "^1.1.2", "karma-jasmine-sinon": "^1.0.4", diff --git a/config/config.sample.php b/config/config.sample.php index 9a5648c95df..902bfa6e44d 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -1499,11 +1499,26 @@ $CONFIG = array( /** * List of trusted proxy servers * - * If you configure these also consider setting `forwarded_for_headers` which - * otherwise defaults to `HTTP_X_FORWARDED_FOR` (the `X-Forwarded-For` header). + * You may set this to an array containing a combination of + * - IPv4 addresses, e.g. `192.168.2.123` + * - IPv4 ranges in CIDR notation, e.g. `192.168.2.0/24` + * - IPv6 addresses, e.g. `fd9e:21a7:a92c:2323::1` + * + * _(CIDR notation for IPv6 is currently work in progress and thus not + * available as of yet)_ + * + * When an incoming request's `REMOTE_ADDR` matches any of the IP addresses + * specified here, it is assumed to be a proxy instead of a client. Thus, the + * client IP will be read from the HTTP header specified in + * `forwarded_for_headers` instead of from `REMOTE_ADDR`. + * + * So if you configure `trusted_proxies`, also consider setting + * `forwarded_for_headers` which otherwise defaults to `HTTP_X_FORWARDED_FOR` + * (the `X-Forwarded-For` header). + * * Defaults to an empty array. */ -'trusted_proxies' => array('203.0.113.45', '198.51.100.128'), +'trusted_proxies' => array('203.0.113.45', '198.51.100.128', '192.168.2.0/24'), /** * Headers that should be trusted as client IP address in combination with @@ -1648,4 +1663,14 @@ $CONFIG = array( * If this is set to "false" it will not show the link. */ 'simpleSignUpLink.shown' => true, + +/** + * By default autocompletion is enabled for the login form on Nextcloud's login page. + * While this is enabled, browsers are allowed to "remember" login names and such. + * Some companies require it to be disabled to comply with their security policy. + * + * Simply set this property to "false", if you want to turn this feature off. + */ + +'login_form_autocomplete' => true, ); diff --git a/core/Command/App/Remove.php b/core/Command/App/Remove.php new file mode 100644 index 00000000000..71d5cef229c --- /dev/null +++ b/core/Command/App/Remove.php @@ -0,0 +1,149 @@ +<?php +/** + * @copyright Copyright (c) 2018, Patrik Kernstock <info@pkern.at> + * + * @author Patrik Kernstock <info@pkern.at> + * + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + +namespace OC\Core\Command\App; + +use Throwable; +use OC\Installer; +use OCP\App\IAppManager; +use OCP\ILogger; +use Stecman\Component\Symfony\Console\BashCompletion\Completion\CompletionAwareInterface; +use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +class Remove extends Command implements CompletionAwareInterface { + + /** @var IAppManager */ + protected $manager; + /** @var Installer */ + private $installer; + /** @var ILogger */ + private $logger; + + /** + * @param IAppManager $manager + * @param Installer $installer + * @param ILogger $logger + */ + public function __construct(IAppManager $manager, Installer $installer, ILogger $logger) { + parent::__construct(); + $this->manager = $manager; + $this->installer = $installer; + $this->logger = $logger; + } + + protected function configure() { + $this + ->setName('app:remove') + ->setDescription('remove an app') + ->addArgument( + 'app-id', + InputArgument::REQUIRED, + 'remove the specified app' + ) + ->addOption( + 'keep-data', + null, + InputOption::VALUE_NONE, + 'keep app data and do not remove them' + ); + } + + protected function execute(InputInterface $input, OutputInterface $output) { + $appId = $input->getArgument('app-id'); + + // Check if the app is installed + if (!\OC_App::getAppPath($appId)) { + $output->writeln($appId . ' is not installed'); + return 1; + } + + // Removing shipped apps is not possible, therefore we pre-check that + // before trying to remove it + if ($this->manager->isShipped($appId)) { + $output->writeln($appId . ' could not be removed as it is a shipped app'); + return 1; + } + + // If we want to keep the data of the app, we simply don't disable it here. + // App uninstall tasks are being executed when disabled. More info: PR #11627. + if (!$input->getOption('keep-data')) { + try { + $this->manager->disableApp($appId); + $output->writeln($appId . ' disabled'); + } catch(Throwable $e) { + $output->writeln('<error>Error: ' . $e->getMessage() . '</error>'); + $this->logger->logException($e, [ + 'app' => 'CLI', + 'level' => ILogger::ERROR + ]); + return 1; + } + } + + // Let's try to remove the app... + try { + $result = $this->installer->removeApp($appId); + } catch(Throwable $e) { + $output->writeln('<error>Error: ' . $e->getMessage() . '</error>'); + $this->logger->logException($e, [ + 'app' => 'CLI', + 'level' => ILogger::ERROR + ]); + return 1; + } + + if($result === false) { + $output->writeln($appId . ' could not be removed'); + return 1; + } + + $output->writeln($appId . ' removed'); + + return 0; + } + + /** + * @param string $optionName + * @param CompletionContext $context + * @return string[] + */ + public function completeOptionValues($optionName, CompletionContext $context) { + return []; + } + + /** + * @param string $argumentName + * @param CompletionContext $context + * @return string[] + */ + public function completeArgumentValues($argumentName, CompletionContext $context) { + if ($argumentName === 'app-id') { + return \OC_App::getAllApps(); + } + return []; + } +} diff --git a/core/Controller/LoginController.php b/core/Controller/LoginController.php index a9fb22f21b7..d34f243f15f 100644 --- a/core/Controller/LoginController.php +++ b/core/Controller/LoginController.php @@ -171,6 +171,14 @@ class LoginController extends Controller { $parameters['loginName'] = ''; $parameters['user_autofocus'] = true; } + + $autocomplete = $this->config->getSystemValue('login_form_autocomplete', true); + if ($autocomplete){ + $parameters['login_form_autocomplete'] = 'on'; + } else { + $parameters['login_form_autocomplete'] = 'off'; + } + if (!empty($redirect_url)) { $parameters['redirect_url'] = $redirect_url; } diff --git a/core/Migrations/Version15000Date20181015062942.php b/core/Migrations/Version15000Date20181015062942.php new file mode 100644 index 00000000000..e73b663d2fd --- /dev/null +++ b/core/Migrations/Version15000Date20181015062942.php @@ -0,0 +1,54 @@ +<?php +declare(strict_types=1); +/** + * @copyright Copyright (c) 2018 Roeland Jago Douma <roeland@famdouma.nl> + * + * @author Roeland Jago Douma <roeland@famdouma.nl> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OC\Core\Migrations; + +use Closure; +use Doctrine\DBAL\Types\Type; +use OCP\DB\ISchemaWrapper; +use OCP\Migration\SimpleMigrationStep; +use OCP\Migration\IOutput; + +class Version15000Date20181015062942 extends SimpleMigrationStep { + + /** + * @param IOutput $output + * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` + * @param array $options + * @return null|ISchemaWrapper + */ + public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) { + /** @var ISchemaWrapper $schema */ + $schema = $schemaClosure(); + + $table = $schema->getTable('share'); + $table->addColumn('hide_download', 'smallint', [ + 'notnull' => true, + 'length' => 1, + 'default' => 0, + ]); + + return $schema; + } +} diff --git a/core/css/css-variables.scss b/core/css/css-variables.scss index a2946672294..6df2e0a3428 100644 --- a/core/css/css-variables.scss +++ b/core/css/css-variables.scss @@ -39,4 +39,6 @@ --border-radius-pill: $border-radius-pill; --font-face: $font-face; + + --animation-quick: $animation-quick; } diff --git a/core/css/functions.scss b/core/css/functions.scss index 5007c3bbe79..70c0b688fed 100644 --- a/core/css/functions.scss +++ b/core/css/functions.scss @@ -47,9 +47,9 @@ @function icon-color-path($icon, $dir, $color, $version: 1, $core: false) { $color: remove-hash-from-color($color); @if $core { - @return '#{$webroot}/svg/core/#{$dir}/#{$icon}/#{$color}?v=#{$version}'; + @return '#{$webroot}/svg/core/#{$dir}/#{$icon}?color=#{$color}&v=#{$version}'; } @else { - @return '#{$webroot}/svg/#{$dir}/#{$icon}/#{$color}?v=#{$version}'; + @return '#{$webroot}/svg/#{$dir}/#{$icon}?color=#{$color}&v=#{$version}'; } } diff --git a/core/css/global.scss b/core/css/global.scss index 9511d4324fa..06dc3688a2b 100644 --- a/core/css/global.scss +++ b/core/css/global.scss @@ -25,12 +25,12 @@ } .hidden { - display: none; + display: none !important; /* Hiding should take precedence */ } .hidden-visually { position: absolute; - left:-10000px; + left: -10000px; top: auto; width: 1px; height: 1px; @@ -47,4 +47,4 @@ .inlineblock { display: inline-block; -}
\ No newline at end of file +} diff --git a/core/css/header.scss b/core/css/header.scss index f2527ca3a79..879734097ae 100644 --- a/core/css/header.scss +++ b/core/css/header.scss @@ -513,25 +513,90 @@ nav[role='navigation'] { height: 20px; } - /* app title popup */ + /* App title */ li span { - display: none; + opacity: 0; position: absolute; - overflow: visible; - background-color: var(--color-main-background); - white-space: nowrap; - border: none; - border-radius: var(--border-radius); - border-top-left-radius: 0; - border-top-right-radius: 0; - color: var(--color-text-lighter); - width: auto; - left: 50%; - top: 100%; - transform: translateX(-50%); - padding: 4px 10px; - filter: drop-shadow(0 1px 10px var(--color-box-shadow)); - z-index: 100; + color: var(--color-primary-text); + bottom: -5px; + width: 100%; + text-align: center; + overflow: hidden; + text-overflow: ellipsis; + } + + + /* Set up transitions for showing app titles on hover */ + li { + /* Prevent flicker effect because of low-hanging span element */ + overflow-y: hidden; + + /* App icon */ + svg, + .icon-more-white { + transition: transform var(--animation-quick) ease; + } + + /* App title */ + span { + transition: all var(--animation-quick) ease; + } + + /* Triangle */ + a::before { + transition: border var(--animation-quick) ease; + } + } + + /* Show all app titles on hovering app menu area */ + &:hover { + li { + /* Move up app icon */ + svg, + .icon-more-white { + transform: translateY(-7px); + } + + /* Show app title */ + span { + opacity: .6; + bottom: 2px; + z-index: -1; /* fix clickability issue - otherwise we need to move the span into the link */ + } + + /* Prominent app title for current and hovered/focused app */ + &:hover span, + &:focus span, + .active + span { + opacity: 1; + } + + /* Smaller triangle because of limited space */ + a::before { + border-width: 5px; + } + } + } + + /* Also show app title on focusing single entry (showing all on focus is only possible with CSS4 and parent selectors) */ + li a:focus { + /* Move up app icon */ + svg, + .icon-more-white, { + transform: translateY(-7px); + } + + /* Show app title */ + & + span, + span { + opacity: 1; + bottom: 2px; + } + + /* Smaller triangle because of limited space */ + &::before { + border-width: 5px; + } } /* show triangle below active app */ @@ -549,6 +614,7 @@ nav[role='navigation'] { bottom: 0; display: none; } + /* triangle focus feedback */ li a.active::before, li:hover a::before, @@ -560,7 +626,6 @@ nav[role='navigation'] { z-index: 99; } li:hover a::before, - li:hover a::before, li a.active:hover::before, li a:focus::before { z-index: 101; diff --git a/core/css/icons.scss b/core/css/icons.scss index 5b96d1223a7..99b1dc9c215 100644 --- a/core/css/icons.scss +++ b/core/css/icons.scss @@ -466,3 +466,7 @@ img, object, video, button, textarea, input, select, div[contenteditable='true'] @include icon-color('search', 'actions', $color-black, 1, true); } + +.icon-talk { + @include icon-color('app-dark', 'spreed', $color-black, 1); +} diff --git a/core/css/inputs.scss b/core/css/inputs.scss index 2611e1bb2f4..7d30f0386c9 100644 --- a/core/css/inputs.scss +++ b/core/css/inputs.scss @@ -163,6 +163,7 @@ input[type='reset'] { padding: 6px 12px; width: auto; min-height: 34px; + display: inline-block; cursor: pointer; box-sizing: border-box; background-color: var(--color-background-dark); diff --git a/core/css/jquery-ui-fixes.scss b/core/css/jquery-ui-fixes.scss index e30beee44e5..eab22e70d62 100644 --- a/core/css/jquery-ui-fixes.scss +++ b/core/css/jquery-ui-fixes.scss @@ -70,7 +70,8 @@ .ui-widget-header .ui-state-highlight { border: 1px solid var(--color-main-background); background: var(--color-main-background) none; - color: var(--color-text-lighter); + color: var(--color-text-light); + font-weight: 600; } .ui-state-highlight a, .ui-widget-content .ui-state-highlight a, @@ -171,9 +172,12 @@ &.ui-menu { padding: 0; .ui-menu-item a { + color: var(--color-text-lighter); + padding: 4px 4px 4px 14px; + &.ui-state-focus, &.ui-state-active { - font-weight: inherit; box-shadow: inset 4px 0 var(--color-primary); + color: var(--color-text); } } } diff --git a/core/css/styles.scss b/core/css/styles.scss index 4b80b4f9626..f23f4c2dead 100644 --- a/core/css/styles.scss +++ b/core/css/styles.scss @@ -798,7 +798,7 @@ code { &.view-grid { $grid-size: 120px; $grid-pad: 10px; - $name-height: 20px; + $name-height: 30px; display: flex; flex-direction: column; @@ -818,20 +818,22 @@ code { flex-direction: column; width: $grid-size - 2 * $grid-pad; + td { border: none; padding: 0; + text-align: center; + border-radius: var(--border-radius); &.filename { padding: #{$grid-size - 2 * $grid-pad} 0 0 0; background-position: center top; background-size: contain; line-height: $name-height; - height: $name-height; } &.filesize { - line-height: $name-height; - text-align: left; + line-height: $name-height / 3; + width: 100%; } &.date { display: none; diff --git a/core/css/variables.scss b/core/css/variables.scss index dffd6403471..a827629479c 100644 --- a/core/css/variables.scss +++ b/core/css/variables.scss @@ -80,6 +80,7 @@ $border-radius-pill: 100px !default; $font-face: 'Nunito', 'Open Sans', Frutiger, Calibri, 'Myriad Pro', Myriad, sans-serif !default; +$animation-quick: 100ms; // various structure data $header-height: 50px; diff --git a/core/js/share/sharedialoglinkshareview_popover_menu.handlebars b/core/js/share/sharedialoglinkshareview_popover_menu.handlebars index 412ed8efca0..baee3aa6630 100644 --- a/core/js/share/sharedialoglinkshareview_popover_menu.handlebars +++ b/core/js/share/sharedialoglinkshareview_popover_menu.handlebars @@ -11,6 +11,16 @@ <input id="linkText-{{cid}}" class="linkText" type="text" readonly="readonly" value="{{shareLinkURL}}" /> </span> </li> + {{#if showHideDownloadCheckbox}} + <li> + <span class="shareOption menuitem"> + <span class="icon-loading-small hidden"></span> + <input type="checkbox" name="hideDownload" id="sharingDialogHideDownload-{{cid}}" class="checkbox hideDownloadCheckbox" + {{#if hideDownload}}checked="checked"{{/if}} /> + <label for="sharingDialogHideDownload-{{cid}}">{{hideDownloadLabel}}</label> + </span> + </li> + {{/if}} {{#if publicUpload}} <li> <span class="shareOption menuitem"> diff --git a/core/js/sharedialoglinkshareview.js b/core/js/sharedialoglinkshareview.js index aac4843c8e0..7603b058a96 100644 --- a/core/js/sharedialoglinkshareview.js +++ b/core/js/sharedialoglinkshareview.js @@ -47,6 +47,8 @@ 'change .linkCheckbox': 'onLinkCheckBoxChange', // open menu 'click .share-menu .icon-more': 'onToggleMenu', + // hide download + 'change .hideDownloadCheckbox': 'onHideDownloadChange', // password 'focusout input.linkPassText': 'onPasswordEntered', 'keyup input.linkPassText': 'onPasswordKeyUp', @@ -179,6 +181,20 @@ $el.select(); }, + onHideDownloadChange: function() { + var $checkbox = this.$('.hideDownloadCheckbox'); + $checkbox.siblings('.icon-loading-small').removeClass('hidden').addClass('inlineblock'); + + var hideDownload = false; + if($checkbox.is(':checked')) { + hideDownload = true; + } + + this.model.saveLinkShare({ + hideDownload: hideDownload + }); + }, + onShowPasswordClick: function() { this.$el.find('.linkPass').slideToggle(OC.menuSpeed); this.$el.find('.linkPassMenu').toggleClass('hidden'); @@ -401,6 +417,9 @@ var passwordPlaceholderInitial = this.configModel.get('enforcePasswordForPublicLink') ? PASSWORD_PLACEHOLDER_MESSAGE : PASSWORD_PLACEHOLDER_MESSAGE_OPTIONAL; + var showHideDownloadCheckbox = !this.model.isFolder(); + var hideDownload = this.model.get('linkShare').hideDownload; + var publicEditable = !this.model.isFolder() && isLinkShare @@ -464,6 +483,9 @@ shareLinkURL: this.model.get('linkShare').link, urlLabel: t('core', 'Link'), + showHideDownloadCheckbox: showHideDownloadCheckbox, + hideDownload: hideDownload, + hideDownloadLabel: t('core', 'Hide download'), enablePasswordLabel: t('core', 'Password protect'), passwordLabel: t('core', 'Password'), passwordPlaceholder: isPasswordSet ? PASSWORD_PLACEHOLDER : PASSWORD_PLACEHOLDER_MESSAGE, diff --git a/core/js/sharedialogview.js b/core/js/sharedialogview.js index 9c648357e61..082bf9571d7 100644 --- a/core/js/sharedialogview.js +++ b/core/js/sharedialogview.js @@ -312,6 +312,41 @@ var suggestions = exactMatches.concat(users).concat(groups).concat(remotes).concat(remoteGroups).concat(emails).concat(circles).concat(rooms).concat(lookup); + function dynamicSort(property) { + return function (a,b) { + var aProperty = ''; + var bProperty = ''; + if (typeof a[property] !== 'undefined') { + aProperty = a[property]; + } + if (typeof b[property] !== 'undefined') { + bProperty = b[property]; + } + return (aProperty < bProperty) ? -1 : (aProperty > bProperty) ? 1 : 0; + } + } + + /** + * Sort share entries by uuid to properly group them + */ + var grouped = suggestions.sort(dynamicSort('uuid')); + + var previousUuid = null; + var groupedLength = grouped.length; + var result = []; + /** + * build the result array that only contains all contact entries from + * merged contacts, if the search term matches its contact name + */ + for (i = 0; i < groupedLength; i++) { + if (typeof grouped[i].uuid !== 'undefined' && grouped[i].uuid === previousUuid) { + grouped[i].merged = true; + } + if (searchTerm === grouped[i].name || typeof grouped[i].merged === 'undefined') { + result.push(grouped[i]); + } + previousUuid = grouped[i].uuid; + } var moreResultsAvailable = ( oc_config['sharing.maxAutocompleteResults'] > 0 @@ -328,7 +363,7 @@ ) ); - deferred.resolve(suggestions, exactMatches, moreResultsAvailable); + deferred.resolve(result, exactMatches, moreResultsAvailable); } else { deferred.reject(result.ocs.meta.message); } @@ -441,33 +476,72 @@ }, autocompleteRenderItem: function(ul, item) { - + var icon = 'icon-user'; var text = item.label; + if (typeof item.name !== 'undefined') { + text = item.name; + } if (item.value.shareType === OC.Share.SHARE_TYPE_GROUP) { - text = t('core', '{sharee} (group)', { sharee: text }, undefined, { escape: false }); + icon = 'icon-contacts-dark'; } else if (item.value.shareType === OC.Share.SHARE_TYPE_REMOTE) { - text = t('core', '{sharee} (remote)', {sharee: text}, undefined, {escape: false}); + icon = 'icon-shared'; } else if (item.value.shareType === OC.Share.SHARE_TYPE_REMOTE_GROUP) { text = t('core', '{sharee} (remote group)', { sharee: text }, undefined, { escape: false }); + icon = 'icon-shared'; } else if (item.value.shareType === OC.Share.SHARE_TYPE_EMAIL) { - text = t('core', '{sharee} (email)', { sharee: text }, undefined, { escape: false }); + icon = 'icon-mail'; } else if (item.value.shareType === OC.Share.SHARE_TYPE_CIRCLE) { text = t('core', '{sharee} ({type}, {owner})', {sharee: text, type: item.value.circleInfo, owner: item.value.circleOwner}, undefined, {escape: false}); + icon = 'icon-circle'; } else if (item.value.shareType === OC.Share.SHARE_TYPE_ROOM) { - text = t('core', '{sharee} (conversation)', { sharee: text }, undefined, { escape: false }); + icon = 'icon-talk'; + } + var description = ''; + var getTranslatedType = function(type) { + switch (type) { + case 'HOME': + return t('core', 'Home'); + case 'WORK': + return t('core', 'Home'); + case 'OTHER': + return t('core', 'Other'); + default: + return type; + } + }; + if (typeof item.type !== 'undefined' && item.type !== null) { + description = getTranslatedType(item.type); } var insert = $("<div class='share-autocomplete-item'/>"); - var avatar = $("<div class='avatardiv'></div>").appendTo(insert); - if (item.value.shareType === OC.Share.SHARE_TYPE_USER || item.value.shareType === OC.Share.SHARE_TYPE_CIRCLE) { - avatar.avatar(item.value.shareWith, 32, undefined, undefined, undefined, item.label); + if (item.merged) { + insert.addClass('merged'); + text = item.value.shareWith; } else { - avatar.imageplaceholder(text, undefined, 32); + var avatar = $("<div class='avatardiv'></div>").appendTo(insert); + if (item.value.shareType === OC.Share.SHARE_TYPE_USER || item.value.shareType === OC.Share.SHARE_TYPE_CIRCLE) { + avatar.avatar(item.value.shareWith, 32, undefined, undefined, undefined, item.label); + } else { + if (typeof item.uuid === 'undefined') { + item.uuid = text; + } + avatar.imageplaceholder(item.uuid, text, 32); + } + description = item.value.shareWith; + } + if (description !== '') { + insert.addClass('with-description'); } $("<div class='autocomplete-item-text'></div>") - .text(text) + .html( + text.replace( + new RegExp(this.term, "gi"), + "<span class='ui-state-highlight'>$&</span>") + + '<span class="autocomplete-item-details">' + description + '</span>' + ) .appendTo(insert); insert.attr('title', item.value.shareWith); + insert.append('<span class="icon '+icon+'" title="' + text + '"></span>'); insert = $("<a>") .append(insert); return $("<li>") @@ -479,6 +553,20 @@ _onSelectRecipient: function(e, s) { var self = this; + if (e.keyCode == 9) { + e.preventDefault(); + if (typeof s.item.name !== 'undefined') { + e.target.value = s.item.name; + } else { + e.target.value = s.item.label; + } + setTimeout(function() { + $(e.target).attr('disabled', false) + .autocomplete('search', $(e.target).val()); + }, 0); + return false; + } + e.preventDefault(); // Ensure that the keydown handler for the input field is not // called; otherwise it would try to add the recipient again, which diff --git a/core/js/shareitemmodel.js b/core/js/shareitemmodel.js index f4a3caf1370..3f92a8591e5 100644 --- a/core/js/shareitemmodel.js +++ b/core/js/shareitemmodel.js @@ -18,6 +18,7 @@ * @typedef {object} OC.Share.Types.LinkShareInfo * @property {bool} isLinkShare * @property {string} token + * @property {bool} hideDownload * @property {string|null} password * @property {string} link * @property {number} permissions @@ -136,6 +137,7 @@ call = this.updateShare(shareId, attributes, options); } else { attributes = _.defaults(attributes, { + hideDownload: false, password: '', passwordChanged: false, permissions: OC.PERMISSION_READ, @@ -866,6 +868,9 @@ isLinkShare: true, id: share.id, token: share.token, + // hide_download is returned as an int, so force it + // to a boolean + hideDownload: !!share.hide_download, password: share.share_with, link: link, permissions: share.permissions, diff --git a/core/js/sharetemplates.js b/core/js/sharetemplates.js index efdd3ff6606..0c1fee37455 100644 --- a/core/js/sharetemplates.js +++ b/core/js/sharetemplates.js @@ -61,6 +61,20 @@ templates['sharedialoglinkshareview'] = template({"1":function(container,depth0, templates['sharedialoglinkshareview_popover_menu'] = template({"1":function(container,depth0,helpers,partials,data) { var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression; + return " <li>\n <span class=\"shareOption menuitem\">\n <span class=\"icon-loading-small hidden\"></span>\n <input type=\"checkbox\" name=\"hideDownload\" id=\"sharingDialogHideDownload-" + + alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper))) + + "\" class=\"checkbox hideDownloadCheckbox\"\n " + + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.hideDownload : depth0),{"name":"if","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + + " />\n <label for=\"sharingDialogHideDownload-" + + alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper))) + + "\">" + + alias4(((helper = (helper = helpers.hideDownloadLabel || (depth0 != null ? depth0.hideDownloadLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"hideDownloadLabel","hash":{},"data":data}) : helper))) + + "</label>\n </span>\n </li>\n"; +},"2":function(container,depth0,helpers,partials,data) { + return "checked=\"checked\""; +},"4":function(container,depth0,helpers,partials,data) { + var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression; + return " <li>\n <span class=\"shareOption menuitem\">\n <span class=\"icon-loading-small hidden\"></span>\n <input type=\"radio\" name=\"publicUpload\" value=\"" + alias4(((helper = (helper = helpers.publicUploadRValue || (depth0 != null ? depth0.publicUploadRValue : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"publicUploadRValue","hash":{},"data":data}) : helper))) + "\" id=\"sharingDialogAllowPublicUpload-r-" @@ -92,7 +106,7 @@ templates['sharedialoglinkshareview_popover_menu'] = template({"1":function(cont + "\">" + alias4(((helper = (helper = helpers.publicUploadWLabel || (depth0 != null ? depth0.publicUploadWLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"publicUploadWLabel","hash":{},"data":data}) : helper))) + "</label>\n </span>\n </li>\n"; -},"3":function(container,depth0,helpers,partials,data) { +},"6":function(container,depth0,helpers,partials,data) { var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression; return " <li id=\"allowPublicEditingWrapper\">\n <span class=\"shareOption menuitem\">\n <span class=\"icon-loading-small hidden\"></span>\n <input type=\"checkbox\" name=\"allowPublicEditing\" id=\"sharingDialogAllowPublicEditing-" @@ -104,41 +118,39 @@ templates['sharedialoglinkshareview_popover_menu'] = template({"1":function(cont + "\">" + alias4(((helper = (helper = helpers.publicEditingLabel || (depth0 != null ? depth0.publicEditingLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"publicEditingLabel","hash":{},"data":data}) : helper))) + "</label>\n </span>\n </li>\n"; -},"5":function(container,depth0,helpers,partials,data) { +},"8":function(container,depth0,helpers,partials,data) { var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression; return " <li>\n <span class=\"shareOption menuitem\">\n <input type=\"checkbox\" name=\"showPassword\" id=\"showPassword-" + alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper))) + "\" class=\"checkbox showPasswordCheckbox\"\n " - + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isPasswordSet : depth0),{"name":"if","hash":{},"fn":container.program(6, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isPasswordSet : depth0),{"name":"if","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + " " - + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isPasswordEnforced : depth0),{"name":"if","hash":{},"fn":container.program(8, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isPasswordEnforced : depth0),{"name":"if","hash":{},"fn":container.program(9, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + " value=\"1\" />\n <label for=\"showPassword-" + alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper))) + "\">" + alias4(((helper = (helper = helpers.enablePasswordLabel || (depth0 != null ? depth0.enablePasswordLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"enablePasswordLabel","hash":{},"data":data}) : helper))) + "</label>\n </span>\n </li>\n <li class=\"" - + ((stack1 = helpers.unless.call(alias1,(depth0 != null ? depth0.isPasswordSet : depth0),{"name":"unless","hash":{},"fn":container.program(10, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + + ((stack1 = helpers.unless.call(alias1,(depth0 != null ? depth0.isPasswordSet : depth0),{"name":"unless","hash":{},"fn":container.program(11, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + " linkPassMenu\">\n <span class=\"shareOption menuitem icon-share-pass\">\n <input id=\"linkPassText-" + alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper))) + "\" class=\"linkPassText\" type=\"password\" placeholder=\"" + alias4(((helper = (helper = helpers.passwordPlaceholder || (depth0 != null ? depth0.passwordPlaceholder : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"passwordPlaceholder","hash":{},"data":data}) : helper))) + "\" autocomplete=\"new-password\" />\n <span class=\"icon icon-loading-small hidden\"></span>\n </span>\n </li>\n"; -},"6":function(container,depth0,helpers,partials,data) { - return "checked=\"checked\""; -},"8":function(container,depth0,helpers,partials,data) { +},"9":function(container,depth0,helpers,partials,data) { return "disabled=\"disabled\""; -},"10":function(container,depth0,helpers,partials,data) { +},"11":function(container,depth0,helpers,partials,data) { return "hidden"; -},"12":function(container,depth0,helpers,partials,data) { +},"13":function(container,depth0,helpers,partials,data) { var helper; return container.escapeExpression(((helper = (helper = helpers.expireDate || (depth0 != null ? depth0.expireDate : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"expireDate","hash":{},"data":data}) : helper))); -},"14":function(container,depth0,helpers,partials,data) { +},"15":function(container,depth0,helpers,partials,data) { var helper; return container.escapeExpression(((helper = (helper = helpers.defaultExpireDate || (depth0 != null ? depth0.defaultExpireDate : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"defaultExpireDate","hash":{},"data":data}) : helper))); -},"16":function(container,depth0,helpers,partials,data) { +},"17":function(container,depth0,helpers,partials,data) { var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression; return " <li>\n <a href=\"#\" class=\"shareOption menuitem pop-up\" data-url=\"" @@ -162,21 +174,22 @@ templates['sharedialoglinkshareview_popover_menu'] = template({"1":function(cont + "\" class=\"linkText\" type=\"text\" readonly=\"readonly\" value=\"" + alias4(((helper = (helper = helpers.shareLinkURL || (depth0 != null ? depth0.shareLinkURL : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"shareLinkURL","hash":{},"data":data}) : helper))) + "\" />\n </span>\n </li>\n" - + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.publicUpload : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.publicEditing : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.showPasswordCheckBox : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.showHideDownloadCheckbox : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.publicUpload : depth0),{"name":"if","hash":{},"fn":container.program(4, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.publicEditing : depth0),{"name":"if","hash":{},"fn":container.program(6, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.showPasswordCheckBox : depth0),{"name":"if","hash":{},"fn":container.program(8, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + " <li>\n <span class=\"shareOption menuitem\">\n <input id=\"expireDate-" + alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper))) + "\" type=\"checkbox\" name=\"expirationDate\" class=\"expireDate checkbox\"\n " - + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.hasExpireDate : depth0),{"name":"if","hash":{},"fn":container.program(6, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.hasExpireDate : depth0),{"name":"if","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + " " - + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isExpirationEnforced : depth0),{"name":"if","hash":{},"fn":container.program(8, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isExpirationEnforced : depth0),{"name":"if","hash":{},"fn":container.program(9, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + "\" />\n <label for=\"expireDate-" + alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper))) + "\">" + alias4(((helper = (helper = helpers.expireDateLabel || (depth0 != null ? depth0.expireDateLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"expireDateLabel","hash":{},"data":data}) : helper))) + "</label>\n </span>\n </li>\n <li class=\"" - + ((stack1 = helpers.unless.call(alias1,(depth0 != null ? depth0.hasExpireDate : depth0),{"name":"unless","hash":{},"fn":container.program(10, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + + ((stack1 = helpers.unless.call(alias1,(depth0 != null ? depth0.hasExpireDate : depth0),{"name":"unless","hash":{},"fn":container.program(11, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + "\">\n <span class=\"menuitem icon-expiredate expirationDateContainer-" + alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper))) + "\">\n <label for=\"expirationDatePicker-" @@ -190,7 +203,7 @@ templates['sharedialoglinkshareview_popover_menu'] = template({"1":function(cont + "\" class=\"datepicker\" type=\"text\" placeholder=\"" + alias4(((helper = (helper = helpers.expirationDatePlaceholder || (depth0 != null ? depth0.expirationDatePlaceholder : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"expirationDatePlaceholder","hash":{},"data":data}) : helper))) + "\" value=\"" - + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.hasExpireDate : depth0),{"name":"if","hash":{},"fn":container.program(12, data, 0),"inverse":container.program(14, data, 0),"data":data})) != null ? stack1 : "") + + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.hasExpireDate : depth0),{"name":"if","hash":{},"fn":container.program(13, data, 0),"inverse":container.program(15, data, 0),"data":data})) != null ? stack1 : "") + "\" />\n </span>\n </li>\n <li>\n <a href=\"#\" class=\"share-add\">\n <span class=\"icon-loading-small hidden\"></span>\n <span class=\"icon icon-edit\"></span>\n <span>" + alias4(((helper = (helper = helpers.addNoteLabel || (depth0 != null ? depth0.addNoteLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"addNoteLabel","hash":{},"data":data}) : helper))) + "</span>\n <input type=\"button\" class=\"share-note-delete icon-delete\">\n </a>\n </li>\n <li class=\"share-note-form share-note-link hidden\">\n <span class=\"menuitem icon-note\">\n <textarea class=\"share-note\">" @@ -198,7 +211,7 @@ templates['sharedialoglinkshareview_popover_menu'] = template({"1":function(cont + "</textarea>\n <input type=\"submit\" class=\"icon-confirm share-note-submit\" value=\"\" id=\"add-note-" + alias4(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"shareId","hash":{},"data":data}) : helper))) + "\" />\n </span>\n </li>\n" - + ((stack1 = helpers.each.call(alias1,(depth0 != null ? depth0.social : depth0),{"name":"each","hash":{},"fn":container.program(16, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + + ((stack1 = helpers.each.call(alias1,(depth0 != null ? depth0.social : depth0),{"name":"each","hash":{},"fn":container.program(17, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") + " </ul>\n</div>\n"; },"useData":true}); templates['sharedialoglinkshareview_popover_menu_pending'] = template({"1":function(container,depth0,helpers,partials,data) { diff --git a/core/js/tests/specs/sharedialoglinkshareview.js b/core/js/tests/specs/sharedialoglinkshareview.js index 9d07dcb479d..d8dec3968e3 100644 --- a/core/js/tests/specs/sharedialoglinkshareview.js +++ b/core/js/tests/specs/sharedialoglinkshareview.js @@ -72,6 +72,100 @@ describe('OC.Share.ShareDialogLinkShareView', function () { configModel.isShareWithLinkAllowed.restore(); }); + describe('hide download', function () { + + var $hideDownloadCheckbox; + var $workingIcon; + + beforeEach(function () { + // Needed to render the view + configModel.isShareWithLinkAllowed.returns(true); + + // Setting the share also triggers the rendering + shareModel.set({ + linkShare: { + isLinkShare: true, + } + }); + + $hideDownloadCheckbox = view.$el.find('.hideDownloadCheckbox'); + $workingIcon = $hideDownloadCheckbox.prev('.icon-loading-small'); + + sinon.stub(shareModel, 'saveLinkShare'); + + expect($workingIcon.hasClass('hidden')).toBeTruthy(); + }); + + afterEach(function () { + shareModel.saveLinkShare.restore(); + }); + + it('is shown if the share is a file', function() { + expect($hideDownloadCheckbox.length).toBeTruthy(); + }); + + it('is not shown if the share is a folder', function() { + shareModel.fileInfoModel.set('mimetype', 'httpd/unix-directory'); + + // Setting the item type also triggers the rendering + shareModel.set({ + itemType: 'folder' + }); + + $hideDownloadCheckbox = view.$el.find('.hideDownloadCheckbox'); + + expect($hideDownloadCheckbox.length).toBeFalsy(); + }); + + it('checkbox is checked when the setting is enabled', function () { + shareModel.set({ + linkShare: { + isLinkShare: true, + hideDownload: true + } + }); + + $hideDownloadCheckbox = view.$el.find('.hideDownloadCheckbox'); + + expect($hideDownloadCheckbox.is(':checked')).toEqual(true); + }); + + it('checkbox is not checked when the setting is disabled', function () { + expect($hideDownloadCheckbox.is(':checked')).toEqual(false); + }); + + it('enables the setting if clicked when unchecked', function () { + // Simulate the click by checking the checkbox and then triggering + // the "change" event. + $hideDownloadCheckbox.prop('checked', true); + $hideDownloadCheckbox.change(); + + expect($workingIcon.hasClass('hidden')).toBeFalsy(); + expect(shareModel.saveLinkShare.withArgs({ hideDownload: true }).calledOnce).toBeTruthy(); + }); + + it('disables the setting if clicked when checked', function () { + shareModel.set({ + linkShare: { + isLinkShare: true, + hideDownload: true + } + }); + + $hideDownloadCheckbox = view.$el.find('.hideDownloadCheckbox'); + $workingIcon = $hideDownloadCheckbox.prev('.icon-loading-small'); + + // Simulate the click by unchecking the checkbox and then triggering + // the "change" event. + $hideDownloadCheckbox.prop('checked', false); + $hideDownloadCheckbox.change(); + + expect($workingIcon.hasClass('hidden')).toBeFalsy(); + expect(shareModel.saveLinkShare.withArgs({ hideDownload: false }).calledOnce).toBeTruthy(); + }); + + }); + describe('onPasswordEntered', function () { var $passwordText; diff --git a/core/js/tests/specs/shareitemmodelSpec.js b/core/js/tests/specs/shareitemmodelSpec.js index 2e89b2e3cda..a2eabbf4ae4 100644 --- a/core/js/tests/specs/shareitemmodelSpec.js +++ b/core/js/tests/specs/shareitemmodelSpec.js @@ -168,7 +168,8 @@ describe('OC.Share.ShareItemModel', function() { stime: 1403884258, storage: 1, token: 'tehtoken', - uid_owner: 'root' + uid_owner: 'root', + hide_download: 1 } ])); @@ -186,6 +187,7 @@ describe('OC.Share.ShareItemModel', function() { var linkShare = model.get('linkShare'); expect(linkShare.isLinkShare).toEqual(true); + expect(linkShare.hideDownload).toEqual(true); // TODO: check more attributes }); @@ -289,7 +291,8 @@ describe('OC.Share.ShareItemModel', function() { stime: 1403884258, storage: 1, token: 'tehtoken', - uid_owner: 'root' + uid_owner: 'root', + hide_download: 0 }, { displayname_owner: 'root', expiration: '2015-10-15 00:00:00', @@ -307,7 +310,8 @@ describe('OC.Share.ShareItemModel', function() { stime: 1403884509, storage: 1, token: 'anothertoken', - uid_owner: 'root' + uid_owner: 'root', + hide_download: 1 }] )); OC.currentUser = 'root'; @@ -320,6 +324,7 @@ describe('OC.Share.ShareItemModel', function() { var linkShare = model.get('linkShare'); expect(linkShare.isLinkShare).toEqual(true); expect(linkShare.token).toEqual('tehtoken'); + expect(linkShare.hideDownload).toEqual(false); // TODO: check child too }); @@ -579,6 +584,7 @@ describe('OC.Share.ShareItemModel', function() { expect(addShareStub.calledOnce).toEqual(true); expect(addShareStub.firstCall.args[0]).toEqual({ + hideDownload: false, password: '', passwordChanged: false, permissions: OC.PERMISSION_READ, @@ -603,6 +609,7 @@ describe('OC.Share.ShareItemModel', function() { expect(addShareStub.calledOnce).toEqual(true); expect(addShareStub.firstCall.args[0]).toEqual({ + hideDownload: false, password: '', passwordChanged: false, permissions: OC.PERMISSION_READ, diff --git a/core/l10n/af.js b/core/l10n/af.js index f8088145682..0cb8191d595 100644 --- a/core/l10n/af.js +++ b/core/l10n/af.js @@ -141,9 +141,6 @@ OC.L10N.register( "No users found for {search}" : "Geen gebruiker gevind vir {search}", "An error occurred (\"{message}\"). Please try again" : "'n Fout het voorgekom (\"{message}\"). Probeer asseblief weer", "An error occurred. Please try again" : "'n Fout het voorgekom. Probeer asseblief weer", - "{sharee} (group)" : "{sharee} (groep)", - "{sharee} (remote)" : "{sharee} (afgeleë)", - "{sharee} (email)" : "{sharee} (e-pos)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Deel", "Name or email address..." : "Naam of e-posadres...", @@ -243,6 +240,9 @@ OC.L10N.register( "Error setting expiration date" : "Fout terwyl vervaldatum stel", "The public link will expire no later than {days} days after it is created" : "Die publieke skakel sal presies {days} na dit geskep is verval", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} gedeel via skakel", + "{sharee} (group)" : "{sharee} (groep)", + "{sharee} (remote)" : "{sharee} (afgeleë)", + "{sharee} (email)" : "{sharee} (e-pos)", "Share with other people by entering a user or group or an email address." : "Deel met ander deur 'n gebruiker, groep of e-posadres in te vul. ", "The specified document has not been found on the server." : "Die gekose dokument was nie op die bediener gevind nie.", "You can click here to return to %s." : "U kan hier klik om terug te keer na %s", diff --git a/core/l10n/af.json b/core/l10n/af.json index e835f8bf954..5dc57050819 100644 --- a/core/l10n/af.json +++ b/core/l10n/af.json @@ -139,9 +139,6 @@ "No users found for {search}" : "Geen gebruiker gevind vir {search}", "An error occurred (\"{message}\"). Please try again" : "'n Fout het voorgekom (\"{message}\"). Probeer asseblief weer", "An error occurred. Please try again" : "'n Fout het voorgekom. Probeer asseblief weer", - "{sharee} (group)" : "{sharee} (groep)", - "{sharee} (remote)" : "{sharee} (afgeleë)", - "{sharee} (email)" : "{sharee} (e-pos)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Deel", "Name or email address..." : "Naam of e-posadres...", @@ -241,6 +238,9 @@ "Error setting expiration date" : "Fout terwyl vervaldatum stel", "The public link will expire no later than {days} days after it is created" : "Die publieke skakel sal presies {days} na dit geskep is verval", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} gedeel via skakel", + "{sharee} (group)" : "{sharee} (groep)", + "{sharee} (remote)" : "{sharee} (afgeleë)", + "{sharee} (email)" : "{sharee} (e-pos)", "Share with other people by entering a user or group or an email address." : "Deel met ander deur 'n gebruiker, groep of e-posadres in te vul. ", "The specified document has not been found on the server." : "Die gekose dokument was nie op die bediener gevind nie.", "You can click here to return to %s." : "U kan hier klik om terug te keer na %s", diff --git a/core/l10n/ast.js b/core/l10n/ast.js index d40d4138279..0bd13b54ca5 100644 --- a/core/l10n/ast.js +++ b/core/l10n/ast.js @@ -130,8 +130,6 @@ OC.L10N.register( "No users or groups found for {search}" : "Nun s'alcontraron usuarios o grupos pa {search}", "No users found for {search}" : "Nun s'alcontraron usuarios pa {search}", "An error occurred. Please try again" : "Asocedió un fallu. Volvi tentalo, por favor", - "{sharee} (group)" : "{sharee} (grupu)", - "{sharee} (email)" : "{sharee} (corréu)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nome o direición de corréu...", @@ -230,6 +228,8 @@ OC.L10N.register( "Error setting expiration date" : "Fallu afitando la fecha de caducidá", "The public link will expire no later than {days} days after it is created" : "L'enllaz públicu va caducar enantes de {days} díes dende la so creación", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} compartió per enllaz", + "{sharee} (group)" : "{sharee} (grupu)", + "{sharee} (email)" : "{sharee} (corréu)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparti con otra xente introduciendo un usuariu, grupu, ID de ñube federada o direición de corréu.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparti con otra xente introduciendo un usuariu, grupu o ID de ñube federada.", "Share with other people by entering a user or group or an email address." : "Comparti con otra xente introduciendo un usuariu, grupu o direición de corréu.", diff --git a/core/l10n/ast.json b/core/l10n/ast.json index 5019fcc9955..3ab9303f39a 100644 --- a/core/l10n/ast.json +++ b/core/l10n/ast.json @@ -128,8 +128,6 @@ "No users or groups found for {search}" : "Nun s'alcontraron usuarios o grupos pa {search}", "No users found for {search}" : "Nun s'alcontraron usuarios pa {search}", "An error occurred. Please try again" : "Asocedió un fallu. Volvi tentalo, por favor", - "{sharee} (group)" : "{sharee} (grupu)", - "{sharee} (email)" : "{sharee} (corréu)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nome o direición de corréu...", @@ -228,6 +226,8 @@ "Error setting expiration date" : "Fallu afitando la fecha de caducidá", "The public link will expire no later than {days} days after it is created" : "L'enllaz públicu va caducar enantes de {days} díes dende la so creación", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} compartió per enllaz", + "{sharee} (group)" : "{sharee} (grupu)", + "{sharee} (email)" : "{sharee} (corréu)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparti con otra xente introduciendo un usuariu, grupu, ID de ñube federada o direición de corréu.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparti con otra xente introduciendo un usuariu, grupu o ID de ñube federada.", "Share with other people by entering a user or group or an email address." : "Comparti con otra xente introduciendo un usuariu, grupu o direición de corréu.", diff --git a/core/l10n/bg.js b/core/l10n/bg.js index 08eea88b739..9781829bd69 100644 --- a/core/l10n/bg.js +++ b/core/l10n/bg.js @@ -151,12 +151,8 @@ OC.L10N.register( "No users or groups found for {search}" : "Няма потребители или групи за {search}", "No users found for {search}" : "Няма потребители за {search}", "An error occurred. Please try again" : "Възникна грешка. Моля, опитайте отново", - "{sharee} (group)" : "{sharee} (група)", - "{sharee} (remote)" : "{sharee} (отдалечен)", "{sharee} (remote group)" : "{sharee} (отдалечена група)", - "{sharee} (email)" : "{sharee} (имейл)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (разговор)", "Share" : "Споделяне", "Name or email address..." : "Име или имейл адрес...", "Name..." : "Име...", @@ -278,6 +274,9 @@ OC.L10N.register( "Error setting expiration date" : "Грешка при задаване на срок на валидност", "The public link will expire no later than {days} days after it is created" : "Общодостъпната връзка ще изтече не по-късно от {days} дни след създаването ѝ.", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} споделен с връзка", + "{sharee} (group)" : "{sharee} (група)", + "{sharee} (remote)" : "{sharee} (отдалечен)", + "{sharee} (email)" : "{sharee} (имейл)", "The specified document has not been found on the server." : "Избраният документ не е намерен на сървъра.", "You can click here to return to %s." : "Можете да натиснете тук, за да се върнете на %s.", "The server encountered an internal error and was unable to complete your request." : "Поради вътрешно сървърна грешка, сървърът не можа да изпълни заявката ви.", @@ -297,6 +296,7 @@ OC.L10N.register( "This page will refresh itself when the %s instance is available again." : "Страницата ще се зареди автоматично, когато %s е отново на линия.", "Thank you for your patience." : "Благодарим ви за търпението.", "You are about to grant %s access to your %s account." : "Ще разрешите на %s да ползва профила %s.", + "{sharee} (conversation)" : "{sharee} (разговор)", "Please log in before granting %s access to your %s account." : "Необходимо е да се впишете, преди да дадете достъп на %s до вашия %s профил." }, "nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/bg.json b/core/l10n/bg.json index 7b2368f8d99..684028f0810 100644 --- a/core/l10n/bg.json +++ b/core/l10n/bg.json @@ -149,12 +149,8 @@ "No users or groups found for {search}" : "Няма потребители или групи за {search}", "No users found for {search}" : "Няма потребители за {search}", "An error occurred. Please try again" : "Възникна грешка. Моля, опитайте отново", - "{sharee} (group)" : "{sharee} (група)", - "{sharee} (remote)" : "{sharee} (отдалечен)", "{sharee} (remote group)" : "{sharee} (отдалечена група)", - "{sharee} (email)" : "{sharee} (имейл)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (разговор)", "Share" : "Споделяне", "Name or email address..." : "Име или имейл адрес...", "Name..." : "Име...", @@ -276,6 +272,9 @@ "Error setting expiration date" : "Грешка при задаване на срок на валидност", "The public link will expire no later than {days} days after it is created" : "Общодостъпната връзка ще изтече не по-късно от {days} дни след създаването ѝ.", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} споделен с връзка", + "{sharee} (group)" : "{sharee} (група)", + "{sharee} (remote)" : "{sharee} (отдалечен)", + "{sharee} (email)" : "{sharee} (имейл)", "The specified document has not been found on the server." : "Избраният документ не е намерен на сървъра.", "You can click here to return to %s." : "Можете да натиснете тук, за да се върнете на %s.", "The server encountered an internal error and was unable to complete your request." : "Поради вътрешно сървърна грешка, сървърът не можа да изпълни заявката ви.", @@ -295,6 +294,7 @@ "This page will refresh itself when the %s instance is available again." : "Страницата ще се зареди автоматично, когато %s е отново на линия.", "Thank you for your patience." : "Благодарим ви за търпението.", "You are about to grant %s access to your %s account." : "Ще разрешите на %s да ползва профила %s.", + "{sharee} (conversation)" : "{sharee} (разговор)", "Please log in before granting %s access to your %s account." : "Необходимо е да се впишете, преди да дадете достъп на %s до вашия %s профил." },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/core/l10n/ca.js b/core/l10n/ca.js index e6ae31313df..0b409104a22 100644 --- a/core/l10n/ca.js +++ b/core/l10n/ca.js @@ -210,12 +210,8 @@ OC.L10N.register( "No users found for {search}" : "No s'han trobat usuaris per {search}", "An error occurred (\"{message}\"). Please try again" : "S'ha produït un error (\"{message}\"). Si us plau, torni a intentar-ho", "An error occurred. Please try again" : "S'ha produït un error. Si us plau, torni a intentar-ho", - "{sharee} (group)" : "{sharee} (grup)", - "{sharee} (remote)" : "{sharee} (remot)", "{sharee} (remote group)" : "{sharee} (grup remot)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (conversation)", "Share" : "Comparteix", "Name or email address..." : "Nom o adreça electrònica...", "Name or federated cloud ID..." : "Nom o ID de Núvol Federat…", @@ -382,6 +378,9 @@ OC.L10N.register( "Error setting expiration date" : "Error en establir la data de venciment", "The public link will expire no later than {days} days after it is created" : "L'enllaç públic tindrà venciment abans de {days} dies després de crear-lo", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compartit per enllaç", + "{sharee} (group)" : "{sharee} (grup)", + "{sharee} (remote)" : "{sharee} (remot)", + "{sharee} (email)" : "{sharee} (email)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Compartir amb altres persones introduint un usuari o grup, un ID de núvol federat o una adreça d’email.", "Share with other people by entering a user or group or a federated cloud ID." : "Compartir amb altres persones introduint un usuari o grup o ID de núvol federat.", "Share with other people by entering a user or group or an email address." : "Compartir amb altres persones introduint un usuari o grup o una adreça d’email.", @@ -413,6 +412,7 @@ OC.L10N.register( "You are about to grant %s access to your %s account." : "Estàs a punt d'autoritzar a %s a accedir al teu compte %s.", "Depending on your configuration, this button could also work to trust the domain:" : "Depenent de la teva configuració, aquest botó també podria funcionar per confiar en el domini:", "Copy URL" : "Copiar URL", + "{sharee} (conversation)" : "{sharee} (conversation)", "Please log in before granting %s access to your %s account." : "Si us plau entrar abans de donar %s accés al teu compte %s.", "Further information how to configure this can be found in the %sdocumentation%s." : "Més informació de com configurar això es pot trobar a la %sdocumentation%s." }, diff --git a/core/l10n/ca.json b/core/l10n/ca.json index c166f4648db..fe9056b6964 100644 --- a/core/l10n/ca.json +++ b/core/l10n/ca.json @@ -208,12 +208,8 @@ "No users found for {search}" : "No s'han trobat usuaris per {search}", "An error occurred (\"{message}\"). Please try again" : "S'ha produït un error (\"{message}\"). Si us plau, torni a intentar-ho", "An error occurred. Please try again" : "S'ha produït un error. Si us plau, torni a intentar-ho", - "{sharee} (group)" : "{sharee} (grup)", - "{sharee} (remote)" : "{sharee} (remot)", "{sharee} (remote group)" : "{sharee} (grup remot)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (conversation)", "Share" : "Comparteix", "Name or email address..." : "Nom o adreça electrònica...", "Name or federated cloud ID..." : "Nom o ID de Núvol Federat…", @@ -380,6 +376,9 @@ "Error setting expiration date" : "Error en establir la data de venciment", "The public link will expire no later than {days} days after it is created" : "L'enllaç públic tindrà venciment abans de {days} dies després de crear-lo", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compartit per enllaç", + "{sharee} (group)" : "{sharee} (grup)", + "{sharee} (remote)" : "{sharee} (remot)", + "{sharee} (email)" : "{sharee} (email)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Compartir amb altres persones introduint un usuari o grup, un ID de núvol federat o una adreça d’email.", "Share with other people by entering a user or group or a federated cloud ID." : "Compartir amb altres persones introduint un usuari o grup o ID de núvol federat.", "Share with other people by entering a user or group or an email address." : "Compartir amb altres persones introduint un usuari o grup o una adreça d’email.", @@ -411,6 +410,7 @@ "You are about to grant %s access to your %s account." : "Estàs a punt d'autoritzar a %s a accedir al teu compte %s.", "Depending on your configuration, this button could also work to trust the domain:" : "Depenent de la teva configuració, aquest botó també podria funcionar per confiar en el domini:", "Copy URL" : "Copiar URL", + "{sharee} (conversation)" : "{sharee} (conversation)", "Please log in before granting %s access to your %s account." : "Si us plau entrar abans de donar %s accés al teu compte %s.", "Further information how to configure this can be found in the %sdocumentation%s." : "Més informació de com configurar això es pot trobar a la %sdocumentation%s." },"pluralForm" :"nplurals=2; plural=(n != 1);" diff --git a/core/l10n/cs.js b/core/l10n/cs.js index 8a0f26a4e22..37ab7ea022f 100644 --- a/core/l10n/cs.js +++ b/core/l10n/cs.js @@ -210,12 +210,8 @@ OC.L10N.register( "No users found for {search}" : "Nebyli nalezeni žádní uživatelé pro {search}", "An error occurred (\"{message}\"). Please try again" : "Došlo k chybě („{message}“). Zkuste to znovu", "An error occurred. Please try again" : "Došlo k chybě. Zkuste to znovu", - "{sharee} (group)" : "{sharee} (skupina)", - "{sharee} (remote)" : "{sharee} (na protějšku)", "{sharee} (remote group)" : "{sharee} (skupina na protějšku)", - "{sharee} (email)" : "{sharee} (e-mail)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (konverzace)", "Share" : "Sdílet", "Name or email address..." : "Jméno nebo e-mailová adresa…", "Name or federated cloud ID..." : "Jméno nebo identifikátor v rámci sdruženého cloudu…", @@ -356,6 +352,7 @@ OC.L10N.register( "For help, see the <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"%s\">documentation</a>." : "Pro pomoc, nahlédněte do <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"%s\">dokumentace</a>.", "I know that if I continue doing the update via web UI has the risk, that the request runs into a timeout and could cause data loss, but I have a backup and know how to restore my instance in case of a failure." : "Beru na vědomí, že při aktualizaci skrze webové rozhraní hrozí nebezpečí vypršení požadavku, který může vyústit ve ztrátu dat. Mám pro takový případ zálohu a vím, jak ji v případě selhání obnovit.", "Upgrade via web on my own risk" : "Na vlastní nebezpečí aktualizovat skrze web", + "Maintenance mode" : "Režim údržby", "This %s instance is currently in maintenance mode, which may take a while." : "Tato instalace %s je právě ve stavu údržby a ta může chvíli trvat.", "Contact your system administrator if this message persists or appeared unexpectedly." : "Pokud se tato zpráva objevuje opakovaně nebo nečekaně, obraťte se správce systému.", "Updated \"%s\" to %s" : "Aktualizováno z „%s“ na %s", @@ -380,6 +377,9 @@ OC.L10N.register( "Error setting expiration date" : "Chyba při nastavení data skončení platnosti", "The public link will expire no later than {days} days after it is created" : "Veřejný odkaz vyprší nejpozději {days} dní od svého vytvoření", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} sdílí pomocí odkazu", + "{sharee} (group)" : "{sharee} (skupina)", + "{sharee} (remote)" : "{sharee} (na protějšku)", + "{sharee} (email)" : "{sharee} (e-mail)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Sdílejte s dalšími lidmi zadáním uživatelského jména, skupiny, federovaného cloud ID, nebo e-mailové adresy.", "Share with other people by entering a user or group or a federated cloud ID." : "Sdílejte s dalšími lidmi zadáním uživatelského jména, skupiny, nebo sdruženého cloud ID.", "Share with other people by entering a user or group or an email address." : "Sdílejte s dalšími lidmi zadáním uživatelského jména, jména skupiny, nebo e-mailové adresy.", @@ -411,6 +411,7 @@ OC.L10N.register( "You are about to grant %s access to your %s account." : "Chystáte se povolit %s přístup k vašemu %s účtu.", "Depending on your configuration, this button could also work to trust the domain:" : "V závislosti na vaší konfiguraci by pro označení domény za důvěryhodnou mohlo fungovat i toto tlačítko:", "Copy URL" : "Kopírovat URL", + "{sharee} (conversation)" : "{sharee} (konverzace)", "Please log in before granting %s access to your %s account." : "Přihlaste se před udělením %s přístupu k vašemu %s účtu.", "Further information how to configure this can be found in the %sdocumentation%s." : "Více informací o tom, jak toto nastavit, jsou k dispozici v%sdokumentaci%s." }, diff --git a/core/l10n/cs.json b/core/l10n/cs.json index 4a01f68d6da..edcc2917e54 100644 --- a/core/l10n/cs.json +++ b/core/l10n/cs.json @@ -208,12 +208,8 @@ "No users found for {search}" : "Nebyli nalezeni žádní uživatelé pro {search}", "An error occurred (\"{message}\"). Please try again" : "Došlo k chybě („{message}“). Zkuste to znovu", "An error occurred. Please try again" : "Došlo k chybě. Zkuste to znovu", - "{sharee} (group)" : "{sharee} (skupina)", - "{sharee} (remote)" : "{sharee} (na protějšku)", "{sharee} (remote group)" : "{sharee} (skupina na protějšku)", - "{sharee} (email)" : "{sharee} (e-mail)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (konverzace)", "Share" : "Sdílet", "Name or email address..." : "Jméno nebo e-mailová adresa…", "Name or federated cloud ID..." : "Jméno nebo identifikátor v rámci sdruženého cloudu…", @@ -354,6 +350,7 @@ "For help, see the <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"%s\">documentation</a>." : "Pro pomoc, nahlédněte do <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"%s\">dokumentace</a>.", "I know that if I continue doing the update via web UI has the risk, that the request runs into a timeout and could cause data loss, but I have a backup and know how to restore my instance in case of a failure." : "Beru na vědomí, že při aktualizaci skrze webové rozhraní hrozí nebezpečí vypršení požadavku, který může vyústit ve ztrátu dat. Mám pro takový případ zálohu a vím, jak ji v případě selhání obnovit.", "Upgrade via web on my own risk" : "Na vlastní nebezpečí aktualizovat skrze web", + "Maintenance mode" : "Režim údržby", "This %s instance is currently in maintenance mode, which may take a while." : "Tato instalace %s je právě ve stavu údržby a ta může chvíli trvat.", "Contact your system administrator if this message persists or appeared unexpectedly." : "Pokud se tato zpráva objevuje opakovaně nebo nečekaně, obraťte se správce systému.", "Updated \"%s\" to %s" : "Aktualizováno z „%s“ na %s", @@ -378,6 +375,9 @@ "Error setting expiration date" : "Chyba při nastavení data skončení platnosti", "The public link will expire no later than {days} days after it is created" : "Veřejný odkaz vyprší nejpozději {days} dní od svého vytvoření", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} sdílí pomocí odkazu", + "{sharee} (group)" : "{sharee} (skupina)", + "{sharee} (remote)" : "{sharee} (na protějšku)", + "{sharee} (email)" : "{sharee} (e-mail)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Sdílejte s dalšími lidmi zadáním uživatelského jména, skupiny, federovaného cloud ID, nebo e-mailové adresy.", "Share with other people by entering a user or group or a federated cloud ID." : "Sdílejte s dalšími lidmi zadáním uživatelského jména, skupiny, nebo sdruženého cloud ID.", "Share with other people by entering a user or group or an email address." : "Sdílejte s dalšími lidmi zadáním uživatelského jména, jména skupiny, nebo e-mailové adresy.", @@ -409,6 +409,7 @@ "You are about to grant %s access to your %s account." : "Chystáte se povolit %s přístup k vašemu %s účtu.", "Depending on your configuration, this button could also work to trust the domain:" : "V závislosti na vaší konfiguraci by pro označení domény za důvěryhodnou mohlo fungovat i toto tlačítko:", "Copy URL" : "Kopírovat URL", + "{sharee} (conversation)" : "{sharee} (konverzace)", "Please log in before granting %s access to your %s account." : "Přihlaste se před udělením %s přístupu k vašemu %s účtu.", "Further information how to configure this can be found in the %sdocumentation%s." : "Více informací o tom, jak toto nastavit, jsou k dispozici v%sdokumentaci%s." },"pluralForm" :"nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;" diff --git a/core/l10n/da.js b/core/l10n/da.js index cd0114ff748..f6d6d6a5400 100644 --- a/core/l10n/da.js +++ b/core/l10n/da.js @@ -170,9 +170,6 @@ OC.L10N.register( "No users found for {search}" : "Ingen brugere fundet for {search}", "An error occurred (\"{message}\"). Please try again" : "Der opstor den fejl (\"{message}\"). Prøv igen", "An error occurred. Please try again" : "Der opstor den fejl. Prøv igen", - "{sharee} (group)" : "{sharee} (gruppe)", - "{sharee} (remote)" : "{sharee} (ekstern)", - "{sharee} (email)" : "{sharee} (e-mail)", "{sharee} ({type}, {owner})" : "{share} ({type}, {owner})", "Share" : "Del", "Name or email address..." : "Navn eller e-mail adresse...", @@ -319,6 +316,9 @@ OC.L10N.register( "Error setting expiration date" : "Fejl under sætning af udløbsdato", "The public link will expire no later than {days} days after it is created" : "Det offentlige link udløber senest {days} dage efter det blev oprettet", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} delt via link", + "{sharee} (group)" : "{sharee} (gruppe)", + "{sharee} (remote)" : "{sharee} (ekstern)", + "{sharee} (email)" : "{sharee} (e-mail)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Del med andre ved at indtaste et brugernavn, en gruppe, et federated cloud id eller en e-mail adresse.", "Share with other people by entering a user or group or a federated cloud ID." : "Del med andre ved at indtaste et brugernavn, en gruppe eller et federated cloud id.", "Share with other people by entering a user or group or an email address." : "Del med andre ved at indtaste et brugernavn, en gruppe eller e-mail adresse.", diff --git a/core/l10n/da.json b/core/l10n/da.json index 26938bb5a20..b363b922f7e 100644 --- a/core/l10n/da.json +++ b/core/l10n/da.json @@ -168,9 +168,6 @@ "No users found for {search}" : "Ingen brugere fundet for {search}", "An error occurred (\"{message}\"). Please try again" : "Der opstor den fejl (\"{message}\"). Prøv igen", "An error occurred. Please try again" : "Der opstor den fejl. Prøv igen", - "{sharee} (group)" : "{sharee} (gruppe)", - "{sharee} (remote)" : "{sharee} (ekstern)", - "{sharee} (email)" : "{sharee} (e-mail)", "{sharee} ({type}, {owner})" : "{share} ({type}, {owner})", "Share" : "Del", "Name or email address..." : "Navn eller e-mail adresse...", @@ -317,6 +314,9 @@ "Error setting expiration date" : "Fejl under sætning af udløbsdato", "The public link will expire no later than {days} days after it is created" : "Det offentlige link udløber senest {days} dage efter det blev oprettet", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} delt via link", + "{sharee} (group)" : "{sharee} (gruppe)", + "{sharee} (remote)" : "{sharee} (ekstern)", + "{sharee} (email)" : "{sharee} (e-mail)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Del med andre ved at indtaste et brugernavn, en gruppe, et federated cloud id eller en e-mail adresse.", "Share with other people by entering a user or group or a federated cloud ID." : "Del med andre ved at indtaste et brugernavn, en gruppe eller et federated cloud id.", "Share with other people by entering a user or group or an email address." : "Del med andre ved at indtaste et brugernavn, en gruppe eller e-mail adresse.", diff --git a/core/l10n/de.js b/core/l10n/de.js index 260bb9ef824..1be2a21a5c6 100644 --- a/core/l10n/de.js +++ b/core/l10n/de.js @@ -167,6 +167,7 @@ OC.L10N.register( "Share to {name}" : "Mit {name} teilen", "Copy link" : "Link kopieren", "Link" : "Link", + "Hide download" : "Download verbergen", "Password protect" : "Passwortschutz", "Allow editing" : "Bearbeitung erlauben", "Email link to person" : "Link per E-Mail verschicken", @@ -210,12 +211,10 @@ OC.L10N.register( "No users found for {search}" : "Keine Benutzer für {search} gefunden", "An error occurred (\"{message}\"). Please try again" : "Benötigt keine Übersetzung. Für iOS wird nur die formelle Übersetzung verwendet (de_DE). ", "An error occurred. Please try again" : "Es ist ein Fehler aufgetreten. Bitte versuche es noch einmal", - "{sharee} (group)" : "{sharee} (Gruppe)", - "{sharee} (remote)" : "{sharee} (remote)", "{sharee} (remote group)" : "{sharee} (externe Gruppe)", - "{sharee} (email)" : "{sharee} (E-Mail)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (conversation)", + "Home" : "Start", + "Other" : "Andere", "Share" : "Teilen", "Name or email address..." : "Name oder E-Mail-Adresse…", "Name or federated cloud ID..." : "Name oder Federated-Cloud-ID…", @@ -382,6 +381,9 @@ OC.L10N.register( "Error setting expiration date" : "Fehler beim Setzen des Ablaufdatums", "The public link will expire no later than {days} days after it is created" : "Der öffentliche Link wird spätestens {days} Tage nach seiner Erstellung ablaufen", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} mittels Link geteilt", + "{sharee} (group)" : "{sharee} (Gruppe)", + "{sharee} (remote)" : "{sharee} (remote)", + "{sharee} (email)" : "{sharee} (E-Mail)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Teile mit Anderen, indem Du einen Benutzer, eine Gruppe, eine Federated-Cloud-ID oder eine E-Mail-Adressen eingibst.", "Share with other people by entering a user or group or a federated cloud ID." : "Teile mit Anderen, indem Du einen Benutzer, eine Gruppe, oder eine Federated-Cloud-ID eingibst.", "Share with other people by entering a user or group or an email address." : "Teile mit Anderen, indem Du einen Benutzer, eine Gruppe, oder eine E-Mail-Adresse eingibst.", @@ -413,6 +415,7 @@ OC.L10N.register( "You are about to grant %s access to your %s account." : "Du bist dabei, %s Zugriff auf Dein %s-Konto zu gewähren.", "Depending on your configuration, this button could also work to trust the domain:" : "Abhängig von Deiner Konfiguration kann diese Schaltfläche verwandt werden, um die Domain als vertrauenswürdig einzustufen:", "Copy URL" : "URL kopieren", + "{sharee} (conversation)" : "{sharee} (conversation)", "Please log in before granting %s access to your %s account." : "Bitte anmelden, bevor Du %s Zugriff auf Dein %s-Konto gewährst.", "Further information how to configure this can be found in the %sdocumentation%s." : "Weitere Informationen zur Konfiguration findest du in der %sDokumentation%s." }, diff --git a/core/l10n/de.json b/core/l10n/de.json index cf5b11bb679..f2063db8b24 100644 --- a/core/l10n/de.json +++ b/core/l10n/de.json @@ -165,6 +165,7 @@ "Share to {name}" : "Mit {name} teilen", "Copy link" : "Link kopieren", "Link" : "Link", + "Hide download" : "Download verbergen", "Password protect" : "Passwortschutz", "Allow editing" : "Bearbeitung erlauben", "Email link to person" : "Link per E-Mail verschicken", @@ -208,12 +209,10 @@ "No users found for {search}" : "Keine Benutzer für {search} gefunden", "An error occurred (\"{message}\"). Please try again" : "Benötigt keine Übersetzung. Für iOS wird nur die formelle Übersetzung verwendet (de_DE). ", "An error occurred. Please try again" : "Es ist ein Fehler aufgetreten. Bitte versuche es noch einmal", - "{sharee} (group)" : "{sharee} (Gruppe)", - "{sharee} (remote)" : "{sharee} (remote)", "{sharee} (remote group)" : "{sharee} (externe Gruppe)", - "{sharee} (email)" : "{sharee} (E-Mail)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (conversation)", + "Home" : "Start", + "Other" : "Andere", "Share" : "Teilen", "Name or email address..." : "Name oder E-Mail-Adresse…", "Name or federated cloud ID..." : "Name oder Federated-Cloud-ID…", @@ -380,6 +379,9 @@ "Error setting expiration date" : "Fehler beim Setzen des Ablaufdatums", "The public link will expire no later than {days} days after it is created" : "Der öffentliche Link wird spätestens {days} Tage nach seiner Erstellung ablaufen", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} mittels Link geteilt", + "{sharee} (group)" : "{sharee} (Gruppe)", + "{sharee} (remote)" : "{sharee} (remote)", + "{sharee} (email)" : "{sharee} (E-Mail)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Teile mit Anderen, indem Du einen Benutzer, eine Gruppe, eine Federated-Cloud-ID oder eine E-Mail-Adressen eingibst.", "Share with other people by entering a user or group or a federated cloud ID." : "Teile mit Anderen, indem Du einen Benutzer, eine Gruppe, oder eine Federated-Cloud-ID eingibst.", "Share with other people by entering a user or group or an email address." : "Teile mit Anderen, indem Du einen Benutzer, eine Gruppe, oder eine E-Mail-Adresse eingibst.", @@ -411,6 +413,7 @@ "You are about to grant %s access to your %s account." : "Du bist dabei, %s Zugriff auf Dein %s-Konto zu gewähren.", "Depending on your configuration, this button could also work to trust the domain:" : "Abhängig von Deiner Konfiguration kann diese Schaltfläche verwandt werden, um die Domain als vertrauenswürdig einzustufen:", "Copy URL" : "URL kopieren", + "{sharee} (conversation)" : "{sharee} (conversation)", "Please log in before granting %s access to your %s account." : "Bitte anmelden, bevor Du %s Zugriff auf Dein %s-Konto gewährst.", "Further information how to configure this can be found in the %sdocumentation%s." : "Weitere Informationen zur Konfiguration findest du in der %sDokumentation%s." },"pluralForm" :"nplurals=2; plural=(n != 1);" diff --git a/core/l10n/de_DE.js b/core/l10n/de_DE.js index 7a7b1b15739..bdcea5e0bb5 100644 --- a/core/l10n/de_DE.js +++ b/core/l10n/de_DE.js @@ -167,6 +167,7 @@ OC.L10N.register( "Share to {name}" : "Mit {name} teilen", "Copy link" : "Link kopieren", "Link" : "Link", + "Hide download" : "Download verbergen", "Password protect" : "Passwortschutz", "Allow editing" : "Bearbeitung erlauben", "Email link to person" : "Link per E-Mail verschicken", @@ -210,12 +211,10 @@ OC.L10N.register( "No users found for {search}" : "Keine Benutzer für {search} gefunden", "An error occurred (\"{message}\"). Please try again" : "Es ist ein Fehler aufgetreten (\"{message}\"). Bitte erneut versuchen.", "An error occurred. Please try again" : "Es ist ein Fehler aufgetreten. Bitte versuchen Sie es noch einmal", - "{sharee} (group)" : "{sharee} (Gruppe)", - "{sharee} (remote)" : "{sharee} (remote)", "{sharee} (remote group)" : "{sharee} (Externe Gruppe)", - "{sharee} (email)" : "{sharee} (E-Mail)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (conversation)", + "Home" : "Start", + "Other" : "Andere", "Share" : "Teilen", "Name or email address..." : "Name oder E-Mail-Adresse…", "Name or federated cloud ID..." : "Name oder Federated-Cloud-ID…", @@ -382,6 +381,9 @@ OC.L10N.register( "Error setting expiration date" : "Fehler beim Setzen des Ablaufdatums", "The public link will expire no later than {days} days after it is created" : "Der öffentliche Link wird spätestens {days} Tage nach seiner Erstellung ablaufen", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} mittels Link geteilt", + "{sharee} (group)" : "{sharee} (Gruppe)", + "{sharee} (remote)" : "{sharee} (remote)", + "{sharee} (email)" : "{sharee} (E-Mail)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Teilen mit Anderen, indem Sie einen Benutzer, eine Gruppe, eine Federated-Cloud-ID oder eine E-Mail-Adresse eingeben.", "Share with other people by entering a user or group or a federated cloud ID." : "Teilen mit Anderen, indem Sie einen Benutzer, eine Gruppe, oder eine Federated-Cloud-ID eingeben.", "Share with other people by entering a user or group or an email address." : "Teilen mit Anderen, indem Sie einen Benutzer, eine Gruppe, oder eine E-Mail-Adresse eingeben.", @@ -413,6 +415,7 @@ OC.L10N.register( "You are about to grant %s access to your %s account." : "Sie sind dabei, %s Zugriff auf Ihr %s-Konto zu gewähren.", "Depending on your configuration, this button could also work to trust the domain:" : "Abhängig von Ihrer Konfiguration kann diese Schaltfläche verwandt werden, um die Domain als vertrauenswürdig einzustufen:", "Copy URL" : "URL kopieren", + "{sharee} (conversation)" : "{sharee} (conversation)", "Please log in before granting %s access to your %s account." : "Bitte anmelden, bevor Du %s Zugriff auf Dein %s-Konto gewährst.", "Further information how to configure this can be found in the %sdocumentation%s." : "Weitere Informationen zur Konfiguration finden Sie in der %sDokumentation%s." }, diff --git a/core/l10n/de_DE.json b/core/l10n/de_DE.json index dc1ed554487..7f844020d63 100644 --- a/core/l10n/de_DE.json +++ b/core/l10n/de_DE.json @@ -165,6 +165,7 @@ "Share to {name}" : "Mit {name} teilen", "Copy link" : "Link kopieren", "Link" : "Link", + "Hide download" : "Download verbergen", "Password protect" : "Passwortschutz", "Allow editing" : "Bearbeitung erlauben", "Email link to person" : "Link per E-Mail verschicken", @@ -208,12 +209,10 @@ "No users found for {search}" : "Keine Benutzer für {search} gefunden", "An error occurred (\"{message}\"). Please try again" : "Es ist ein Fehler aufgetreten (\"{message}\"). Bitte erneut versuchen.", "An error occurred. Please try again" : "Es ist ein Fehler aufgetreten. Bitte versuchen Sie es noch einmal", - "{sharee} (group)" : "{sharee} (Gruppe)", - "{sharee} (remote)" : "{sharee} (remote)", "{sharee} (remote group)" : "{sharee} (Externe Gruppe)", - "{sharee} (email)" : "{sharee} (E-Mail)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (conversation)", + "Home" : "Start", + "Other" : "Andere", "Share" : "Teilen", "Name or email address..." : "Name oder E-Mail-Adresse…", "Name or federated cloud ID..." : "Name oder Federated-Cloud-ID…", @@ -380,6 +379,9 @@ "Error setting expiration date" : "Fehler beim Setzen des Ablaufdatums", "The public link will expire no later than {days} days after it is created" : "Der öffentliche Link wird spätestens {days} Tage nach seiner Erstellung ablaufen", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} mittels Link geteilt", + "{sharee} (group)" : "{sharee} (Gruppe)", + "{sharee} (remote)" : "{sharee} (remote)", + "{sharee} (email)" : "{sharee} (E-Mail)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Teilen mit Anderen, indem Sie einen Benutzer, eine Gruppe, eine Federated-Cloud-ID oder eine E-Mail-Adresse eingeben.", "Share with other people by entering a user or group or a federated cloud ID." : "Teilen mit Anderen, indem Sie einen Benutzer, eine Gruppe, oder eine Federated-Cloud-ID eingeben.", "Share with other people by entering a user or group or an email address." : "Teilen mit Anderen, indem Sie einen Benutzer, eine Gruppe, oder eine E-Mail-Adresse eingeben.", @@ -411,6 +413,7 @@ "You are about to grant %s access to your %s account." : "Sie sind dabei, %s Zugriff auf Ihr %s-Konto zu gewähren.", "Depending on your configuration, this button could also work to trust the domain:" : "Abhängig von Ihrer Konfiguration kann diese Schaltfläche verwandt werden, um die Domain als vertrauenswürdig einzustufen:", "Copy URL" : "URL kopieren", + "{sharee} (conversation)" : "{sharee} (conversation)", "Please log in before granting %s access to your %s account." : "Bitte anmelden, bevor Du %s Zugriff auf Dein %s-Konto gewährst.", "Further information how to configure this can be found in the %sdocumentation%s." : "Weitere Informationen zur Konfiguration finden Sie in der %sDokumentation%s." },"pluralForm" :"nplurals=2; plural=(n != 1);" diff --git a/core/l10n/el.js b/core/l10n/el.js index 490cace3f23..aae27a52af2 100644 --- a/core/l10n/el.js +++ b/core/l10n/el.js @@ -155,9 +155,6 @@ OC.L10N.register( "No users or groups found for {search}" : "Δεν βρέθηκαν χρήστες ή ομάδες για την αναζήτηση {search}", "No users found for {search}" : "Δεν βρέθηκαν χρήστες για την αναζήτηση {search}", "An error occurred. Please try again" : "Παρουσιάστηκε σφάλμα. Παρακαλώ δοκιμάστε αργότερα", - "{sharee} (group)" : "{sharee} (ομάδα)", - "{sharee} (remote)" : "{sharee} (απομακρυσμένα)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Διαμοιρασμός", "Name or email address..." : "Όνομα ή διεύθυνση ηλεκτρονικού ταχυδρομείου...", @@ -281,6 +278,9 @@ OC.L10N.register( "Error setting expiration date" : "Σφάλμα κατά τον ορισμό ημερομηνίας λήξης", "The public link will expire no later than {days} days after it is created" : "Ο δημόσιος σύνδεσμος θα απενεργοποιηθεί το πολύ σε {days} ημέρες μετά την δημιουργία του", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} διαμοιράστηκε με σύνδεσμο", + "{sharee} (group)" : "{sharee} (ομάδα)", + "{sharee} (remote)" : "{sharee} (απομακρυσμένα)", + "{sharee} (email)" : "{sharee} (email)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Διαμοιραστείτε με άλλους εισάγοντας τον χρήστη ή την ομάδα, το ID του federated cloud ή μια διεύθυνση ηλεκτρονικού ταχυδρομείου.", "Share with other people by entering a user or group or a federated cloud ID." : "Διαμοιραστείτε με άλλους εισάγοντας τον χρήστη ή την ομάδα ή το ID του federated cloud.", "Share with other people by entering a user or group or an email address." : "Διαμοιραστείτε με άλλους εισάγοντας τον χρήστη ή την ομάδα ή μια διεύθυνση ηλεκτρονικού ταχυδρομείου.", diff --git a/core/l10n/el.json b/core/l10n/el.json index e70fff20a1e..08f2db92103 100644 --- a/core/l10n/el.json +++ b/core/l10n/el.json @@ -153,9 +153,6 @@ "No users or groups found for {search}" : "Δεν βρέθηκαν χρήστες ή ομάδες για την αναζήτηση {search}", "No users found for {search}" : "Δεν βρέθηκαν χρήστες για την αναζήτηση {search}", "An error occurred. Please try again" : "Παρουσιάστηκε σφάλμα. Παρακαλώ δοκιμάστε αργότερα", - "{sharee} (group)" : "{sharee} (ομάδα)", - "{sharee} (remote)" : "{sharee} (απομακρυσμένα)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Διαμοιρασμός", "Name or email address..." : "Όνομα ή διεύθυνση ηλεκτρονικού ταχυδρομείου...", @@ -279,6 +276,9 @@ "Error setting expiration date" : "Σφάλμα κατά τον ορισμό ημερομηνίας λήξης", "The public link will expire no later than {days} days after it is created" : "Ο δημόσιος σύνδεσμος θα απενεργοποιηθεί το πολύ σε {days} ημέρες μετά την δημιουργία του", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} διαμοιράστηκε με σύνδεσμο", + "{sharee} (group)" : "{sharee} (ομάδα)", + "{sharee} (remote)" : "{sharee} (απομακρυσμένα)", + "{sharee} (email)" : "{sharee} (email)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Διαμοιραστείτε με άλλους εισάγοντας τον χρήστη ή την ομάδα, το ID του federated cloud ή μια διεύθυνση ηλεκτρονικού ταχυδρομείου.", "Share with other people by entering a user or group or a federated cloud ID." : "Διαμοιραστείτε με άλλους εισάγοντας τον χρήστη ή την ομάδα ή το ID του federated cloud.", "Share with other people by entering a user or group or an email address." : "Διαμοιραστείτε με άλλους εισάγοντας τον χρήστη ή την ομάδα ή μια διεύθυνση ηλεκτρονικού ταχυδρομείου.", diff --git a/core/l10n/en_GB.js b/core/l10n/en_GB.js index 269026c479a..1530abaedb8 100644 --- a/core/l10n/en_GB.js +++ b/core/l10n/en_GB.js @@ -172,9 +172,6 @@ OC.L10N.register( "No users found for {search}" : "No users found for {search}", "An error occurred (\"{message}\"). Please try again" : "An error occurred (\"{message}\"). Please try again", "An error occurred. Please try again" : "An error occurred. Please try again", - "{sharee} (group)" : "{sharee} (group)", - "{sharee} (remote)" : "{sharee} (remote)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Share", "Name or email address..." : "Name or email address...", @@ -325,6 +322,9 @@ OC.L10N.register( "Error setting expiration date" : "Error setting expiration date", "The public link will expire no later than {days} days after it is created" : "The public link will expire no later than {days} days after it is created", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} shared via link", + "{sharee} (group)" : "{sharee} (group)", + "{sharee} (remote)" : "{sharee} (remote)", + "{sharee} (email)" : "{sharee} (email)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Share with other people by entering a user or group, a federated cloud ID or an email address.", "Share with other people by entering a user or group or a federated cloud ID." : "Share with other people by entering a user or group or a federated cloud ID.", "Share with other people by entering a user or group or an email address." : "Share with other people by entering a user or group or an email address.", diff --git a/core/l10n/en_GB.json b/core/l10n/en_GB.json index 66c984ba1d7..5fd03c9de3d 100644 --- a/core/l10n/en_GB.json +++ b/core/l10n/en_GB.json @@ -170,9 +170,6 @@ "No users found for {search}" : "No users found for {search}", "An error occurred (\"{message}\"). Please try again" : "An error occurred (\"{message}\"). Please try again", "An error occurred. Please try again" : "An error occurred. Please try again", - "{sharee} (group)" : "{sharee} (group)", - "{sharee} (remote)" : "{sharee} (remote)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Share", "Name or email address..." : "Name or email address...", @@ -323,6 +320,9 @@ "Error setting expiration date" : "Error setting expiration date", "The public link will expire no later than {days} days after it is created" : "The public link will expire no later than {days} days after it is created", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} shared via link", + "{sharee} (group)" : "{sharee} (group)", + "{sharee} (remote)" : "{sharee} (remote)", + "{sharee} (email)" : "{sharee} (email)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Share with other people by entering a user or group, a federated cloud ID or an email address.", "Share with other people by entering a user or group or a federated cloud ID." : "Share with other people by entering a user or group or a federated cloud ID.", "Share with other people by entering a user or group or an email address." : "Share with other people by entering a user or group or an email address.", diff --git a/core/l10n/eo.js b/core/l10n/eo.js index 3900daa108b..2ebc961173f 100644 --- a/core/l10n/eo.js +++ b/core/l10n/eo.js @@ -116,9 +116,6 @@ OC.L10N.register( "No users or groups found for {search}" : "Neniu uzanto aŭ grupo troviĝis por {search}", "An error occurred (\"{message}\"). Please try again" : "Eraro okazis (\"{message}\"). Bonvolu provi ree.", "An error occurred. Please try again" : "Eraro okazis. Bonvolu provi ree", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (fora)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Kunhavigi", "Name or email address..." : "Nomo aŭ retpoŝtadreso...", @@ -215,6 +212,9 @@ OC.L10N.register( "Shared with {recipients}" : "Kunhavigis kun {recipients}", "Error setting expiration date" : "Eraro dum agordado de limdato", "The public link will expire no later than {days} days after it is created" : "La publika ligilo senvalidiĝos ne pli malfrue ol {days} tagojn post ĝi kreiĝos", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (fora)", + "{sharee} (email)" : "{sharee} (email)", "This action requires you to confirm your password:" : "Tiu ĉi ago bezonas ke vi konfirmas vian pasvorton:", "Wrong password. Reset it?" : "Falsa pasvorto. Ĉu vi volas rekomenci ĝin?", "Stay logged in" : "Daŭri ensalutinta", diff --git a/core/l10n/eo.json b/core/l10n/eo.json index c48216f51b5..1a1b56551f6 100644 --- a/core/l10n/eo.json +++ b/core/l10n/eo.json @@ -114,9 +114,6 @@ "No users or groups found for {search}" : "Neniu uzanto aŭ grupo troviĝis por {search}", "An error occurred (\"{message}\"). Please try again" : "Eraro okazis (\"{message}\"). Bonvolu provi ree.", "An error occurred. Please try again" : "Eraro okazis. Bonvolu provi ree", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (fora)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Kunhavigi", "Name or email address..." : "Nomo aŭ retpoŝtadreso...", @@ -213,6 +210,9 @@ "Shared with {recipients}" : "Kunhavigis kun {recipients}", "Error setting expiration date" : "Eraro dum agordado de limdato", "The public link will expire no later than {days} days after it is created" : "La publika ligilo senvalidiĝos ne pli malfrue ol {days} tagojn post ĝi kreiĝos", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (fora)", + "{sharee} (email)" : "{sharee} (email)", "This action requires you to confirm your password:" : "Tiu ĉi ago bezonas ke vi konfirmas vian pasvorton:", "Wrong password. Reset it?" : "Falsa pasvorto. Ĉu vi volas rekomenci ĝin?", "Stay logged in" : "Daŭri ensalutinta", diff --git a/core/l10n/es.js b/core/l10n/es.js index ce580b7d2de..7b8c50b4034 100644 --- a/core/l10n/es.js +++ b/core/l10n/es.js @@ -210,12 +210,8 @@ OC.L10N.register( "No users found for {search}" : "No se han encontrado usuarios para {search}", "An error occurred (\"{message}\"). Please try again" : "Ha ocurrido un error (\"{message}\"). Por favor inténtelo de nuevo", "An error occurred. Please try again" : "Ha ocurrido un error. Por favor inténtelo de nuevo", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", "{sharee} (remote group)" : "{sharee} (grupo remoto)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (conversación)", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico...", "Name or federated cloud ID..." : "Nombre o ID de nube federada...", @@ -382,6 +378,9 @@ OC.L10N.register( "Error setting expiration date" : "Error estableciendo fecha de caducidad", "The public link will expire no later than {days} days after it is created" : "El vínculo público no expirará antes de {days} desde que se creó", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} compartido por medio de un link", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (email)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparte con otras personas introduciendo un usuario, grupo, ID de nube federada o dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparte con otras personas introduciendo un usuario, grupo o ID de nube federada.", "Share with other people by entering a user or group or an email address." : "Comparte con otras personas introduciendo un usuario, grupo o una dirección de correo electrónico.", @@ -413,6 +412,7 @@ OC.L10N.register( "You are about to grant %s access to your %s account." : "Estás a punto de conceder a %s acceso a tu cuenta de %s", "Depending on your configuration, this button could also work to trust the domain:" : "Dependiendo de tu configuración, este botón también podría servir para confiar en el dominio:", "Copy URL" : "Copiar URL", + "{sharee} (conversation)" : "{sharee} (conversación)", "Please log in before granting %s access to your %s account." : "Por favor, inicie sesión antes de conceder a %s acceso a tu %s cuenta.", "Further information how to configure this can be found in the %sdocumentation%s." : "Más información sobre cómo configurar esto se puede encontrar en la %sdocumentación%s." }, diff --git a/core/l10n/es.json b/core/l10n/es.json index a2be02603df..15fa4d62ad7 100644 --- a/core/l10n/es.json +++ b/core/l10n/es.json @@ -208,12 +208,8 @@ "No users found for {search}" : "No se han encontrado usuarios para {search}", "An error occurred (\"{message}\"). Please try again" : "Ha ocurrido un error (\"{message}\"). Por favor inténtelo de nuevo", "An error occurred. Please try again" : "Ha ocurrido un error. Por favor inténtelo de nuevo", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", "{sharee} (remote group)" : "{sharee} (grupo remoto)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (conversación)", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico...", "Name or federated cloud ID..." : "Nombre o ID de nube federada...", @@ -380,6 +376,9 @@ "Error setting expiration date" : "Error estableciendo fecha de caducidad", "The public link will expire no later than {days} days after it is created" : "El vínculo público no expirará antes de {days} desde que se creó", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} compartido por medio de un link", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (email)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparte con otras personas introduciendo un usuario, grupo, ID de nube federada o dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparte con otras personas introduciendo un usuario, grupo o ID de nube federada.", "Share with other people by entering a user or group or an email address." : "Comparte con otras personas introduciendo un usuario, grupo o una dirección de correo electrónico.", @@ -411,6 +410,7 @@ "You are about to grant %s access to your %s account." : "Estás a punto de conceder a %s acceso a tu cuenta de %s", "Depending on your configuration, this button could also work to trust the domain:" : "Dependiendo de tu configuración, este botón también podría servir para confiar en el dominio:", "Copy URL" : "Copiar URL", + "{sharee} (conversation)" : "{sharee} (conversación)", "Please log in before granting %s access to your %s account." : "Por favor, inicie sesión antes de conceder a %s acceso a tu %s cuenta.", "Further information how to configure this can be found in the %sdocumentation%s." : "Más información sobre cómo configurar esto se puede encontrar en la %sdocumentación%s." },"pluralForm" :"nplurals=2; plural=(n != 1);" diff --git a/core/l10n/es_419.js b/core/l10n/es_419.js index f44a641ce1e..6cb4f43e6a8 100644 --- a/core/l10n/es_419.js +++ b/core/l10n/es_419.js @@ -167,9 +167,6 @@ OC.L10N.register( "No users or groups found for {search}" : "No se encontraron usuarios o gurpos para {search}", "No users found for {search}" : "No se encontraron usuarios para {search}", "An error occurred. Please try again" : "Se presentó un error. Por favor vuelve a intentarlo", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (correo electrónico)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico", @@ -294,6 +291,9 @@ OC.L10N.register( "Error setting expiration date" : "Se presentó un error al establecer la fecha de expiración", "The public link will expire no later than {days} days after it is created" : "La liga pública expirará a los {days} días de haber sido creada", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compartido mediante una liga", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (correo electrónico)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparte con otras personas ingresando una dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparte con otras personas ingresando un usuario o un grupo.", "Share with other people by entering a user or group or an email address." : "Comparte con otras personas ingresando un usuario, un grupo o una dirección de correo electrónico.", diff --git a/core/l10n/es_419.json b/core/l10n/es_419.json index 62d866f1327..fcb62367d14 100644 --- a/core/l10n/es_419.json +++ b/core/l10n/es_419.json @@ -165,9 +165,6 @@ "No users or groups found for {search}" : "No se encontraron usuarios o gurpos para {search}", "No users found for {search}" : "No se encontraron usuarios para {search}", "An error occurred. Please try again" : "Se presentó un error. Por favor vuelve a intentarlo", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (correo electrónico)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico", @@ -292,6 +289,9 @@ "Error setting expiration date" : "Se presentó un error al establecer la fecha de expiración", "The public link will expire no later than {days} days after it is created" : "La liga pública expirará a los {days} días de haber sido creada", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compartido mediante una liga", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (correo electrónico)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparte con otras personas ingresando una dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparte con otras personas ingresando un usuario o un grupo.", "Share with other people by entering a user or group or an email address." : "Comparte con otras personas ingresando un usuario, un grupo o una dirección de correo electrónico.", diff --git a/core/l10n/es_AR.js b/core/l10n/es_AR.js index 88229c30d51..36ff6cfc7ea 100644 --- a/core/l10n/es_AR.js +++ b/core/l10n/es_AR.js @@ -147,9 +147,6 @@ OC.L10N.register( "No users or groups found for {search}" : "No se encontraron usuarios o gurpos para {search}", "No users found for {search}" : "No se encontraron usuarios para {search}", "An error occurred. Please try again" : "Se presentó un error. Favor de volver a intentar", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (correo electrónico)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico", @@ -265,6 +262,9 @@ OC.L10N.register( "Error setting expiration date" : "Se presentó un error al establecer la fecha de expiración", "The public link will expire no later than {days} days after it is created" : "El link público expirará a los {days} días de haber sido creado", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compatido mediante un link", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (correo electrónico)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparta con otras personas ingresando un usuario, un grupo, un ID de nube federado o una dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparta con otras personas ingresando un usuario, un grupo o un ID de nube federado.", "Share with other people by entering a user or group or an email address." : "Comparta con otras personas ingresando un usuario, un grupo o una dirección de correo electrónico.", diff --git a/core/l10n/es_AR.json b/core/l10n/es_AR.json index 1036a3cba25..c13e9e0bffb 100644 --- a/core/l10n/es_AR.json +++ b/core/l10n/es_AR.json @@ -145,9 +145,6 @@ "No users or groups found for {search}" : "No se encontraron usuarios o gurpos para {search}", "No users found for {search}" : "No se encontraron usuarios para {search}", "An error occurred. Please try again" : "Se presentó un error. Favor de volver a intentar", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (correo electrónico)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico", @@ -263,6 +260,9 @@ "Error setting expiration date" : "Se presentó un error al establecer la fecha de expiración", "The public link will expire no later than {days} days after it is created" : "El link público expirará a los {days} días de haber sido creado", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compatido mediante un link", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (correo electrónico)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparta con otras personas ingresando un usuario, un grupo, un ID de nube federado o una dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparta con otras personas ingresando un usuario, un grupo o un ID de nube federado.", "Share with other people by entering a user or group or an email address." : "Comparta con otras personas ingresando un usuario, un grupo o una dirección de correo electrónico.", diff --git a/core/l10n/es_CL.js b/core/l10n/es_CL.js index 28531d48743..d98b3dcebed 100644 --- a/core/l10n/es_CL.js +++ b/core/l10n/es_CL.js @@ -170,9 +170,6 @@ OC.L10N.register( "No users found for {search}" : "No se encontraron usuarios para {search}", "An error occurred (\"{message}\"). Please try again" : "Se presentó un error (\"{message}\"). Por favor vuelve a intentarlo", "An error occurred. Please try again" : "Se presentó un error. Por favor vuelve a intentarlo", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (correo electrónico)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico", @@ -323,6 +320,9 @@ OC.L10N.register( "Error setting expiration date" : "Se presentó un error al establecer la fecha de expiración", "The public link will expire no later than {days} days after it is created" : "La liga pública expirará a los {days} días de haber sido creada", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compartido mediante una liga", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (correo electrónico)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparte con otras personas ingresando una dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparte con otras personas ingresando un usuario o un grupo.", "Share with other people by entering a user or group or an email address." : "Comparte con otras personas ingresando un usuario, un grupo o una dirección de correo electrónico.", diff --git a/core/l10n/es_CL.json b/core/l10n/es_CL.json index 9ec18d03f47..4446f7c8610 100644 --- a/core/l10n/es_CL.json +++ b/core/l10n/es_CL.json @@ -168,9 +168,6 @@ "No users found for {search}" : "No se encontraron usuarios para {search}", "An error occurred (\"{message}\"). Please try again" : "Se presentó un error (\"{message}\"). Por favor vuelve a intentarlo", "An error occurred. Please try again" : "Se presentó un error. Por favor vuelve a intentarlo", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (correo electrónico)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico", @@ -321,6 +318,9 @@ "Error setting expiration date" : "Se presentó un error al establecer la fecha de expiración", "The public link will expire no later than {days} days after it is created" : "La liga pública expirará a los {days} días de haber sido creada", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compartido mediante una liga", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (correo electrónico)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparte con otras personas ingresando una dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparte con otras personas ingresando un usuario o un grupo.", "Share with other people by entering a user or group or an email address." : "Comparte con otras personas ingresando un usuario, un grupo o una dirección de correo electrónico.", diff --git a/core/l10n/es_CO.js b/core/l10n/es_CO.js index 28531d48743..d98b3dcebed 100644 --- a/core/l10n/es_CO.js +++ b/core/l10n/es_CO.js @@ -170,9 +170,6 @@ OC.L10N.register( "No users found for {search}" : "No se encontraron usuarios para {search}", "An error occurred (\"{message}\"). Please try again" : "Se presentó un error (\"{message}\"). Por favor vuelve a intentarlo", "An error occurred. Please try again" : "Se presentó un error. Por favor vuelve a intentarlo", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (correo electrónico)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico", @@ -323,6 +320,9 @@ OC.L10N.register( "Error setting expiration date" : "Se presentó un error al establecer la fecha de expiración", "The public link will expire no later than {days} days after it is created" : "La liga pública expirará a los {days} días de haber sido creada", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compartido mediante una liga", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (correo electrónico)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparte con otras personas ingresando una dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparte con otras personas ingresando un usuario o un grupo.", "Share with other people by entering a user or group or an email address." : "Comparte con otras personas ingresando un usuario, un grupo o una dirección de correo electrónico.", diff --git a/core/l10n/es_CO.json b/core/l10n/es_CO.json index 9ec18d03f47..4446f7c8610 100644 --- a/core/l10n/es_CO.json +++ b/core/l10n/es_CO.json @@ -168,9 +168,6 @@ "No users found for {search}" : "No se encontraron usuarios para {search}", "An error occurred (\"{message}\"). Please try again" : "Se presentó un error (\"{message}\"). Por favor vuelve a intentarlo", "An error occurred. Please try again" : "Se presentó un error. Por favor vuelve a intentarlo", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (correo electrónico)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico", @@ -321,6 +318,9 @@ "Error setting expiration date" : "Se presentó un error al establecer la fecha de expiración", "The public link will expire no later than {days} days after it is created" : "La liga pública expirará a los {days} días de haber sido creada", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compartido mediante una liga", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (correo electrónico)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparte con otras personas ingresando una dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparte con otras personas ingresando un usuario o un grupo.", "Share with other people by entering a user or group or an email address." : "Comparte con otras personas ingresando un usuario, un grupo o una dirección de correo electrónico.", diff --git a/core/l10n/es_CR.js b/core/l10n/es_CR.js index 28531d48743..d98b3dcebed 100644 --- a/core/l10n/es_CR.js +++ b/core/l10n/es_CR.js @@ -170,9 +170,6 @@ OC.L10N.register( "No users found for {search}" : "No se encontraron usuarios para {search}", "An error occurred (\"{message}\"). Please try again" : "Se presentó un error (\"{message}\"). Por favor vuelve a intentarlo", "An error occurred. Please try again" : "Se presentó un error. Por favor vuelve a intentarlo", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (correo electrónico)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico", @@ -323,6 +320,9 @@ OC.L10N.register( "Error setting expiration date" : "Se presentó un error al establecer la fecha de expiración", "The public link will expire no later than {days} days after it is created" : "La liga pública expirará a los {days} días de haber sido creada", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compartido mediante una liga", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (correo electrónico)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparte con otras personas ingresando una dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparte con otras personas ingresando un usuario o un grupo.", "Share with other people by entering a user or group or an email address." : "Comparte con otras personas ingresando un usuario, un grupo o una dirección de correo electrónico.", diff --git a/core/l10n/es_CR.json b/core/l10n/es_CR.json index 9ec18d03f47..4446f7c8610 100644 --- a/core/l10n/es_CR.json +++ b/core/l10n/es_CR.json @@ -168,9 +168,6 @@ "No users found for {search}" : "No se encontraron usuarios para {search}", "An error occurred (\"{message}\"). Please try again" : "Se presentó un error (\"{message}\"). Por favor vuelve a intentarlo", "An error occurred. Please try again" : "Se presentó un error. Por favor vuelve a intentarlo", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (correo electrónico)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico", @@ -321,6 +318,9 @@ "Error setting expiration date" : "Se presentó un error al establecer la fecha de expiración", "The public link will expire no later than {days} days after it is created" : "La liga pública expirará a los {days} días de haber sido creada", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compartido mediante una liga", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (correo electrónico)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparte con otras personas ingresando una dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparte con otras personas ingresando un usuario o un grupo.", "Share with other people by entering a user or group or an email address." : "Comparte con otras personas ingresando un usuario, un grupo o una dirección de correo electrónico.", diff --git a/core/l10n/es_DO.js b/core/l10n/es_DO.js index 28531d48743..d98b3dcebed 100644 --- a/core/l10n/es_DO.js +++ b/core/l10n/es_DO.js @@ -170,9 +170,6 @@ OC.L10N.register( "No users found for {search}" : "No se encontraron usuarios para {search}", "An error occurred (\"{message}\"). Please try again" : "Se presentó un error (\"{message}\"). Por favor vuelve a intentarlo", "An error occurred. Please try again" : "Se presentó un error. Por favor vuelve a intentarlo", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (correo electrónico)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico", @@ -323,6 +320,9 @@ OC.L10N.register( "Error setting expiration date" : "Se presentó un error al establecer la fecha de expiración", "The public link will expire no later than {days} days after it is created" : "La liga pública expirará a los {days} días de haber sido creada", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compartido mediante una liga", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (correo electrónico)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparte con otras personas ingresando una dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparte con otras personas ingresando un usuario o un grupo.", "Share with other people by entering a user or group or an email address." : "Comparte con otras personas ingresando un usuario, un grupo o una dirección de correo electrónico.", diff --git a/core/l10n/es_DO.json b/core/l10n/es_DO.json index 9ec18d03f47..4446f7c8610 100644 --- a/core/l10n/es_DO.json +++ b/core/l10n/es_DO.json @@ -168,9 +168,6 @@ "No users found for {search}" : "No se encontraron usuarios para {search}", "An error occurred (\"{message}\"). Please try again" : "Se presentó un error (\"{message}\"). Por favor vuelve a intentarlo", "An error occurred. Please try again" : "Se presentó un error. Por favor vuelve a intentarlo", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (correo electrónico)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico", @@ -321,6 +318,9 @@ "Error setting expiration date" : "Se presentó un error al establecer la fecha de expiración", "The public link will expire no later than {days} days after it is created" : "La liga pública expirará a los {days} días de haber sido creada", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compartido mediante una liga", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (correo electrónico)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparte con otras personas ingresando una dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparte con otras personas ingresando un usuario o un grupo.", "Share with other people by entering a user or group or an email address." : "Comparte con otras personas ingresando un usuario, un grupo o una dirección de correo electrónico.", diff --git a/core/l10n/es_EC.js b/core/l10n/es_EC.js index 28531d48743..d98b3dcebed 100644 --- a/core/l10n/es_EC.js +++ b/core/l10n/es_EC.js @@ -170,9 +170,6 @@ OC.L10N.register( "No users found for {search}" : "No se encontraron usuarios para {search}", "An error occurred (\"{message}\"). Please try again" : "Se presentó un error (\"{message}\"). Por favor vuelve a intentarlo", "An error occurred. Please try again" : "Se presentó un error. Por favor vuelve a intentarlo", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (correo electrónico)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico", @@ -323,6 +320,9 @@ OC.L10N.register( "Error setting expiration date" : "Se presentó un error al establecer la fecha de expiración", "The public link will expire no later than {days} days after it is created" : "La liga pública expirará a los {days} días de haber sido creada", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compartido mediante una liga", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (correo electrónico)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparte con otras personas ingresando una dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparte con otras personas ingresando un usuario o un grupo.", "Share with other people by entering a user or group or an email address." : "Comparte con otras personas ingresando un usuario, un grupo o una dirección de correo electrónico.", diff --git a/core/l10n/es_EC.json b/core/l10n/es_EC.json index 9ec18d03f47..4446f7c8610 100644 --- a/core/l10n/es_EC.json +++ b/core/l10n/es_EC.json @@ -168,9 +168,6 @@ "No users found for {search}" : "No se encontraron usuarios para {search}", "An error occurred (\"{message}\"). Please try again" : "Se presentó un error (\"{message}\"). Por favor vuelve a intentarlo", "An error occurred. Please try again" : "Se presentó un error. Por favor vuelve a intentarlo", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (correo electrónico)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico", @@ -321,6 +318,9 @@ "Error setting expiration date" : "Se presentó un error al establecer la fecha de expiración", "The public link will expire no later than {days} days after it is created" : "La liga pública expirará a los {days} días de haber sido creada", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compartido mediante una liga", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (correo electrónico)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparte con otras personas ingresando una dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparte con otras personas ingresando un usuario o un grupo.", "Share with other people by entering a user or group or an email address." : "Comparte con otras personas ingresando un usuario, un grupo o una dirección de correo electrónico.", diff --git a/core/l10n/es_GT.js b/core/l10n/es_GT.js index 28531d48743..d98b3dcebed 100644 --- a/core/l10n/es_GT.js +++ b/core/l10n/es_GT.js @@ -170,9 +170,6 @@ OC.L10N.register( "No users found for {search}" : "No se encontraron usuarios para {search}", "An error occurred (\"{message}\"). Please try again" : "Se presentó un error (\"{message}\"). Por favor vuelve a intentarlo", "An error occurred. Please try again" : "Se presentó un error. Por favor vuelve a intentarlo", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (correo electrónico)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico", @@ -323,6 +320,9 @@ OC.L10N.register( "Error setting expiration date" : "Se presentó un error al establecer la fecha de expiración", "The public link will expire no later than {days} days after it is created" : "La liga pública expirará a los {days} días de haber sido creada", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compartido mediante una liga", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (correo electrónico)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparte con otras personas ingresando una dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparte con otras personas ingresando un usuario o un grupo.", "Share with other people by entering a user or group or an email address." : "Comparte con otras personas ingresando un usuario, un grupo o una dirección de correo electrónico.", diff --git a/core/l10n/es_GT.json b/core/l10n/es_GT.json index 9ec18d03f47..4446f7c8610 100644 --- a/core/l10n/es_GT.json +++ b/core/l10n/es_GT.json @@ -168,9 +168,6 @@ "No users found for {search}" : "No se encontraron usuarios para {search}", "An error occurred (\"{message}\"). Please try again" : "Se presentó un error (\"{message}\"). Por favor vuelve a intentarlo", "An error occurred. Please try again" : "Se presentó un error. Por favor vuelve a intentarlo", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (correo electrónico)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico", @@ -321,6 +318,9 @@ "Error setting expiration date" : "Se presentó un error al establecer la fecha de expiración", "The public link will expire no later than {days} days after it is created" : "La liga pública expirará a los {days} días de haber sido creada", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compartido mediante una liga", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (correo electrónico)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparte con otras personas ingresando una dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparte con otras personas ingresando un usuario o un grupo.", "Share with other people by entering a user or group or an email address." : "Comparte con otras personas ingresando un usuario, un grupo o una dirección de correo electrónico.", diff --git a/core/l10n/es_HN.js b/core/l10n/es_HN.js index f44a641ce1e..6cb4f43e6a8 100644 --- a/core/l10n/es_HN.js +++ b/core/l10n/es_HN.js @@ -167,9 +167,6 @@ OC.L10N.register( "No users or groups found for {search}" : "No se encontraron usuarios o gurpos para {search}", "No users found for {search}" : "No se encontraron usuarios para {search}", "An error occurred. Please try again" : "Se presentó un error. Por favor vuelve a intentarlo", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (correo electrónico)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico", @@ -294,6 +291,9 @@ OC.L10N.register( "Error setting expiration date" : "Se presentó un error al establecer la fecha de expiración", "The public link will expire no later than {days} days after it is created" : "La liga pública expirará a los {days} días de haber sido creada", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compartido mediante una liga", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (correo electrónico)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparte con otras personas ingresando una dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparte con otras personas ingresando un usuario o un grupo.", "Share with other people by entering a user or group or an email address." : "Comparte con otras personas ingresando un usuario, un grupo o una dirección de correo electrónico.", diff --git a/core/l10n/es_HN.json b/core/l10n/es_HN.json index 62d866f1327..fcb62367d14 100644 --- a/core/l10n/es_HN.json +++ b/core/l10n/es_HN.json @@ -165,9 +165,6 @@ "No users or groups found for {search}" : "No se encontraron usuarios o gurpos para {search}", "No users found for {search}" : "No se encontraron usuarios para {search}", "An error occurred. Please try again" : "Se presentó un error. Por favor vuelve a intentarlo", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (correo electrónico)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico", @@ -292,6 +289,9 @@ "Error setting expiration date" : "Se presentó un error al establecer la fecha de expiración", "The public link will expire no later than {days} days after it is created" : "La liga pública expirará a los {days} días de haber sido creada", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compartido mediante una liga", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (correo electrónico)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparte con otras personas ingresando una dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparte con otras personas ingresando un usuario o un grupo.", "Share with other people by entering a user or group or an email address." : "Comparte con otras personas ingresando un usuario, un grupo o una dirección de correo electrónico.", diff --git a/core/l10n/es_MX.js b/core/l10n/es_MX.js index cfa292606c7..705c2721a69 100644 --- a/core/l10n/es_MX.js +++ b/core/l10n/es_MX.js @@ -170,9 +170,6 @@ OC.L10N.register( "No users found for {search}" : "No se encontraron usuarios para {search}", "An error occurred (\"{message}\"). Please try again" : "Se presentó un error (\"{message}\"). Por favor vuelve a intentarlo", "An error occurred. Please try again" : "Se presentó un error. Por favor vuelve a intentarlo", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (correo electrónico)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico", @@ -323,6 +320,9 @@ OC.L10N.register( "Error setting expiration date" : "Se presentó un error al establecer la fecha de expiración", "The public link will expire no later than {days} days after it is created" : "La liga pública expirará a los {days} días de haber sido creada", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compartido mediante una liga", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (correo electrónico)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparte con otras personas ingresando una dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparte con otras personas ingresando un usuario o un grupo.", "Share with other people by entering a user or group or an email address." : "Comparte con otras personas ingresando un usuario, un grupo o una dirección de correo electrónico.", diff --git a/core/l10n/es_MX.json b/core/l10n/es_MX.json index ea929476c1f..87529c8e1b2 100644 --- a/core/l10n/es_MX.json +++ b/core/l10n/es_MX.json @@ -168,9 +168,6 @@ "No users found for {search}" : "No se encontraron usuarios para {search}", "An error occurred (\"{message}\"). Please try again" : "Se presentó un error (\"{message}\"). Por favor vuelve a intentarlo", "An error occurred. Please try again" : "Se presentó un error. Por favor vuelve a intentarlo", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (correo electrónico)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico", @@ -321,6 +318,9 @@ "Error setting expiration date" : "Se presentó un error al establecer la fecha de expiración", "The public link will expire no later than {days} days after it is created" : "La liga pública expirará a los {days} días de haber sido creada", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compartido mediante una liga", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (correo electrónico)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparte con otras personas ingresando una dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparte con otras personas ingresando un usuario o un grupo.", "Share with other people by entering a user or group or an email address." : "Comparte con otras personas ingresando un usuario, un grupo o una dirección de correo electrónico.", diff --git a/core/l10n/es_NI.js b/core/l10n/es_NI.js index f44a641ce1e..6cb4f43e6a8 100644 --- a/core/l10n/es_NI.js +++ b/core/l10n/es_NI.js @@ -167,9 +167,6 @@ OC.L10N.register( "No users or groups found for {search}" : "No se encontraron usuarios o gurpos para {search}", "No users found for {search}" : "No se encontraron usuarios para {search}", "An error occurred. Please try again" : "Se presentó un error. Por favor vuelve a intentarlo", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (correo electrónico)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico", @@ -294,6 +291,9 @@ OC.L10N.register( "Error setting expiration date" : "Se presentó un error al establecer la fecha de expiración", "The public link will expire no later than {days} days after it is created" : "La liga pública expirará a los {days} días de haber sido creada", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compartido mediante una liga", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (correo electrónico)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparte con otras personas ingresando una dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparte con otras personas ingresando un usuario o un grupo.", "Share with other people by entering a user or group or an email address." : "Comparte con otras personas ingresando un usuario, un grupo o una dirección de correo electrónico.", diff --git a/core/l10n/es_NI.json b/core/l10n/es_NI.json index 62d866f1327..fcb62367d14 100644 --- a/core/l10n/es_NI.json +++ b/core/l10n/es_NI.json @@ -165,9 +165,6 @@ "No users or groups found for {search}" : "No se encontraron usuarios o gurpos para {search}", "No users found for {search}" : "No se encontraron usuarios para {search}", "An error occurred. Please try again" : "Se presentó un error. Por favor vuelve a intentarlo", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (correo electrónico)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico", @@ -292,6 +289,9 @@ "Error setting expiration date" : "Se presentó un error al establecer la fecha de expiración", "The public link will expire no later than {days} days after it is created" : "La liga pública expirará a los {days} días de haber sido creada", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compartido mediante una liga", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (correo electrónico)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparte con otras personas ingresando una dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparte con otras personas ingresando un usuario o un grupo.", "Share with other people by entering a user or group or an email address." : "Comparte con otras personas ingresando un usuario, un grupo o una dirección de correo electrónico.", diff --git a/core/l10n/es_PA.js b/core/l10n/es_PA.js index f44a641ce1e..6cb4f43e6a8 100644 --- a/core/l10n/es_PA.js +++ b/core/l10n/es_PA.js @@ -167,9 +167,6 @@ OC.L10N.register( "No users or groups found for {search}" : "No se encontraron usuarios o gurpos para {search}", "No users found for {search}" : "No se encontraron usuarios para {search}", "An error occurred. Please try again" : "Se presentó un error. Por favor vuelve a intentarlo", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (correo electrónico)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico", @@ -294,6 +291,9 @@ OC.L10N.register( "Error setting expiration date" : "Se presentó un error al establecer la fecha de expiración", "The public link will expire no later than {days} days after it is created" : "La liga pública expirará a los {days} días de haber sido creada", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compartido mediante una liga", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (correo electrónico)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparte con otras personas ingresando una dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparte con otras personas ingresando un usuario o un grupo.", "Share with other people by entering a user or group or an email address." : "Comparte con otras personas ingresando un usuario, un grupo o una dirección de correo electrónico.", diff --git a/core/l10n/es_PA.json b/core/l10n/es_PA.json index 62d866f1327..fcb62367d14 100644 --- a/core/l10n/es_PA.json +++ b/core/l10n/es_PA.json @@ -165,9 +165,6 @@ "No users or groups found for {search}" : "No se encontraron usuarios o gurpos para {search}", "No users found for {search}" : "No se encontraron usuarios para {search}", "An error occurred. Please try again" : "Se presentó un error. Por favor vuelve a intentarlo", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (correo electrónico)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico", @@ -292,6 +289,9 @@ "Error setting expiration date" : "Se presentó un error al establecer la fecha de expiración", "The public link will expire no later than {days} days after it is created" : "La liga pública expirará a los {days} días de haber sido creada", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compartido mediante una liga", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (correo electrónico)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparte con otras personas ingresando una dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparte con otras personas ingresando un usuario o un grupo.", "Share with other people by entering a user or group or an email address." : "Comparte con otras personas ingresando un usuario, un grupo o una dirección de correo electrónico.", diff --git a/core/l10n/es_PE.js b/core/l10n/es_PE.js index f44a641ce1e..6cb4f43e6a8 100644 --- a/core/l10n/es_PE.js +++ b/core/l10n/es_PE.js @@ -167,9 +167,6 @@ OC.L10N.register( "No users or groups found for {search}" : "No se encontraron usuarios o gurpos para {search}", "No users found for {search}" : "No se encontraron usuarios para {search}", "An error occurred. Please try again" : "Se presentó un error. Por favor vuelve a intentarlo", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (correo electrónico)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico", @@ -294,6 +291,9 @@ OC.L10N.register( "Error setting expiration date" : "Se presentó un error al establecer la fecha de expiración", "The public link will expire no later than {days} days after it is created" : "La liga pública expirará a los {days} días de haber sido creada", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compartido mediante una liga", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (correo electrónico)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparte con otras personas ingresando una dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparte con otras personas ingresando un usuario o un grupo.", "Share with other people by entering a user or group or an email address." : "Comparte con otras personas ingresando un usuario, un grupo o una dirección de correo electrónico.", diff --git a/core/l10n/es_PE.json b/core/l10n/es_PE.json index 62d866f1327..fcb62367d14 100644 --- a/core/l10n/es_PE.json +++ b/core/l10n/es_PE.json @@ -165,9 +165,6 @@ "No users or groups found for {search}" : "No se encontraron usuarios o gurpos para {search}", "No users found for {search}" : "No se encontraron usuarios para {search}", "An error occurred. Please try again" : "Se presentó un error. Por favor vuelve a intentarlo", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (correo electrónico)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico", @@ -292,6 +289,9 @@ "Error setting expiration date" : "Se presentó un error al establecer la fecha de expiración", "The public link will expire no later than {days} days after it is created" : "La liga pública expirará a los {days} días de haber sido creada", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compartido mediante una liga", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (correo electrónico)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparte con otras personas ingresando una dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparte con otras personas ingresando un usuario o un grupo.", "Share with other people by entering a user or group or an email address." : "Comparte con otras personas ingresando un usuario, un grupo o una dirección de correo electrónico.", diff --git a/core/l10n/es_PR.js b/core/l10n/es_PR.js index f44a641ce1e..6cb4f43e6a8 100644 --- a/core/l10n/es_PR.js +++ b/core/l10n/es_PR.js @@ -167,9 +167,6 @@ OC.L10N.register( "No users or groups found for {search}" : "No se encontraron usuarios o gurpos para {search}", "No users found for {search}" : "No se encontraron usuarios para {search}", "An error occurred. Please try again" : "Se presentó un error. Por favor vuelve a intentarlo", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (correo electrónico)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico", @@ -294,6 +291,9 @@ OC.L10N.register( "Error setting expiration date" : "Se presentó un error al establecer la fecha de expiración", "The public link will expire no later than {days} days after it is created" : "La liga pública expirará a los {days} días de haber sido creada", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compartido mediante una liga", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (correo electrónico)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparte con otras personas ingresando una dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparte con otras personas ingresando un usuario o un grupo.", "Share with other people by entering a user or group or an email address." : "Comparte con otras personas ingresando un usuario, un grupo o una dirección de correo electrónico.", diff --git a/core/l10n/es_PR.json b/core/l10n/es_PR.json index 62d866f1327..fcb62367d14 100644 --- a/core/l10n/es_PR.json +++ b/core/l10n/es_PR.json @@ -165,9 +165,6 @@ "No users or groups found for {search}" : "No se encontraron usuarios o gurpos para {search}", "No users found for {search}" : "No se encontraron usuarios para {search}", "An error occurred. Please try again" : "Se presentó un error. Por favor vuelve a intentarlo", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (correo electrónico)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico", @@ -292,6 +289,9 @@ "Error setting expiration date" : "Se presentó un error al establecer la fecha de expiración", "The public link will expire no later than {days} days after it is created" : "La liga pública expirará a los {days} días de haber sido creada", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compartido mediante una liga", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (correo electrónico)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparte con otras personas ingresando una dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparte con otras personas ingresando un usuario o un grupo.", "Share with other people by entering a user or group or an email address." : "Comparte con otras personas ingresando un usuario, un grupo o una dirección de correo electrónico.", diff --git a/core/l10n/es_PY.js b/core/l10n/es_PY.js index f44a641ce1e..6cb4f43e6a8 100644 --- a/core/l10n/es_PY.js +++ b/core/l10n/es_PY.js @@ -167,9 +167,6 @@ OC.L10N.register( "No users or groups found for {search}" : "No se encontraron usuarios o gurpos para {search}", "No users found for {search}" : "No se encontraron usuarios para {search}", "An error occurred. Please try again" : "Se presentó un error. Por favor vuelve a intentarlo", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (correo electrónico)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico", @@ -294,6 +291,9 @@ OC.L10N.register( "Error setting expiration date" : "Se presentó un error al establecer la fecha de expiración", "The public link will expire no later than {days} days after it is created" : "La liga pública expirará a los {days} días de haber sido creada", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compartido mediante una liga", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (correo electrónico)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparte con otras personas ingresando una dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparte con otras personas ingresando un usuario o un grupo.", "Share with other people by entering a user or group or an email address." : "Comparte con otras personas ingresando un usuario, un grupo o una dirección de correo electrónico.", diff --git a/core/l10n/es_PY.json b/core/l10n/es_PY.json index 62d866f1327..fcb62367d14 100644 --- a/core/l10n/es_PY.json +++ b/core/l10n/es_PY.json @@ -165,9 +165,6 @@ "No users or groups found for {search}" : "No se encontraron usuarios o gurpos para {search}", "No users found for {search}" : "No se encontraron usuarios para {search}", "An error occurred. Please try again" : "Se presentó un error. Por favor vuelve a intentarlo", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (correo electrónico)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico", @@ -292,6 +289,9 @@ "Error setting expiration date" : "Se presentó un error al establecer la fecha de expiración", "The public link will expire no later than {days} days after it is created" : "La liga pública expirará a los {days} días de haber sido creada", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compartido mediante una liga", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (correo electrónico)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparte con otras personas ingresando una dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparte con otras personas ingresando un usuario o un grupo.", "Share with other people by entering a user or group or an email address." : "Comparte con otras personas ingresando un usuario, un grupo o una dirección de correo electrónico.", diff --git a/core/l10n/es_SV.js b/core/l10n/es_SV.js index 28531d48743..d98b3dcebed 100644 --- a/core/l10n/es_SV.js +++ b/core/l10n/es_SV.js @@ -170,9 +170,6 @@ OC.L10N.register( "No users found for {search}" : "No se encontraron usuarios para {search}", "An error occurred (\"{message}\"). Please try again" : "Se presentó un error (\"{message}\"). Por favor vuelve a intentarlo", "An error occurred. Please try again" : "Se presentó un error. Por favor vuelve a intentarlo", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (correo electrónico)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico", @@ -323,6 +320,9 @@ OC.L10N.register( "Error setting expiration date" : "Se presentó un error al establecer la fecha de expiración", "The public link will expire no later than {days} days after it is created" : "La liga pública expirará a los {days} días de haber sido creada", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compartido mediante una liga", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (correo electrónico)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparte con otras personas ingresando una dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparte con otras personas ingresando un usuario o un grupo.", "Share with other people by entering a user or group or an email address." : "Comparte con otras personas ingresando un usuario, un grupo o una dirección de correo electrónico.", diff --git a/core/l10n/es_SV.json b/core/l10n/es_SV.json index 9ec18d03f47..4446f7c8610 100644 --- a/core/l10n/es_SV.json +++ b/core/l10n/es_SV.json @@ -168,9 +168,6 @@ "No users found for {search}" : "No se encontraron usuarios para {search}", "An error occurred (\"{message}\"). Please try again" : "Se presentó un error (\"{message}\"). Por favor vuelve a intentarlo", "An error occurred. Please try again" : "Se presentó un error. Por favor vuelve a intentarlo", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (correo electrónico)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico", @@ -321,6 +318,9 @@ "Error setting expiration date" : "Se presentó un error al establecer la fecha de expiración", "The public link will expire no later than {days} days after it is created" : "La liga pública expirará a los {days} días de haber sido creada", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compartido mediante una liga", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (correo electrónico)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparte con otras personas ingresando una dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparte con otras personas ingresando un usuario o un grupo.", "Share with other people by entering a user or group or an email address." : "Comparte con otras personas ingresando un usuario, un grupo o una dirección de correo electrónico.", diff --git a/core/l10n/es_UY.js b/core/l10n/es_UY.js index f44a641ce1e..6cb4f43e6a8 100644 --- a/core/l10n/es_UY.js +++ b/core/l10n/es_UY.js @@ -167,9 +167,6 @@ OC.L10N.register( "No users or groups found for {search}" : "No se encontraron usuarios o gurpos para {search}", "No users found for {search}" : "No se encontraron usuarios para {search}", "An error occurred. Please try again" : "Se presentó un error. Por favor vuelve a intentarlo", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (correo electrónico)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico", @@ -294,6 +291,9 @@ OC.L10N.register( "Error setting expiration date" : "Se presentó un error al establecer la fecha de expiración", "The public link will expire no later than {days} days after it is created" : "La liga pública expirará a los {days} días de haber sido creada", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compartido mediante una liga", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (correo electrónico)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparte con otras personas ingresando una dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparte con otras personas ingresando un usuario o un grupo.", "Share with other people by entering a user or group or an email address." : "Comparte con otras personas ingresando un usuario, un grupo o una dirección de correo electrónico.", diff --git a/core/l10n/es_UY.json b/core/l10n/es_UY.json index 62d866f1327..fcb62367d14 100644 --- a/core/l10n/es_UY.json +++ b/core/l10n/es_UY.json @@ -165,9 +165,6 @@ "No users or groups found for {search}" : "No se encontraron usuarios o gurpos para {search}", "No users found for {search}" : "No se encontraron usuarios para {search}", "An error occurred. Please try again" : "Se presentó un error. Por favor vuelve a intentarlo", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (correo electrónico)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Compartir", "Name or email address..." : "Nombre o dirección de correo electrónico", @@ -292,6 +289,9 @@ "Error setting expiration date" : "Se presentó un error al establecer la fecha de expiración", "The public link will expire no later than {days} days after it is created" : "La liga pública expirará a los {days} días de haber sido creada", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha compartido mediante una liga", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (correo electrónico)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Comparte con otras personas ingresando una dirección de correo electrónico.", "Share with other people by entering a user or group or a federated cloud ID." : "Comparte con otras personas ingresando un usuario o un grupo.", "Share with other people by entering a user or group or an email address." : "Comparte con otras personas ingresando un usuario, un grupo o una dirección de correo electrónico.", diff --git a/core/l10n/et_EE.js b/core/l10n/et_EE.js index f52158fff67..d5dc8f888a1 100644 --- a/core/l10n/et_EE.js +++ b/core/l10n/et_EE.js @@ -153,9 +153,6 @@ OC.L10N.register( "No users or groups found for {search}" : "Otsingu {search} põhjal kasutajaid ega gruppe ei leitud", "No users found for {search}" : "Otsingu {search} põhjal kasutajaid ei leitud", "An error occurred. Please try again" : "Tekkis tõrge. Palun proovi uuesti", - "{sharee} (group)" : "{sharee} (grupp)", - "{sharee} (remote)" : "{sharee} (mujal serveris)", - "{sharee} (email)" : "{sharee} (e-post)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Jaga", "Name or email address..." : "Nimi või e-posti aadress", @@ -275,6 +272,9 @@ OC.L10N.register( "Error setting expiration date" : "Viga aegumise kuupäeva määramisel", "The public link will expire no later than {days} days after it is created" : "Avalik link aegub mitte hiljem kui pärast {days} päeva selle loomist", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} lingiga jagatud", + "{sharee} (group)" : "{sharee} (grupp)", + "{sharee} (remote)" : "{sharee} (mujal serveris)", + "{sharee} (email)" : "{sharee} (e-post)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Jaga teiste inimestega sisestades kasutaja või grupi, liitpilve ID või e-posti aadressi.", "Share with other people by entering a user or group or a federated cloud ID." : "Jaga teiste inimestega, sisestades kasutaja või grupi või liitpilve ID.", "Share with other people by entering a user or group or an email address." : "Jaga teiste inimestega, sisestades kasutaja, grupi või e-posti aadressi.", diff --git a/core/l10n/et_EE.json b/core/l10n/et_EE.json index 7ae2161a144..01c2d1626d2 100644 --- a/core/l10n/et_EE.json +++ b/core/l10n/et_EE.json @@ -151,9 +151,6 @@ "No users or groups found for {search}" : "Otsingu {search} põhjal kasutajaid ega gruppe ei leitud", "No users found for {search}" : "Otsingu {search} põhjal kasutajaid ei leitud", "An error occurred. Please try again" : "Tekkis tõrge. Palun proovi uuesti", - "{sharee} (group)" : "{sharee} (grupp)", - "{sharee} (remote)" : "{sharee} (mujal serveris)", - "{sharee} (email)" : "{sharee} (e-post)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Jaga", "Name or email address..." : "Nimi või e-posti aadress", @@ -273,6 +270,9 @@ "Error setting expiration date" : "Viga aegumise kuupäeva määramisel", "The public link will expire no later than {days} days after it is created" : "Avalik link aegub mitte hiljem kui pärast {days} päeva selle loomist", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} lingiga jagatud", + "{sharee} (group)" : "{sharee} (grupp)", + "{sharee} (remote)" : "{sharee} (mujal serveris)", + "{sharee} (email)" : "{sharee} (e-post)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Jaga teiste inimestega sisestades kasutaja või grupi, liitpilve ID või e-posti aadressi.", "Share with other people by entering a user or group or a federated cloud ID." : "Jaga teiste inimestega, sisestades kasutaja või grupi või liitpilve ID.", "Share with other people by entering a user or group or an email address." : "Jaga teiste inimestega, sisestades kasutaja, grupi või e-posti aadressi.", diff --git a/core/l10n/eu.js b/core/l10n/eu.js index 041313326a6..248409d80d7 100644 --- a/core/l10n/eu.js +++ b/core/l10n/eu.js @@ -150,9 +150,6 @@ OC.L10N.register( "No users or groups found for {search}" : "Ez dira {search} -rentzat erabiltzaile edo talderik aurkitu", "No users found for {search}" : "Ez dira {search} -rentzat erabiltzailerik aurkitu", "An error occurred. Please try again" : "Errore bat gertatu da. Saiatu berriro.", - "{sharee} (group)" : "{sharee} (taldea)", - "{sharee} (remote)" : "{sharee} (urrunekoa)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {jabea})", "Share" : "Partekatu", "Name or email address..." : "Izena edo e-posta helbidea...", @@ -273,6 +270,9 @@ OC.L10N.register( "Error setting expiration date" : "Errore bat egon da muga data ezartzean", "The public link will expire no later than {days} days after it is created" : "Esteka publikoak iraungi egingo du, askoz jota, sortu eta {days} egunetara.", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} esteka bidez partekatuta", + "{sharee} (group)" : "{sharee} (taldea)", + "{sharee} (remote)" : "{sharee} (urrunekoa)", + "{sharee} (email)" : "{sharee} (email)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Parteka ezazu jendearekin taldeko erabiltzailea, federatutako hodei baten IDa edo e-posta helbide bat sartuta.", "Share with other people by entering a user or group or a federated cloud ID." : "Parteka ezazu jendearekin taldeko erabiltzailea edo federatutako hodei baten IDa sartuta.", "Share with other people by entering a user or group or an email address." : "Parteka ezazu jendearekin taldeko erabiltzailea edo e-posta helbide bat sartuta.", diff --git a/core/l10n/eu.json b/core/l10n/eu.json index 37d0faa64b9..686e31fcc7d 100644 --- a/core/l10n/eu.json +++ b/core/l10n/eu.json @@ -148,9 +148,6 @@ "No users or groups found for {search}" : "Ez dira {search} -rentzat erabiltzaile edo talderik aurkitu", "No users found for {search}" : "Ez dira {search} -rentzat erabiltzailerik aurkitu", "An error occurred. Please try again" : "Errore bat gertatu da. Saiatu berriro.", - "{sharee} (group)" : "{sharee} (taldea)", - "{sharee} (remote)" : "{sharee} (urrunekoa)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {jabea})", "Share" : "Partekatu", "Name or email address..." : "Izena edo e-posta helbidea...", @@ -271,6 +268,9 @@ "Error setting expiration date" : "Errore bat egon da muga data ezartzean", "The public link will expire no later than {days} days after it is created" : "Esteka publikoak iraungi egingo du, askoz jota, sortu eta {days} egunetara.", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} esteka bidez partekatuta", + "{sharee} (group)" : "{sharee} (taldea)", + "{sharee} (remote)" : "{sharee} (urrunekoa)", + "{sharee} (email)" : "{sharee} (email)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Parteka ezazu jendearekin taldeko erabiltzailea, federatutako hodei baten IDa edo e-posta helbide bat sartuta.", "Share with other people by entering a user or group or a federated cloud ID." : "Parteka ezazu jendearekin taldeko erabiltzailea edo federatutako hodei baten IDa sartuta.", "Share with other people by entering a user or group or an email address." : "Parteka ezazu jendearekin taldeko erabiltzailea edo e-posta helbide bat sartuta.", diff --git a/core/l10n/fa.js b/core/l10n/fa.js index 6c5cd28899c..1b8c916cffe 100644 --- a/core/l10n/fa.js +++ b/core/l10n/fa.js @@ -150,9 +150,6 @@ OC.L10N.register( "No users or groups found for {search}" : "هیچ کاربری یا گروهی یافت نشد {search}", "No users found for {search}" : "هیچ کاربری با جستجوی {search} یافت نشد", "An error occurred. Please try again" : "یک خطا رخ داده است، لطفا مجددا تلاش کنید", - "{sharee} (group)" : "{sharee} (group)", - "{sharee} (remote)" : "{sharee} (remote)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "اشتراکگذاری", "Name or email address..." : "نام یا آدرس ایمیل ...", @@ -257,6 +254,9 @@ OC.L10N.register( "Error setting expiration date" : "خطا در تنظیم تاریخ انقضا", "The public link will expire no later than {days} days after it is created" : "لینک عمومی پس از {days} روز پس از ایجاد منقضی خواهد شد", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} به اشتراک گذاشته شده از طریق لینک", + "{sharee} (group)" : "{sharee} (group)", + "{sharee} (remote)" : "{sharee} (remote)", + "{sharee} (email)" : "{sharee} (email)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "با وارد کردن یک کاربر یا گروه، شناسه Federated Cloud یا آدرس ایمیل با دیگران به اشتراک بگذارید.", "Share with other people by entering a user or group or a federated cloud ID." : "با وارد کردن یک کاربر یا گروه یا شناسه Federated Cloud با افراد دیگر به اشتراک بگذارید.", "Share with other people by entering a user or group or an email address." : "با وارد کردن یک کاربر یا گروه یا یک آدرس ایمیل با افراد دیگر به اشتراک بگذارید.", diff --git a/core/l10n/fa.json b/core/l10n/fa.json index 24e8130b426..96cc772cc9e 100644 --- a/core/l10n/fa.json +++ b/core/l10n/fa.json @@ -148,9 +148,6 @@ "No users or groups found for {search}" : "هیچ کاربری یا گروهی یافت نشد {search}", "No users found for {search}" : "هیچ کاربری با جستجوی {search} یافت نشد", "An error occurred. Please try again" : "یک خطا رخ داده است، لطفا مجددا تلاش کنید", - "{sharee} (group)" : "{sharee} (group)", - "{sharee} (remote)" : "{sharee} (remote)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "اشتراکگذاری", "Name or email address..." : "نام یا آدرس ایمیل ...", @@ -255,6 +252,9 @@ "Error setting expiration date" : "خطا در تنظیم تاریخ انقضا", "The public link will expire no later than {days} days after it is created" : "لینک عمومی پس از {days} روز پس از ایجاد منقضی خواهد شد", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} به اشتراک گذاشته شده از طریق لینک", + "{sharee} (group)" : "{sharee} (group)", + "{sharee} (remote)" : "{sharee} (remote)", + "{sharee} (email)" : "{sharee} (email)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "با وارد کردن یک کاربر یا گروه، شناسه Federated Cloud یا آدرس ایمیل با دیگران به اشتراک بگذارید.", "Share with other people by entering a user or group or a federated cloud ID." : "با وارد کردن یک کاربر یا گروه یا شناسه Federated Cloud با افراد دیگر به اشتراک بگذارید.", "Share with other people by entering a user or group or an email address." : "با وارد کردن یک کاربر یا گروه یا یک آدرس ایمیل با افراد دیگر به اشتراک بگذارید.", diff --git a/core/l10n/fi.js b/core/l10n/fi.js index 8cbbf37cc80..52f76812da4 100644 --- a/core/l10n/fi.js +++ b/core/l10n/fi.js @@ -180,9 +180,6 @@ OC.L10N.register( "No users found for {search}" : "Haulla {search} ei löytynyt käyttäjiä", "An error occurred (\"{message}\"). Please try again" : "Tapahtui virhe (\"{message}\"). Yritä uudestaan", "An error occurred. Please try again" : "Tapahtui virhe, yritä uudelleen", - "{sharee} (group)" : "{sharee} (ryhmä)", - "{sharee} (remote)" : "{sharee} (etä)", - "{sharee} (email)" : "{sharee} (sähköposti)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Jaa", "Name or email address..." : "Nimi tai sähköpostiosoite...", @@ -332,6 +329,9 @@ OC.L10N.register( "Error setting expiration date" : "Virhe vanhenemispäivää asetettaessa", "The public link will expire no later than {days} days after it is created" : "Julkinen linkki vanhenee {days} päivän jälkeen sen luomisesta", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} jakoi linkillä", + "{sharee} (group)" : "{sharee} (ryhmä)", + "{sharee} (remote)" : "{sharee} (etä)", + "{sharee} (email)" : "{sharee} (sähköposti)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Jaa muille kirjoittamalla käyttäjä tai ryhmä, federoidun pilven tunniste tai sähköpostiosoite.", "Share with other people by entering a user or group or a federated cloud ID." : "Jaa muille kirjoittamalla käyttäjä, ryhmä tai federoidun pilven tunniste.", "Share with other people by entering a user or group or an email address." : "Jaa muille kirjoittamalla käyttäjä, ryhmä tai sähköpostiosoite.", diff --git a/core/l10n/fi.json b/core/l10n/fi.json index 22bcbca652b..cd83c50269d 100644 --- a/core/l10n/fi.json +++ b/core/l10n/fi.json @@ -178,9 +178,6 @@ "No users found for {search}" : "Haulla {search} ei löytynyt käyttäjiä", "An error occurred (\"{message}\"). Please try again" : "Tapahtui virhe (\"{message}\"). Yritä uudestaan", "An error occurred. Please try again" : "Tapahtui virhe, yritä uudelleen", - "{sharee} (group)" : "{sharee} (ryhmä)", - "{sharee} (remote)" : "{sharee} (etä)", - "{sharee} (email)" : "{sharee} (sähköposti)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Jaa", "Name or email address..." : "Nimi tai sähköpostiosoite...", @@ -330,6 +327,9 @@ "Error setting expiration date" : "Virhe vanhenemispäivää asetettaessa", "The public link will expire no later than {days} days after it is created" : "Julkinen linkki vanhenee {days} päivän jälkeen sen luomisesta", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} jakoi linkillä", + "{sharee} (group)" : "{sharee} (ryhmä)", + "{sharee} (remote)" : "{sharee} (etä)", + "{sharee} (email)" : "{sharee} (sähköposti)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Jaa muille kirjoittamalla käyttäjä tai ryhmä, federoidun pilven tunniste tai sähköpostiosoite.", "Share with other people by entering a user or group or a federated cloud ID." : "Jaa muille kirjoittamalla käyttäjä, ryhmä tai federoidun pilven tunniste.", "Share with other people by entering a user or group or an email address." : "Jaa muille kirjoittamalla käyttäjä, ryhmä tai sähköpostiosoite.", diff --git a/core/l10n/fr.js b/core/l10n/fr.js index a0e31cc9e93..5eaf3ba99f8 100644 --- a/core/l10n/fr.js +++ b/core/l10n/fr.js @@ -210,12 +210,8 @@ OC.L10N.register( "No users found for {search}" : "Aucun utilisateur trouvé pour {search}", "An error occurred (\"{message}\"). Please try again" : "Une erreur est survenue (\"{message}\"). Veuillez réessayer", "An error occurred. Please try again" : "Une erreur est survenue. Merci de réessayer", - "{sharee} (group)" : "{sharee} (groupe)", - "{sharee} (remote)" : "{sharee} (distant)", "{sharee} (remote group)" : "{sharee} (groupe distant)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (discussion)", "Share" : "Partager", "Name or email address..." : "Nom ou adresse mail...", "Name or federated cloud ID..." : "Nom ou ID du cloud fédéré...", @@ -382,6 +378,9 @@ OC.L10N.register( "Error setting expiration date" : "Erreur lors de la configuration de la date d'expiration", "The public link will expire no later than {days} days after it is created" : "Ce lien public expirera dans {days} jours après sa création.", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} a partagé via un lien", + "{sharee} (group)" : "{sharee} (groupe)", + "{sharee} (remote)" : "{sharee} (distant)", + "{sharee} (email)" : "{sharee} (email)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Partager avec d'autres personnes en indiquant un nom d'utilisateur, un groupe, un identifiant de cloud fédéré ou une adresse email.", "Share with other people by entering a user or group or a federated cloud ID." : "Partager avec d'autres personnes en indiquant un utilisateur, un groupe ou un identifiant de cloud fédéré.", "Share with other people by entering a user or group or an email address." : "Partager avec d'autres personnes en indiquant un utilisateur, un groupe ou une adresse email.", @@ -413,6 +412,7 @@ OC.L10N.register( "You are about to grant %s access to your %s account." : "Vous êtes sur le point d'accorder à \"%s\" l'accès à votre compte \"%s\".", "Depending on your configuration, this button could also work to trust the domain:" : "En fonction de votre configuration, ce bouton peut aussi fonctionner pour approuver ce domaine :", "Copy URL" : "Copier l'adresse URL", + "{sharee} (conversation)" : "{sharee} (discussion)", "Please log in before granting %s access to your %s account." : "Veuillez vous connecter avant d'autoriser %s à accéder à votre compte %s.", "Further information how to configure this can be found in the %sdocumentation%s." : "Vous trouverez d'autres informations sur la configuration dans la %sdocumentation %s." }, diff --git a/core/l10n/fr.json b/core/l10n/fr.json index 8aa4264d799..d526c33fc7b 100644 --- a/core/l10n/fr.json +++ b/core/l10n/fr.json @@ -208,12 +208,8 @@ "No users found for {search}" : "Aucun utilisateur trouvé pour {search}", "An error occurred (\"{message}\"). Please try again" : "Une erreur est survenue (\"{message}\"). Veuillez réessayer", "An error occurred. Please try again" : "Une erreur est survenue. Merci de réessayer", - "{sharee} (group)" : "{sharee} (groupe)", - "{sharee} (remote)" : "{sharee} (distant)", "{sharee} (remote group)" : "{sharee} (groupe distant)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (discussion)", "Share" : "Partager", "Name or email address..." : "Nom ou adresse mail...", "Name or federated cloud ID..." : "Nom ou ID du cloud fédéré...", @@ -380,6 +376,9 @@ "Error setting expiration date" : "Erreur lors de la configuration de la date d'expiration", "The public link will expire no later than {days} days after it is created" : "Ce lien public expirera dans {days} jours après sa création.", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} a partagé via un lien", + "{sharee} (group)" : "{sharee} (groupe)", + "{sharee} (remote)" : "{sharee} (distant)", + "{sharee} (email)" : "{sharee} (email)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Partager avec d'autres personnes en indiquant un nom d'utilisateur, un groupe, un identifiant de cloud fédéré ou une adresse email.", "Share with other people by entering a user or group or a federated cloud ID." : "Partager avec d'autres personnes en indiquant un utilisateur, un groupe ou un identifiant de cloud fédéré.", "Share with other people by entering a user or group or an email address." : "Partager avec d'autres personnes en indiquant un utilisateur, un groupe ou une adresse email.", @@ -411,6 +410,7 @@ "You are about to grant %s access to your %s account." : "Vous êtes sur le point d'accorder à \"%s\" l'accès à votre compte \"%s\".", "Depending on your configuration, this button could also work to trust the domain:" : "En fonction de votre configuration, ce bouton peut aussi fonctionner pour approuver ce domaine :", "Copy URL" : "Copier l'adresse URL", + "{sharee} (conversation)" : "{sharee} (discussion)", "Please log in before granting %s access to your %s account." : "Veuillez vous connecter avant d'autoriser %s à accéder à votre compte %s.", "Further information how to configure this can be found in the %sdocumentation%s." : "Vous trouverez d'autres informations sur la configuration dans la %sdocumentation %s." },"pluralForm" :"nplurals=2; plural=(n > 1);" diff --git a/core/l10n/he.js b/core/l10n/he.js index 06645532032..5b34af12545 100644 --- a/core/l10n/he.js +++ b/core/l10n/he.js @@ -198,12 +198,8 @@ OC.L10N.register( "No users found for {search}" : "לא אותרו משתמשים עבור {search}", "An error occurred (\"{message}\"). Please try again" : "אירעה שגיאה (\"{message}\"). נא לנסות שוב", "An error occurred. Please try again" : "אירעה שגיאה. יש לנסות שנית", - "{sharee} (group)" : "{sharee} (קבוצה)", - "{sharee} (remote)" : "{sharee} (מרוחק)", "{sharee} (remote group)" : "{sharee} (קבוצה מרוחקת)", - "{sharee} (email)" : "{sharee} (דוא״ל)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (דיון)", "Share" : "שתף", "Name or email address..." : "שם או כתובת דוא״ל…", "Name or federated cloud ID..." : "שם או מזהה ענן מאוגד…", @@ -359,6 +355,9 @@ OC.L10N.register( "Error setting expiration date" : "אירעה שגיאה בעת הגדרת תאריך התפוגה", "The public link will expire no later than {days} days after it is created" : "הקישור הציבורי יפוג עד {days} ימים לאחר שנוצר", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} שותף על ידי קישור", + "{sharee} (group)" : "{sharee} (קבוצה)", + "{sharee} (remote)" : "{sharee} (מרוחק)", + "{sharee} (email)" : "{sharee} (דוא״ל)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "ניתן לשתף אחרים על ידי הקלדת משתמש או קבוצה או מזהה ענן מאוגד או כתובת דוא״ל.", "Share with other people by entering a user or group or a federated cloud ID." : "ניתן לשתף אחרים על ידי הקלדת משתמש או קבוצה או מזהה ענן מאוגד.", "Share with other people by entering a user or group or an email address." : "ניתן לשתף עם אנשים אחרים על ידי הקלדת משתמש או קבוצה או כתובת דוא״ל.", @@ -389,6 +388,7 @@ OC.L10N.register( "Back to log in" : "חזרה לכניסה", "You are about to grant %s access to your %s account." : "פעולה זו תעניק הרשאת %s לחשבון שלך ב־%s.", "Depending on your configuration, this button could also work to trust the domain:" : "בהתאם לתצורה שלך, הכפתור הזה יכול לעבוד גם כדי לתת אמון בשם המתחם:", + "{sharee} (conversation)" : "{sharee} (דיון)", "Please log in before granting %s access to your %s account." : "נא להיכנס בטרם מתן הרשאת %s לחשבון שלך ב־%s.", "Further information how to configure this can be found in the %sdocumentation%s." : "ניתן למצוא מידע נוסף כיצד להגדיר ב%sתיעוד%s." }, diff --git a/core/l10n/he.json b/core/l10n/he.json index 10a4653e898..649197398c3 100644 --- a/core/l10n/he.json +++ b/core/l10n/he.json @@ -196,12 +196,8 @@ "No users found for {search}" : "לא אותרו משתמשים עבור {search}", "An error occurred (\"{message}\"). Please try again" : "אירעה שגיאה (\"{message}\"). נא לנסות שוב", "An error occurred. Please try again" : "אירעה שגיאה. יש לנסות שנית", - "{sharee} (group)" : "{sharee} (קבוצה)", - "{sharee} (remote)" : "{sharee} (מרוחק)", "{sharee} (remote group)" : "{sharee} (קבוצה מרוחקת)", - "{sharee} (email)" : "{sharee} (דוא״ל)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (דיון)", "Share" : "שתף", "Name or email address..." : "שם או כתובת דוא״ל…", "Name or federated cloud ID..." : "שם או מזהה ענן מאוגד…", @@ -357,6 +353,9 @@ "Error setting expiration date" : "אירעה שגיאה בעת הגדרת תאריך התפוגה", "The public link will expire no later than {days} days after it is created" : "הקישור הציבורי יפוג עד {days} ימים לאחר שנוצר", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} שותף על ידי קישור", + "{sharee} (group)" : "{sharee} (קבוצה)", + "{sharee} (remote)" : "{sharee} (מרוחק)", + "{sharee} (email)" : "{sharee} (דוא״ל)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "ניתן לשתף אחרים על ידי הקלדת משתמש או קבוצה או מזהה ענן מאוגד או כתובת דוא״ל.", "Share with other people by entering a user or group or a federated cloud ID." : "ניתן לשתף אחרים על ידי הקלדת משתמש או קבוצה או מזהה ענן מאוגד.", "Share with other people by entering a user or group or an email address." : "ניתן לשתף עם אנשים אחרים על ידי הקלדת משתמש או קבוצה או כתובת דוא״ל.", @@ -387,6 +386,7 @@ "Back to log in" : "חזרה לכניסה", "You are about to grant %s access to your %s account." : "פעולה זו תעניק הרשאת %s לחשבון שלך ב־%s.", "Depending on your configuration, this button could also work to trust the domain:" : "בהתאם לתצורה שלך, הכפתור הזה יכול לעבוד גם כדי לתת אמון בשם המתחם:", + "{sharee} (conversation)" : "{sharee} (דיון)", "Please log in before granting %s access to your %s account." : "נא להיכנס בטרם מתן הרשאת %s לחשבון שלך ב־%s.", "Further information how to configure this can be found in the %sdocumentation%s." : "ניתן למצוא מידע נוסף כיצד להגדיר ב%sתיעוד%s." },"pluralForm" :"nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % 1 == 0) ? 1: (n % 10 == 0 && n % 1 == 0 && n > 10) ? 2 : 3;" diff --git a/core/l10n/hu.js b/core/l10n/hu.js index 6737eec4793..641f78aefb3 100644 --- a/core/l10n/hu.js +++ b/core/l10n/hu.js @@ -194,9 +194,6 @@ OC.L10N.register( "No users found for {search}" : "{search} keresésre nem található felhasználó", "An error occurred (\"{message}\"). Please try again" : "Hiba történt (\"{message}\"). Kérjük, próbálja meg újra! ", "An error occurred. Please try again" : "Hiba történt. Kérjük, próbálja meg újra!", - "{sharee} (group)" : "{sharee} (csoport)", - "{sharee} (remote)" : "{sharee} (távoli)", - "{sharee} (email)" : "{sharee} (e-mail)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Megosztás", "Name or email address..." : "Név vagy e-mail cím...", @@ -350,6 +347,9 @@ OC.L10N.register( "Error setting expiration date" : "Nem sikerült a lejárati időt beállítani", "The public link will expire no later than {days} days after it is created" : "A nyilvános hivatkozás érvényessége legkorábban {days} nappal a létrehozása után jár csak le", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} megosztva hivatkozással", + "{sharee} (group)" : "{sharee} (csoport)", + "{sharee} (remote)" : "{sharee} (távoli)", + "{sharee} (email)" : "{sharee} (e-mail)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Megosztás más emberekkel név vagy csoport, egy egységes felhőazonosító vagy e-mail cím megadásával.", "Share with other people by entering a user or group or a federated cloud ID." : "Megosztás más emberekkel felhasználó, csoport vagy egyesített felhőazonosító megadásával.", "Share with other people by entering a user or group or an email address." : "Megosztás más emberekkel név, csoport vagy e-mail cím megadásával.", diff --git a/core/l10n/hu.json b/core/l10n/hu.json index c4644231513..37152e84b68 100644 --- a/core/l10n/hu.json +++ b/core/l10n/hu.json @@ -192,9 +192,6 @@ "No users found for {search}" : "{search} keresésre nem található felhasználó", "An error occurred (\"{message}\"). Please try again" : "Hiba történt (\"{message}\"). Kérjük, próbálja meg újra! ", "An error occurred. Please try again" : "Hiba történt. Kérjük, próbálja meg újra!", - "{sharee} (group)" : "{sharee} (csoport)", - "{sharee} (remote)" : "{sharee} (távoli)", - "{sharee} (email)" : "{sharee} (e-mail)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Megosztás", "Name or email address..." : "Név vagy e-mail cím...", @@ -348,6 +345,9 @@ "Error setting expiration date" : "Nem sikerült a lejárati időt beállítani", "The public link will expire no later than {days} days after it is created" : "A nyilvános hivatkozás érvényessége legkorábban {days} nappal a létrehozása után jár csak le", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} megosztva hivatkozással", + "{sharee} (group)" : "{sharee} (csoport)", + "{sharee} (remote)" : "{sharee} (távoli)", + "{sharee} (email)" : "{sharee} (e-mail)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Megosztás más emberekkel név vagy csoport, egy egységes felhőazonosító vagy e-mail cím megadásával.", "Share with other people by entering a user or group or a federated cloud ID." : "Megosztás más emberekkel felhasználó, csoport vagy egyesített felhőazonosító megadásával.", "Share with other people by entering a user or group or an email address." : "Megosztás más emberekkel név, csoport vagy e-mail cím megadásával.", diff --git a/core/l10n/id.js b/core/l10n/id.js index 66ac2c6cc56..db6412940a0 100644 --- a/core/l10n/id.js +++ b/core/l10n/id.js @@ -119,9 +119,6 @@ OC.L10N.register( "No users or groups found for {search}" : "Tidak ada pengguna atau grup ditemukan untuk {search}", "No users found for {search}" : "Tidak ada pengguna ditemukan untuk {search}", "An error occurred. Please try again" : "Terjadi kesalahan. Silakan coba lagi", - "{sharee} (group)" : "{sharee} (grup)", - "{sharee} (remote)" : "{sharee} (remote)", - "{sharee} (email)" : "{sharee} (surel)", "Share" : "Bagikan", "Error" : "Kesalahan", "Error removing share" : "Terjadi kesalahan saat menghapus pembagian", @@ -222,6 +219,9 @@ OC.L10N.register( "Error setting expiration date" : "Kesalahan saat mengatur tanggal kedaluwarsa", "The public link will expire no later than {days} days after it is created" : "Tautan publik akan kadaluarsa tidak lebih dari {days} hari setelah ini dibuat", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} dibagikan lewat tautan", + "{sharee} (group)" : "{sharee} (grup)", + "{sharee} (remote)" : "{sharee} (remote)", + "{sharee} (email)" : "{sharee} (surel)", "The specified document has not been found on the server." : "Dokumen yang diminta tidak tersedia pada server.", "You can click here to return to %s." : "Anda dapat klik disini unutk kembali ke %s.", "Stay logged in" : "Tetap masuk", diff --git a/core/l10n/id.json b/core/l10n/id.json index 3fb08a344a2..8435a76b3fa 100644 --- a/core/l10n/id.json +++ b/core/l10n/id.json @@ -117,9 +117,6 @@ "No users or groups found for {search}" : "Tidak ada pengguna atau grup ditemukan untuk {search}", "No users found for {search}" : "Tidak ada pengguna ditemukan untuk {search}", "An error occurred. Please try again" : "Terjadi kesalahan. Silakan coba lagi", - "{sharee} (group)" : "{sharee} (grup)", - "{sharee} (remote)" : "{sharee} (remote)", - "{sharee} (email)" : "{sharee} (surel)", "Share" : "Bagikan", "Error" : "Kesalahan", "Error removing share" : "Terjadi kesalahan saat menghapus pembagian", @@ -220,6 +217,9 @@ "Error setting expiration date" : "Kesalahan saat mengatur tanggal kedaluwarsa", "The public link will expire no later than {days} days after it is created" : "Tautan publik akan kadaluarsa tidak lebih dari {days} hari setelah ini dibuat", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} dibagikan lewat tautan", + "{sharee} (group)" : "{sharee} (grup)", + "{sharee} (remote)" : "{sharee} (remote)", + "{sharee} (email)" : "{sharee} (surel)", "The specified document has not been found on the server." : "Dokumen yang diminta tidak tersedia pada server.", "You can click here to return to %s." : "Anda dapat klik disini unutk kembali ke %s.", "Stay logged in" : "Tetap masuk", diff --git a/core/l10n/is.js b/core/l10n/is.js index ee23b177fc0..0b0b26b723e 100644 --- a/core/l10n/is.js +++ b/core/l10n/is.js @@ -192,6 +192,7 @@ OC.L10N.register( "Can create" : "Getur búið til", "Can change" : "Getur skipt um", "Can delete" : "Getur eytt", + "Password protect by Talk" : "Verja með lykilorði í gegnum Talk", "Access control" : "Aðgangsstýring", "{shareInitiatorDisplayName} shared via link" : "{shareInitiatorDisplayName} deildi með tengli", "Could not unshare" : "Gat ekki hætt deilingu", @@ -203,12 +204,8 @@ OC.L10N.register( "No users found for {search}" : "Engir notendur fundust með {search}", "An error occurred (\"{message}\"). Please try again" : "Villa kom upp (\"{message}\"). Endilega reyndu aftur", "An error occurred. Please try again" : "Villa kom upp. Endilega reyndu aftur", - "{sharee} (group)" : "{sharee} (hópur)", - "{sharee} (remote)" : "{sharee} (fjartengdur)", "{sharee} (remote group)" : "{sharee} (fjartengdur hópur)", - "{sharee} (email)" : "{sharee} (tölvupóstur)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (samtal)", "Share" : "Deila", "Name or email address..." : "Nafn eða tölvupóstfang...", "Name or federated cloud ID..." : "Nafn eða skýjasambandsauðkenni (Federated Cloud ID)...", @@ -291,6 +288,7 @@ OC.L10N.register( "See the documentation" : "Sjá hjálparskjölin", "This application requires JavaScript for correct operation. Please {linkstart}enable JavaScript{linkend} and reload the page." : "Þetta forrit krefst JavaScript fyrir rétta virkni. {linkstart} virkjaðu JavaScript {linkend} og endurlestu síðan síðuna.", "Skip to main content" : "Sleppa og fara í meginefni", + "Skip to navigation of app" : "Hlaupa yfir í flakk innan forrits", "More apps" : "Fleiri forrit", "More apps menu" : "Valmynd með fleiri forrit", "Search" : "Leita", @@ -370,6 +368,9 @@ OC.L10N.register( "Error setting expiration date" : "Villa við að setja gildistíma", "The public link will expire no later than {days} days after it is created" : "Almenningstengillinn rennur út eigi síðar en {days} dögum eftir að hann er útbúinn", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} deildi með tengli", + "{sharee} (group)" : "{sharee} (hópur)", + "{sharee} (remote)" : "{sharee} (fjartengdur)", + "{sharee} (email)" : "{sharee} (tölvupóstur)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Deildu með öðru fólki með því að setja inn notanda, hóp, skýjasambandsauðkenni eða tölvupóstfang.", "Share with other people by entering a user or group or a federated cloud ID." : "Deildu með öðru fólki með því að setja inn notanda, hóp eða skýjasambandsauðkenni.", "Share with other people by entering a user or group or an email address." : "Deildu með öðru fólki með því að setja inn notanda, hóp eða tölvupóstfang.", @@ -401,6 +402,7 @@ OC.L10N.register( "You are about to grant %s access to your %s account." : "Þú ert að fara að leyfa %s aðgang að %s notandaaðgangnum þínum.", "Depending on your configuration, this button could also work to trust the domain:" : "Það fer eftir stillingunum þínum, þessi hnappur gæti einnig virkað til að treysta þessu léni.", "Copy URL" : "Afrita slóð", + "{sharee} (conversation)" : "{sharee} (samtal)", "Please log in before granting %s access to your %s account." : "Skráði þig inn áður en þú leyfir %s aðgang að %s notandaaðgangnum þínum.", "Further information how to configure this can be found in the %sdocumentation%s." : "Frekari upplýsingar um hvernig hægt er að stilla þetta má finna í %shjálparskjölunum%s." }, diff --git a/core/l10n/is.json b/core/l10n/is.json index bde6d1045ab..05092ee314c 100644 --- a/core/l10n/is.json +++ b/core/l10n/is.json @@ -190,6 +190,7 @@ "Can create" : "Getur búið til", "Can change" : "Getur skipt um", "Can delete" : "Getur eytt", + "Password protect by Talk" : "Verja með lykilorði í gegnum Talk", "Access control" : "Aðgangsstýring", "{shareInitiatorDisplayName} shared via link" : "{shareInitiatorDisplayName} deildi með tengli", "Could not unshare" : "Gat ekki hætt deilingu", @@ -201,12 +202,8 @@ "No users found for {search}" : "Engir notendur fundust með {search}", "An error occurred (\"{message}\"). Please try again" : "Villa kom upp (\"{message}\"). Endilega reyndu aftur", "An error occurred. Please try again" : "Villa kom upp. Endilega reyndu aftur", - "{sharee} (group)" : "{sharee} (hópur)", - "{sharee} (remote)" : "{sharee} (fjartengdur)", "{sharee} (remote group)" : "{sharee} (fjartengdur hópur)", - "{sharee} (email)" : "{sharee} (tölvupóstur)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (samtal)", "Share" : "Deila", "Name or email address..." : "Nafn eða tölvupóstfang...", "Name or federated cloud ID..." : "Nafn eða skýjasambandsauðkenni (Federated Cloud ID)...", @@ -289,6 +286,7 @@ "See the documentation" : "Sjá hjálparskjölin", "This application requires JavaScript for correct operation. Please {linkstart}enable JavaScript{linkend} and reload the page." : "Þetta forrit krefst JavaScript fyrir rétta virkni. {linkstart} virkjaðu JavaScript {linkend} og endurlestu síðan síðuna.", "Skip to main content" : "Sleppa og fara í meginefni", + "Skip to navigation of app" : "Hlaupa yfir í flakk innan forrits", "More apps" : "Fleiri forrit", "More apps menu" : "Valmynd með fleiri forrit", "Search" : "Leita", @@ -368,6 +366,9 @@ "Error setting expiration date" : "Villa við að setja gildistíma", "The public link will expire no later than {days} days after it is created" : "Almenningstengillinn rennur út eigi síðar en {days} dögum eftir að hann er útbúinn", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} deildi með tengli", + "{sharee} (group)" : "{sharee} (hópur)", + "{sharee} (remote)" : "{sharee} (fjartengdur)", + "{sharee} (email)" : "{sharee} (tölvupóstur)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Deildu með öðru fólki með því að setja inn notanda, hóp, skýjasambandsauðkenni eða tölvupóstfang.", "Share with other people by entering a user or group or a federated cloud ID." : "Deildu með öðru fólki með því að setja inn notanda, hóp eða skýjasambandsauðkenni.", "Share with other people by entering a user or group or an email address." : "Deildu með öðru fólki með því að setja inn notanda, hóp eða tölvupóstfang.", @@ -399,6 +400,7 @@ "You are about to grant %s access to your %s account." : "Þú ert að fara að leyfa %s aðgang að %s notandaaðgangnum þínum.", "Depending on your configuration, this button could also work to trust the domain:" : "Það fer eftir stillingunum þínum, þessi hnappur gæti einnig virkað til að treysta þessu léni.", "Copy URL" : "Afrita slóð", + "{sharee} (conversation)" : "{sharee} (samtal)", "Please log in before granting %s access to your %s account." : "Skráði þig inn áður en þú leyfir %s aðgang að %s notandaaðgangnum þínum.", "Further information how to configure this can be found in the %sdocumentation%s." : "Frekari upplýsingar um hvernig hægt er að stilla þetta má finna í %shjálparskjölunum%s." },"pluralForm" :"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);" diff --git a/core/l10n/it.js b/core/l10n/it.js index 28682cb778c..0c502a16885 100644 --- a/core/l10n/it.js +++ b/core/l10n/it.js @@ -167,6 +167,7 @@ OC.L10N.register( "Share to {name}" : "Condividi con {name}", "Copy link" : "Copia collegamento", "Link" : "Collegamento", + "Hide download" : "Nascondi scaricamento", "Password protect" : "Proteggi con password", "Allow editing" : "Consenti la modifica", "Email link to person" : "Invia collegamento via email", @@ -210,12 +211,10 @@ OC.L10N.register( "No users found for {search}" : "Nessun utente trovato per {search}", "An error occurred (\"{message}\"). Please try again" : "Si è verificato un errore (\"{message}\"). Prova ancora", "An error occurred. Please try again" : "Si è verificato un errore. Prova ancora", - "{sharee} (group)" : "{sharee} (group)", - "{sharee} (remote)" : "{sharee} (remote)", "{sharee} (remote group)" : "{sharee} (remote group)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (conversation)", + "Home" : "Home", + "Other" : "Altro", "Share" : "Condividi", "Name or email address..." : "Nome o indirizzo email...", "Name or federated cloud ID..." : "Nome o ID di cloud federata...", @@ -382,6 +381,9 @@ OC.L10N.register( "Error setting expiration date" : "Errore durante l'impostazione della data di scadenza", "The public link will expire no later than {days} days after it is created" : "Il collegamento pubblico scadrà non più tardi di {days} giorni dopo la sua creazione", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha condiviso tramite collegamento", + "{sharee} (group)" : "{sharee} (group)", + "{sharee} (remote)" : "{sharee} (remote)", + "{sharee} (email)" : "{sharee} (email)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Condividi con altre persone digitando un utente o un gruppo, un ID di cloud federata o un indirizzo di posta elettronica.", "Share with other people by entering a user or group or a federated cloud ID." : "Condividi con altre persone digitando un utente, un gruppo o un ID di cloud federata.", "Share with other people by entering a user or group or an email address." : "Condividi con altre persone digitando un utente, un gruppo o un indirizzo di posta elettronica.", @@ -413,6 +415,7 @@ OC.L10N.register( "You are about to grant %s access to your %s account." : "Stai per accordare a \"%s\" l'accesso al tuo account %s.", "Depending on your configuration, this button could also work to trust the domain:" : "In base alla tua configurazione, questo pulsante può funzionare anche per rendere attendibile il dominio:", "Copy URL" : "Copia URL", + "{sharee} (conversation)" : "{sharee} (conversation)", "Please log in before granting %s access to your %s account." : "Accedi prima di accordare a %s l'accesso al tuo account %s.", "Further information how to configure this can be found in the %sdocumentation%s." : "Ulteriori informazioni sulla configurazione sono disponibili nella %sdocumentazione%s." }, diff --git a/core/l10n/it.json b/core/l10n/it.json index 129e9471b69..e93e3137276 100644 --- a/core/l10n/it.json +++ b/core/l10n/it.json @@ -165,6 +165,7 @@ "Share to {name}" : "Condividi con {name}", "Copy link" : "Copia collegamento", "Link" : "Collegamento", + "Hide download" : "Nascondi scaricamento", "Password protect" : "Proteggi con password", "Allow editing" : "Consenti la modifica", "Email link to person" : "Invia collegamento via email", @@ -208,12 +209,10 @@ "No users found for {search}" : "Nessun utente trovato per {search}", "An error occurred (\"{message}\"). Please try again" : "Si è verificato un errore (\"{message}\"). Prova ancora", "An error occurred. Please try again" : "Si è verificato un errore. Prova ancora", - "{sharee} (group)" : "{sharee} (group)", - "{sharee} (remote)" : "{sharee} (remote)", "{sharee} (remote group)" : "{sharee} (remote group)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (conversation)", + "Home" : "Home", + "Other" : "Altro", "Share" : "Condividi", "Name or email address..." : "Nome o indirizzo email...", "Name or federated cloud ID..." : "Nome o ID di cloud federata...", @@ -380,6 +379,9 @@ "Error setting expiration date" : "Errore durante l'impostazione della data di scadenza", "The public link will expire no later than {days} days after it is created" : "Il collegamento pubblico scadrà non più tardi di {days} giorni dopo la sua creazione", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} ha condiviso tramite collegamento", + "{sharee} (group)" : "{sharee} (group)", + "{sharee} (remote)" : "{sharee} (remote)", + "{sharee} (email)" : "{sharee} (email)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Condividi con altre persone digitando un utente o un gruppo, un ID di cloud federata o un indirizzo di posta elettronica.", "Share with other people by entering a user or group or a federated cloud ID." : "Condividi con altre persone digitando un utente, un gruppo o un ID di cloud federata.", "Share with other people by entering a user or group or an email address." : "Condividi con altre persone digitando un utente, un gruppo o un indirizzo di posta elettronica.", @@ -411,6 +413,7 @@ "You are about to grant %s access to your %s account." : "Stai per accordare a \"%s\" l'accesso al tuo account %s.", "Depending on your configuration, this button could also work to trust the domain:" : "In base alla tua configurazione, questo pulsante può funzionare anche per rendere attendibile il dominio:", "Copy URL" : "Copia URL", + "{sharee} (conversation)" : "{sharee} (conversation)", "Please log in before granting %s access to your %s account." : "Accedi prima di accordare a %s l'accesso al tuo account %s.", "Further information how to configure this can be found in the %sdocumentation%s." : "Ulteriori informazioni sulla configurazione sono disponibili nella %sdocumentazione%s." },"pluralForm" :"nplurals=2; plural=(n != 1);" diff --git a/core/l10n/ja.js b/core/l10n/ja.js index c3eb3db054e..668748296d8 100644 --- a/core/l10n/ja.js +++ b/core/l10n/ja.js @@ -155,9 +155,6 @@ OC.L10N.register( "No users or groups found for {search}" : "{search} の検索でユーザー、グループが見つかりません", "No users found for {search}" : "{search} のユーザーはいませんでした", "An error occurred. Please try again" : "エラーが発生しました。もう一度実行してください。", - "{sharee} (group)" : "{sharee} (グループ)", - "{sharee} (remote)" : "{sharee} (リモート)", - "{sharee} (email)" : "{sharee} (メール)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "共有", "Name or email address..." : "名前またはメールアドレス", @@ -281,6 +278,9 @@ OC.L10N.register( "Error setting expiration date" : "有効期限の設定でエラー発生", "The public link will expire no later than {days} days after it is created" : "URLによる共有は、作成してから {days} 日以内に有効期限切れになります", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} がリンク経由で共有", + "{sharee} (group)" : "{sharee} (グループ)", + "{sharee} (remote)" : "{sharee} (リモート)", + "{sharee} (email)" : "{sharee} (メール)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "ユーザー名、グループ、クラウド統合ID、メールアドレスで共有", "Share with other people by entering a user or group or a federated cloud ID." : "ユーザー名、グループ、クラウド統合IDで共有", "Share with other people by entering a user or group or an email address." : "ユーザー名やグループ名、メールアドレスで共有", diff --git a/core/l10n/ja.json b/core/l10n/ja.json index 1a290bfc641..b0819cbfc32 100644 --- a/core/l10n/ja.json +++ b/core/l10n/ja.json @@ -153,9 +153,6 @@ "No users or groups found for {search}" : "{search} の検索でユーザー、グループが見つかりません", "No users found for {search}" : "{search} のユーザーはいませんでした", "An error occurred. Please try again" : "エラーが発生しました。もう一度実行してください。", - "{sharee} (group)" : "{sharee} (グループ)", - "{sharee} (remote)" : "{sharee} (リモート)", - "{sharee} (email)" : "{sharee} (メール)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "共有", "Name or email address..." : "名前またはメールアドレス", @@ -279,6 +276,9 @@ "Error setting expiration date" : "有効期限の設定でエラー発生", "The public link will expire no later than {days} days after it is created" : "URLによる共有は、作成してから {days} 日以内に有効期限切れになります", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} がリンク経由で共有", + "{sharee} (group)" : "{sharee} (グループ)", + "{sharee} (remote)" : "{sharee} (リモート)", + "{sharee} (email)" : "{sharee} (メール)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "ユーザー名、グループ、クラウド統合ID、メールアドレスで共有", "Share with other people by entering a user or group or a federated cloud ID." : "ユーザー名、グループ、クラウド統合IDで共有", "Share with other people by entering a user or group or an email address." : "ユーザー名やグループ名、メールアドレスで共有", diff --git a/core/l10n/ka_GE.js b/core/l10n/ka_GE.js index c1b5a9c3029..8b5b8a9ed69 100644 --- a/core/l10n/ka_GE.js +++ b/core/l10n/ka_GE.js @@ -169,9 +169,6 @@ OC.L10N.register( "No users or groups found for {search}" : "მომხმარებლები და ჯგუფები {search}-ისთვის არ იქნა ნაპოვნი", "No users found for {search}" : "მომხმარებლები {search}-ისთვის არ იქნა ნაპოვნი", "An error occurred. Please try again" : "წარმოიშვა შეცდომა. გთხოვთ სცადოთ ახლიდან.", - "{sharee} (group)" : "{sharee} (ჯგუფი)", - "{sharee} (remote)" : "{sharee} (დისტანციური)", - "{sharee} (email)" : "{sharee} (ელ-ფოსტა)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "გაზიარება", "Name or email address..." : "სახელი ან ელ-ფოსტის მისამართი...", @@ -315,6 +312,9 @@ OC.L10N.register( "Error setting expiration date" : "ვადის გასვლის მითითებისას წარმოიშვა შეცდომა", "The public link will expire no later than {days} days after it is created" : "საზოგადო ბმული გაუქმედება შექმნის მომენტიდან {days} დღის შემდეგ", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} მომხმარებელმა გააზიარა ბმულით", + "{sharee} (group)" : "{sharee} (ჯგუფი)", + "{sharee} (remote)" : "{sharee} (დისტანციური)", + "{sharee} (email)" : "{sharee} (ელ-ფოსტა)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "გაუზიარეთ სხვა ადამიანებს მოხმარებლის, ჯგუფის, ფედერალური ქლაუდ ID-ის ან ელ-ფოსტის მისამართის შეყვანით.", "Share with other people by entering a user or group or a federated cloud ID." : "გაუზიარეთ სხვა ადამიანებს, მომხმარებლის, ჯგუფის ან ფედერალური ქლაუდ ID-ის შეყვანით.", "Share with other people by entering a user or group or an email address." : "გაუზიარეთ სხვა ადამიანებს მომხმარებლის, ჯგუფის ან ელ-ფოსტის მისამართის შეყვანით.", diff --git a/core/l10n/ka_GE.json b/core/l10n/ka_GE.json index f85e63cf772..2e2dff3d7b4 100644 --- a/core/l10n/ka_GE.json +++ b/core/l10n/ka_GE.json @@ -167,9 +167,6 @@ "No users or groups found for {search}" : "მომხმარებლები და ჯგუფები {search}-ისთვის არ იქნა ნაპოვნი", "No users found for {search}" : "მომხმარებლები {search}-ისთვის არ იქნა ნაპოვნი", "An error occurred. Please try again" : "წარმოიშვა შეცდომა. გთხოვთ სცადოთ ახლიდან.", - "{sharee} (group)" : "{sharee} (ჯგუფი)", - "{sharee} (remote)" : "{sharee} (დისტანციური)", - "{sharee} (email)" : "{sharee} (ელ-ფოსტა)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "გაზიარება", "Name or email address..." : "სახელი ან ელ-ფოსტის მისამართი...", @@ -313,6 +310,9 @@ "Error setting expiration date" : "ვადის გასვლის მითითებისას წარმოიშვა შეცდომა", "The public link will expire no later than {days} days after it is created" : "საზოგადო ბმული გაუქმედება შექმნის მომენტიდან {days} დღის შემდეგ", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} მომხმარებელმა გააზიარა ბმულით", + "{sharee} (group)" : "{sharee} (ჯგუფი)", + "{sharee} (remote)" : "{sharee} (დისტანციური)", + "{sharee} (email)" : "{sharee} (ელ-ფოსტა)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "გაუზიარეთ სხვა ადამიანებს მოხმარებლის, ჯგუფის, ფედერალური ქლაუდ ID-ის ან ელ-ფოსტის მისამართის შეყვანით.", "Share with other people by entering a user or group or a federated cloud ID." : "გაუზიარეთ სხვა ადამიანებს, მომხმარებლის, ჯგუფის ან ფედერალური ქლაუდ ID-ის შეყვანით.", "Share with other people by entering a user or group or an email address." : "გაუზიარეთ სხვა ადამიანებს მომხმარებლის, ჯგუფის ან ელ-ფოსტის მისამართის შეყვანით.", diff --git a/core/l10n/ko.js b/core/l10n/ko.js index 3fb9985a83f..be933a3af47 100644 --- a/core/l10n/ko.js +++ b/core/l10n/ko.js @@ -185,9 +185,6 @@ OC.L10N.register( "No users or groups found for {search}" : "{search} 사용자나 그룹을 찾을 수 없음", "No users found for {search}" : "{search} 사용자를 찾을 수 없음", "An error occurred. Please try again" : "오류가 발생했습니다. 다시 시도하십시오.", - "{sharee} (group)" : "{sharee}(그룹)", - "{sharee} (remote)" : "{sharee}(원격)", - "{sharee} (email)" : "{sharee}(이메일)", "{sharee} ({type}, {owner})" : "{sharee}({type}, {owner})", "Share" : "공유", "Name or email address..." : "이름이나 이메일 주소...", @@ -331,6 +328,9 @@ OC.L10N.register( "Error setting expiration date" : "만료 날짜 설정 오류", "The public link will expire no later than {days} days after it is created" : "공개 링크를 만든 후 최대 {days}일까지 유지됩니다", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} 님이 링크를 통해 공유", + "{sharee} (group)" : "{sharee}(그룹)", + "{sharee} (remote)" : "{sharee}(원격)", + "{sharee} (email)" : "{sharee}(이메일)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "사용자나 그룹 이름, 연합 클라우드 ID 및 이메일 주소를 입력해서 다른 사람과 공유하십시오.", "Share with other people by entering a user or group or a federated cloud ID." : "사용자나 그룹 이름, 연합 클라우드 ID를 입력해서 다른 사람과 공유하십시오.", "Share with other people by entering a user or group or an email address." : "사용자나 그룹 이름 및 이메일 주소를 입력해서 다른 사람과 공유하십시오.", diff --git a/core/l10n/ko.json b/core/l10n/ko.json index 4168d836fff..abf54238118 100644 --- a/core/l10n/ko.json +++ b/core/l10n/ko.json @@ -183,9 +183,6 @@ "No users or groups found for {search}" : "{search} 사용자나 그룹을 찾을 수 없음", "No users found for {search}" : "{search} 사용자를 찾을 수 없음", "An error occurred. Please try again" : "오류가 발생했습니다. 다시 시도하십시오.", - "{sharee} (group)" : "{sharee}(그룹)", - "{sharee} (remote)" : "{sharee}(원격)", - "{sharee} (email)" : "{sharee}(이메일)", "{sharee} ({type}, {owner})" : "{sharee}({type}, {owner})", "Share" : "공유", "Name or email address..." : "이름이나 이메일 주소...", @@ -329,6 +326,9 @@ "Error setting expiration date" : "만료 날짜 설정 오류", "The public link will expire no later than {days} days after it is created" : "공개 링크를 만든 후 최대 {days}일까지 유지됩니다", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} 님이 링크를 통해 공유", + "{sharee} (group)" : "{sharee}(그룹)", + "{sharee} (remote)" : "{sharee}(원격)", + "{sharee} (email)" : "{sharee}(이메일)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "사용자나 그룹 이름, 연합 클라우드 ID 및 이메일 주소를 입력해서 다른 사람과 공유하십시오.", "Share with other people by entering a user or group or a federated cloud ID." : "사용자나 그룹 이름, 연합 클라우드 ID를 입력해서 다른 사람과 공유하십시오.", "Share with other people by entering a user or group or an email address." : "사용자나 그룹 이름 및 이메일 주소를 입력해서 다른 사람과 공유하십시오.", diff --git a/core/l10n/lt_LT.js b/core/l10n/lt_LT.js index b189c271038..cce116db616 100644 --- a/core/l10n/lt_LT.js +++ b/core/l10n/lt_LT.js @@ -156,9 +156,6 @@ OC.L10N.register( "No users or groups found for {search}" : "Nerasta vartotojų ar grupių pagal paieškos kriterijų: {search}", "No users found for {search}" : "Nerasta vartotojų pagal paieškos kriterijų: {search}", "An error occurred. Please try again" : "Įvyko klaida. Bandykite dar kartą", - "{sharee} (group)" : "{sharee} (grupė)", - "{sharee} (remote)" : "{sharee} (nuotolinis)", - "{sharee} (email)" : "{sharee} (elektroninis paštas)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Dalintis", "Name or email address..." : "Vardas arba elektroninio pašto adresas...", @@ -283,6 +280,9 @@ OC.L10N.register( "Error setting expiration date" : "Klaida nustatant dalinimosi pabaigos laiką", "The public link will expire no later than {days} days after it is created" : "Nuoroda veiks ne mažiau kaip {days} dienas nuo sukūrimo", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} pasidalino per nuorodą", + "{sharee} (group)" : "{sharee} (grupė)", + "{sharee} (remote)" : "{sharee} (nuotolinis)", + "{sharee} (email)" : "{sharee} (elektroninis paštas)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Pasidalinti su kitais asmenimis galima įvedus vartotojo ar grupės vardą, NextCloud tinklo kompiuterio ID arba elektroninio pašto adresą.", "Share with other people by entering a user or group or a federated cloud ID." : "Pasidalinti su kitais asmenimis galima įvedus vartotojo ar grupės vardą arba NextCloud tinklo kompiuterio ID.", "Share with other people by entering a user or group or an email address." : "Pasidalinti su kitais asmenimis galima įvedus vartotojo ar grupės vardą arba elektroninio pašto adresą.", diff --git a/core/l10n/lt_LT.json b/core/l10n/lt_LT.json index 6206e0193c3..8ab546d29e5 100644 --- a/core/l10n/lt_LT.json +++ b/core/l10n/lt_LT.json @@ -154,9 +154,6 @@ "No users or groups found for {search}" : "Nerasta vartotojų ar grupių pagal paieškos kriterijų: {search}", "No users found for {search}" : "Nerasta vartotojų pagal paieškos kriterijų: {search}", "An error occurred. Please try again" : "Įvyko klaida. Bandykite dar kartą", - "{sharee} (group)" : "{sharee} (grupė)", - "{sharee} (remote)" : "{sharee} (nuotolinis)", - "{sharee} (email)" : "{sharee} (elektroninis paštas)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Dalintis", "Name or email address..." : "Vardas arba elektroninio pašto adresas...", @@ -281,6 +278,9 @@ "Error setting expiration date" : "Klaida nustatant dalinimosi pabaigos laiką", "The public link will expire no later than {days} days after it is created" : "Nuoroda veiks ne mažiau kaip {days} dienas nuo sukūrimo", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} pasidalino per nuorodą", + "{sharee} (group)" : "{sharee} (grupė)", + "{sharee} (remote)" : "{sharee} (nuotolinis)", + "{sharee} (email)" : "{sharee} (elektroninis paštas)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Pasidalinti su kitais asmenimis galima įvedus vartotojo ar grupės vardą, NextCloud tinklo kompiuterio ID arba elektroninio pašto adresą.", "Share with other people by entering a user or group or a federated cloud ID." : "Pasidalinti su kitais asmenimis galima įvedus vartotojo ar grupės vardą arba NextCloud tinklo kompiuterio ID.", "Share with other people by entering a user or group or an email address." : "Pasidalinti su kitais asmenimis galima įvedus vartotojo ar grupės vardą arba elektroninio pašto adresą.", diff --git a/core/l10n/lv.js b/core/l10n/lv.js index 48e1297cc01..ea8322bea5e 100644 --- a/core/l10n/lv.js +++ b/core/l10n/lv.js @@ -171,9 +171,6 @@ OC.L10N.register( "No users or groups found for {search}" : "Pēc {search} netika atrasts neviens lietotājs vai grupa", "No users found for {search}" : "Pēc {search} netika atrasts neviens lietotājs", "An error occurred. Please try again" : "Notika kļūda. Mēģini vēlreiz.", - "{sharee} (group)" : "{sharee} (grupa)", - "{sharee} (remote)" : "{sharee} (attālināti)", - "{sharee} (email)" : "{sharee} (e-pasts)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Koplietot", "Name or email address..." : "Vārds vai e-pasta adrese...", @@ -297,6 +294,9 @@ OC.L10N.register( "Error setting expiration date" : "Kļūda, iestatot termiņa datumu", "The public link will expire no later than {days} days after it is created" : "Šis links beigs strādāt pēc ne vēlāk kā {days} dienām pēc tam kad tas tiks izveidots", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} koplietots ar saiti", + "{sharee} (group)" : "{sharee} (grupa)", + "{sharee} (remote)" : "{sharee} (attālināti)", + "{sharee} (email)" : "{sharee} (e-pasts)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Dalīties ar citiem cilvēkiem ievadot lietotāju, grupu, federated cloud ID vai e-pasta adresi.", "Share with other people by entering a user or group or a federated cloud ID." : "Dalīties ar citiem cilvēkiem ievadot lietotāju, grupu vai federated cloud ID.", "Share with other people by entering a user or group or an email address." : "Dalīties ar citiem cilvēkiem ievadot lietotāju, grupu vai e-pasta adresi.", diff --git a/core/l10n/lv.json b/core/l10n/lv.json index 7745e88c50a..397a6c93c6e 100644 --- a/core/l10n/lv.json +++ b/core/l10n/lv.json @@ -169,9 +169,6 @@ "No users or groups found for {search}" : "Pēc {search} netika atrasts neviens lietotājs vai grupa", "No users found for {search}" : "Pēc {search} netika atrasts neviens lietotājs", "An error occurred. Please try again" : "Notika kļūda. Mēģini vēlreiz.", - "{sharee} (group)" : "{sharee} (grupa)", - "{sharee} (remote)" : "{sharee} (attālināti)", - "{sharee} (email)" : "{sharee} (e-pasts)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Koplietot", "Name or email address..." : "Vārds vai e-pasta adrese...", @@ -295,6 +292,9 @@ "Error setting expiration date" : "Kļūda, iestatot termiņa datumu", "The public link will expire no later than {days} days after it is created" : "Šis links beigs strādāt pēc ne vēlāk kā {days} dienām pēc tam kad tas tiks izveidots", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} koplietots ar saiti", + "{sharee} (group)" : "{sharee} (grupa)", + "{sharee} (remote)" : "{sharee} (attālināti)", + "{sharee} (email)" : "{sharee} (e-pasts)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Dalīties ar citiem cilvēkiem ievadot lietotāju, grupu, federated cloud ID vai e-pasta adresi.", "Share with other people by entering a user or group or a federated cloud ID." : "Dalīties ar citiem cilvēkiem ievadot lietotāju, grupu vai federated cloud ID.", "Share with other people by entering a user or group or an email address." : "Dalīties ar citiem cilvēkiem ievadot lietotāju, grupu vai e-pasta adresi.", diff --git a/core/l10n/nb.js b/core/l10n/nb.js index ee1bbf7e246..05659963e02 100644 --- a/core/l10n/nb.js +++ b/core/l10n/nb.js @@ -46,6 +46,7 @@ OC.L10N.register( "Checked for update of app \"%s\" in appstore" : "Så etter oppdateringer for programmet \"%s\" i program-butikk", "Checking whether the database schema for %s can be updated (this can take a long time depending on the database size)" : "Sjekker om databaseskjemaet for %s kan oppdateres (dette kan ta lang tid hvis databasen er stor)", "Checked database schema update for apps" : "Sjekket databaseskjema-oppdatering for programmer", + "Updated \"%1$s\" to %2$s" : "Oppdaterte \"%1$s\" til %2$s", "Set log level to debug" : "Sett loggnivå for feilsøking", "Reset log level" : "Standard loggnivå", "Starting code integrity check" : "Starter sjekk av kode-integritet", @@ -127,6 +128,7 @@ OC.L10N.register( "Check the background job settings" : "Kontroller instillinger for bakgrunnsjobb", "This server has no working Internet connection: Multiple endpoints could not be reached. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. Establish a connection from this server to the Internet to enjoy all features." : "Denne tjeneren har ingen fungerende internett-forbindelse. Dette betyr at noen funksjoner, som tilknytning av eksterne lagre, varslinger om oppdateringer eller installering av tredjepartsprogrammer ikke vil virke. Fjerntilgang til filer og utsending av varsler på e-post vil kanskje ikke virke heller. Det anbefales å aktivere en internett-forbindelse for denne tjeneren hvis du vil ha full funksjonalitet.", "No memory cache has been configured. To enhance performance, please configure a memcache, if available. Further information can be found in the <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">documentation</a>." : "Hurtigminne er ikke satt opp. For bedre ytelse bør du sette opp hurtigminne hvis det er tilgjengelig. Mer informasjon finnes i <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">dokumentasjonen</a>.", + "No suitable source for randomness found by PHP which is highly discouraged for security reasons. Further information can be found in the <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">documentation</a>." : "Ingen egnet kilde til tilfeldighet funnet av PHP som er svært motløst av sikkerhetshensyn. Mer informasjon finnes i <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">dokumentasjon</a>.", "You are currently running PHP {version}. Upgrade your PHP version to take advantage of <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{phpLink}\">performance and security updates provided by the PHP Group</a> as soon as your distribution supports it." : "Du bruker PHP-{version}. Oppgrader PHP-versjonen for å utnytte <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{phpLink}\">ytelsen og sikkerhetsoppdateringene som tilbys av PHP Group</a, så fort din distribusjon støtter det.", "You are currently running PHP 5.6. The current major version of Nextcloud is the last that is supported on PHP 5.6. It is recommended to upgrade the PHP version to 7.0+ to be able to upgrade to Nextcloud 14." : "Du kjører nå PHP 5.6. Den nåværende hovedversjonen er den siste som støtter PHP 5.6. Det anbefales å oppgradere PHP-versjonen til 7.0+, for å kunne oppgradere til Nextcloud 14.", "The reverse proxy header configuration is incorrect, or you are accessing Nextcloud from a trusted proxy. If not, this is a security issue and can allow an attacker to spoof their IP address as visible to the Nextcloud. Further information can be found in the <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">documentation</a>." : "Det omvendte mellomtjener-hodet er ikke satt opp rett, eller du kobler til Nextcloud fra en betrodd mellomtjener. Hvis ikke, er dette et sikkerhetsproblem, og kan tillate en angriper å forfalske deres IP-adresse slik den er synlig for Nextcloud. Ytterligere informasjon er å finne i <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">dokumentasjonen</a>.", @@ -148,6 +150,8 @@ OC.L10N.register( "Your data directory and files are probably accessible from the Internet. The .htaccess file is not working. It is strongly recommended that you configure your web server so that the data directory is no longer accessible, or move the data directory outside the web server document root." : "Datamappen og filene dine er sannsynligvis tilgjengelige fra Internett. .htaccess-filen fungerer ikke. Det anbefales sterkt at du setter opp vev-tjeneren slik at datamappen ikke kan nås eller at du flytter datamappen ut av vev-tjenerens dokumentrot.", "The \"{header}\" HTTP header is not set to \"{expected}\". This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly." : "HTTP-hodet \"{header}\" er ikke satt opp likt \"{expected}\". Dette kan være en sikkerhet- eller personvernsrisiko og det anbefales at denne innstillingen endres.", "The \"{header}\" HTTP header is not set to \"{expected}\". Some features might not work correctly, as it is recommended to adjust this setting accordingly." : "HTTP-hodet \"{header}\" er ikke satt opp til å være likt \"{expected}\". Det kan hende noen funksjoner ikke fungerer rett, og det anbefales å justere denne innstillingen henholdsvis.", + "The \"{header}\" HTTP header doesn't contain \"{expected}\". This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly." : "\"{header}\" HTTP hode mangler \"{expected}\". Dette er en sikkerhetsrisiko eller personverntrussel. Det er anbefalt å korrigere oppsett.", + "The \"{header}\" HTTP header is not set to \"{val1}\", \"{val2}\", \"{val3}\", \"{val4}\" or \"{val5}\". This can leak referer information. See the <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{link}\">W3C Recommendation ↗</a>." : "\"{header}\" HTTP hode er satt til \"{val1}\", \"{val2}\", \"{val3}\", \"{val4}\" eller \"{val5}\". Dette kan gi lekasje i henvisningsinformasjon. Se <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{link}\">W3C anbefalinger ↗</a>.", "The \"Strict-Transport-Security\" HTTP header is not set to at least \"{seconds}\" seconds. For enhanced security, it is recommended to enable HSTS as described in the <a href=\"{docUrl}\" rel=\"noreferrer noopener\">security tips ↗</a>." : "HTTP-overskriften \"Strict-Transport-Security\" er ikke satt til minst \"{sekunder}\" sekunder. For forbedret sikkerhet anbefales det å aktivere HSTS som beskrevet i <a href=\"{docUrl}\" rel=\"noreferrer noopener\">tips for bedre sikkerhet ↗</a>.", "Accessing site insecurely via HTTP. You are strongly adviced to set up your server to require HTTPS instead, as described in the <a href=\"{docUrl}\">security tips ↗</a>." : "Få tilgang til nettstedet usikkert via HTTP. Du er sterkt anbefalt å sette opp serveren din for å kreve HTTPS i stedet, som beskrevet i<a href=\"{docUrl}\">tips for bedre sikkerhet ↗</a>.", "Shared" : "Delt", @@ -161,6 +165,7 @@ OC.L10N.register( "Press Ctrl-C to copy." : "Trykk Ctrl-C for å kopiere", "Resharing is not allowed" : "Videre deling er ikke tillatt", "Share to {name}" : "Dele med {name}", + "Copy link" : "Kopier lenke", "Link" : "Lenke", "Password protect" : "Passordbeskyttet", "Allow editing" : "Tillat redigering", @@ -178,6 +183,7 @@ OC.L10N.register( "Shared with you and the group {group} by {owner}" : "Delt med deg og gruppen {group} av {owner}", "Shared with you and {circle} by {owner}" : "Delt med deg og {circle} av {owner}", "Shared with you and the conversation {conversation} by {owner}" : "Delt med deg og samtalen {conversation} av {owner}", + "Shared with you in a conversation by {owner}" : "Delt md deg i samtale med {owner}", "Shared with you by {owner}" : "Delt med deg av {owner}", "Choose a password for the mail share" : "Velg et passord for e-postlageret", "group" : "gruppe", @@ -194,6 +200,7 @@ OC.L10N.register( "Can delete" : "Kan slette", "Password protect by Talk" : "Passord beskyttet av Talk", "Access control" : "Tilgangskontroll", + "{shareInitiatorDisplayName} shared via link" : "{shareInitiatorDisplayName} delt via lenke", "Could not unshare" : "Kunne ikke avslutte deling", "Error while sharing" : "Feil under deling", "Share details could not be loaded for this item." : "Klarte ikke å laste inn detaljer om deling for dette elementet.", @@ -203,12 +210,8 @@ OC.L10N.register( "No users found for {search}" : "Ingen brukere funnet for {search}", "An error occurred (\"{message}\"). Please try again" : "En feil inntraff (\"{message}\"). Prøv igjen", "An error occurred. Please try again" : "Det oppstod en feil. Prøv igjen", - "{sharee} (group)" : "{sharee} (gruppe)", - "{sharee} (remote)" : "{sharee} (ekstern)", "{sharee} (remote group)" : "{sharee} (remote group)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (conversation)", "Share" : "Del", "Name or email address..." : "Navn eller e-postadresse…", "Name or federated cloud ID..." : "Navn eller sammenknyttet sky-ID…", @@ -250,6 +253,8 @@ OC.L10N.register( "Help" : "Hjelp", "Access forbidden" : "Tilgang nektet", "File not found" : "Finner ikke filen", + "The document could not be found on the server. Maybe the share was deleted or has expired?" : "Dokumentasjon kan ikke finnes på server. Er deling slettet eller utløpt?", + "Back to %s" : "Tilbake til %s", "Internal Server Error" : "Intern tjenerfeil.", "The server was unable to complete your request." : "Tjeneren kunne ikke fullføre din forespørsel.", "If this happens again, please send the technical details below to the server administrator." : "Hvis dette skjer igjen, send de tekniske detaljene nedenfor til tjeneradministratoren.", @@ -311,23 +316,30 @@ OC.L10N.register( "Forgot password?" : "Glemt passord?", "Back to login" : "Tilbake til innlogging", "Connect to your account" : "Koble til kontoen din", + "Please log in before granting %1$s access to your %2$s account." : "Logg inn før du tildeler %1$stilgang til din %2$skonto.", "App token" : "Program-symbol", "Grant access" : "Gi tilgang", "Alternative log in using app token" : "Alternativ logg inn ved hjelp av program kode", "Account access" : "Kontotilgang", + "You are about to grant %1$s access to your %2$s account." : "Du er i ferd med å tildele %1$s tilgang til din %2$skonto.", "Redirecting …" : "Videresender…", "New password" : "Nytt passord", "New Password" : "Nytt passord", "This share is password-protected" : "Denne deling er beskyttet med passord", "The password is wrong. Try again." : "Feil passord, forsøk igjen", "Two-factor authentication" : "Tofaktor autentisering", + "Enhanced security is enabled for your account. Choose a second factor for authentication:" : "Utvidet sikkerhet er tilgjengelig fo rdin konto. Velg en to-faktor for autentisering.", "Could not load at least one of your enabled two-factor auth methods. Please contact your admin." : "Kunne ikke laste minst en av de aktiverte tofaktor metodene. Ta kontakt med administrasjonen din.", + "Two-factor authentication is enforced but has not been configured on your account. Contact your admin for assistance." : "To-faktor autentisering er aktivert men er ikke satt opp for din konto. Kontakt administrator for hjelp.", + "Two-factor authentication is enforced but has not been configured on your account. Use one of your backup codes to log in or contact your admin for assistance." : "To-faktor autentisering er aktivert men er ikke satt opp for din konto. Bruk en av dine sikkerhet koder for å logge inn eller kontakt administrator for hjelp.", "Use backup code" : "Bruker sikkerhetskopi kode", "Cancel log in" : "Avbryt innlogging", "Error while validating your second factor" : "Feil under validering av din andre faktor", "Access through untrusted domain" : "Nå gjennom ubetrodd domene", "Please contact your administrator. If you are an administrator, edit the \"trusted_domains\" setting in config/config.php like the example in config.sample.php." : "Kontakt din administrator. Hvis du er en administrator, sett opp innstillingen \"trusted_domains\" i config/config.php som eksemplet i config/config.sample.php.", + "Further information how to configure this can be found in the %1$sdocumentation%2$s." : "Ytterligere informasojn om oppsett finnes i %1$sdokumentasjon%2$s.", "App update required" : "Program-oppdatering kreves", + "%1$s will be updated to version %2$s" : "%1$soppdateres til versjon %2$s", "These apps will be updated:" : "Disse programmene vil bli oppdatert:", "These incompatible apps will be disabled:" : "Disse ikke-kompatible programmene vil bli deaktivert:", "The theme %s has been disabled." : "Drakten %s har blitt deaktivert.", @@ -340,7 +352,9 @@ OC.L10N.register( "For help, see the <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"%s\">documentation</a>." : "For hjelp, les <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"%s\">dokumentasjonen</a>.", "I know that if I continue doing the update via web UI has the risk, that the request runs into a timeout and could cause data loss, but I have a backup and know how to restore my instance in case of a failure." : "Jeg vet at hvis jeg fortsetter oppdateringen via vev-grensesnittet er det en mulighet for datatap som følge av tidsavbrudd, men jeg har en sikkerhetskopi og vet hvordan jeg skal gjenopprette min installasjon hvis den feiler.", "Upgrade via web on my own risk" : "Oppgrader via vev på min egen risikio", + "Maintenance mode" : "Modus for vedlikehold", "This %s instance is currently in maintenance mode, which may take a while." : "Denne %s-instansen er for øyeblikket i vedlikeholdsmodus, noe som kan vare en stund.", + "This page will refresh itself when the instance is available again." : "Siden vil oppdatere seg selv når instans er tilgjengelig igjen.", "Contact your system administrator if this message persists or appeared unexpectedly." : "Kontakt systemadministratoren hvis denne meldingen var uventet eller ikke forsvinner.", "Updated \"%s\" to %s" : "Oppdaterte \"%s\" til %s", "%s (3rdparty)" : "%s (tredjepart)", @@ -364,6 +378,9 @@ OC.L10N.register( "Error setting expiration date" : "Kan ikke sette utløpsdato", "The public link will expire no later than {days} days after it is created" : "Den offentlige lenken vil utløpe senest {days} dager etter at den lages", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} delt via lenke", + "{sharee} (group)" : "{sharee} (gruppe)", + "{sharee} (remote)" : "{sharee} (ekstern)", + "{sharee} (email)" : "{sharee} (email)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Del med andre ved å skrive inn en bruker, en gruppe, en sammenknyttet sky-ID eller en e-postadresse.", "Share with other people by entering a user or group or a federated cloud ID." : "Del med andre ved å skrive inn en bruker, en gruppe eller en sammenknyttet sky-ID", "Share with other people by entering a user or group or an email address." : "Del med andre ved å skrive inn en bruker, en gruppe, eller en e-postadresse.", @@ -394,6 +411,8 @@ OC.L10N.register( "Back to log in" : "Tilbake til innlogging", "You are about to grant %s access to your %s account." : "Du er i ferd med å gi %s tilgang til din %s konto.", "Depending on your configuration, this button could also work to trust the domain:" : "Avhengig av ditt oppsett, kan denne knappen også betro domenet.", + "Copy URL" : "Kopier URL", + "{sharee} (conversation)" : "{sharee} (conversation)", "Please log in before granting %s access to your %s account." : "Logg inn før du innvilger %s tilgang til din %s konto.", "Further information how to configure this can be found in the %sdocumentation%s." : "Ytterligere informasjon om hvordan du konfigurerer dette kan du finne i %sdokumentasjon%s." }, diff --git a/core/l10n/nb.json b/core/l10n/nb.json index af40462431d..75981eb1d71 100644 --- a/core/l10n/nb.json +++ b/core/l10n/nb.json @@ -44,6 +44,7 @@ "Checked for update of app \"%s\" in appstore" : "Så etter oppdateringer for programmet \"%s\" i program-butikk", "Checking whether the database schema for %s can be updated (this can take a long time depending on the database size)" : "Sjekker om databaseskjemaet for %s kan oppdateres (dette kan ta lang tid hvis databasen er stor)", "Checked database schema update for apps" : "Sjekket databaseskjema-oppdatering for programmer", + "Updated \"%1$s\" to %2$s" : "Oppdaterte \"%1$s\" til %2$s", "Set log level to debug" : "Sett loggnivå for feilsøking", "Reset log level" : "Standard loggnivå", "Starting code integrity check" : "Starter sjekk av kode-integritet", @@ -125,6 +126,7 @@ "Check the background job settings" : "Kontroller instillinger for bakgrunnsjobb", "This server has no working Internet connection: Multiple endpoints could not be reached. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. Establish a connection from this server to the Internet to enjoy all features." : "Denne tjeneren har ingen fungerende internett-forbindelse. Dette betyr at noen funksjoner, som tilknytning av eksterne lagre, varslinger om oppdateringer eller installering av tredjepartsprogrammer ikke vil virke. Fjerntilgang til filer og utsending av varsler på e-post vil kanskje ikke virke heller. Det anbefales å aktivere en internett-forbindelse for denne tjeneren hvis du vil ha full funksjonalitet.", "No memory cache has been configured. To enhance performance, please configure a memcache, if available. Further information can be found in the <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">documentation</a>." : "Hurtigminne er ikke satt opp. For bedre ytelse bør du sette opp hurtigminne hvis det er tilgjengelig. Mer informasjon finnes i <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">dokumentasjonen</a>.", + "No suitable source for randomness found by PHP which is highly discouraged for security reasons. Further information can be found in the <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">documentation</a>." : "Ingen egnet kilde til tilfeldighet funnet av PHP som er svært motløst av sikkerhetshensyn. Mer informasjon finnes i <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">dokumentasjon</a>.", "You are currently running PHP {version}. Upgrade your PHP version to take advantage of <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{phpLink}\">performance and security updates provided by the PHP Group</a> as soon as your distribution supports it." : "Du bruker PHP-{version}. Oppgrader PHP-versjonen for å utnytte <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{phpLink}\">ytelsen og sikkerhetsoppdateringene som tilbys av PHP Group</a, så fort din distribusjon støtter det.", "You are currently running PHP 5.6. The current major version of Nextcloud is the last that is supported on PHP 5.6. It is recommended to upgrade the PHP version to 7.0+ to be able to upgrade to Nextcloud 14." : "Du kjører nå PHP 5.6. Den nåværende hovedversjonen er den siste som støtter PHP 5.6. Det anbefales å oppgradere PHP-versjonen til 7.0+, for å kunne oppgradere til Nextcloud 14.", "The reverse proxy header configuration is incorrect, or you are accessing Nextcloud from a trusted proxy. If not, this is a security issue and can allow an attacker to spoof their IP address as visible to the Nextcloud. Further information can be found in the <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">documentation</a>." : "Det omvendte mellomtjener-hodet er ikke satt opp rett, eller du kobler til Nextcloud fra en betrodd mellomtjener. Hvis ikke, er dette et sikkerhetsproblem, og kan tillate en angriper å forfalske deres IP-adresse slik den er synlig for Nextcloud. Ytterligere informasjon er å finne i <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">dokumentasjonen</a>.", @@ -146,6 +148,8 @@ "Your data directory and files are probably accessible from the Internet. The .htaccess file is not working. It is strongly recommended that you configure your web server so that the data directory is no longer accessible, or move the data directory outside the web server document root." : "Datamappen og filene dine er sannsynligvis tilgjengelige fra Internett. .htaccess-filen fungerer ikke. Det anbefales sterkt at du setter opp vev-tjeneren slik at datamappen ikke kan nås eller at du flytter datamappen ut av vev-tjenerens dokumentrot.", "The \"{header}\" HTTP header is not set to \"{expected}\". This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly." : "HTTP-hodet \"{header}\" er ikke satt opp likt \"{expected}\". Dette kan være en sikkerhet- eller personvernsrisiko og det anbefales at denne innstillingen endres.", "The \"{header}\" HTTP header is not set to \"{expected}\". Some features might not work correctly, as it is recommended to adjust this setting accordingly." : "HTTP-hodet \"{header}\" er ikke satt opp til å være likt \"{expected}\". Det kan hende noen funksjoner ikke fungerer rett, og det anbefales å justere denne innstillingen henholdsvis.", + "The \"{header}\" HTTP header doesn't contain \"{expected}\". This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly." : "\"{header}\" HTTP hode mangler \"{expected}\". Dette er en sikkerhetsrisiko eller personverntrussel. Det er anbefalt å korrigere oppsett.", + "The \"{header}\" HTTP header is not set to \"{val1}\", \"{val2}\", \"{val3}\", \"{val4}\" or \"{val5}\". This can leak referer information. See the <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{link}\">W3C Recommendation ↗</a>." : "\"{header}\" HTTP hode er satt til \"{val1}\", \"{val2}\", \"{val3}\", \"{val4}\" eller \"{val5}\". Dette kan gi lekasje i henvisningsinformasjon. Se <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{link}\">W3C anbefalinger ↗</a>.", "The \"Strict-Transport-Security\" HTTP header is not set to at least \"{seconds}\" seconds. For enhanced security, it is recommended to enable HSTS as described in the <a href=\"{docUrl}\" rel=\"noreferrer noopener\">security tips ↗</a>." : "HTTP-overskriften \"Strict-Transport-Security\" er ikke satt til minst \"{sekunder}\" sekunder. For forbedret sikkerhet anbefales det å aktivere HSTS som beskrevet i <a href=\"{docUrl}\" rel=\"noreferrer noopener\">tips for bedre sikkerhet ↗</a>.", "Accessing site insecurely via HTTP. You are strongly adviced to set up your server to require HTTPS instead, as described in the <a href=\"{docUrl}\">security tips ↗</a>." : "Få tilgang til nettstedet usikkert via HTTP. Du er sterkt anbefalt å sette opp serveren din for å kreve HTTPS i stedet, som beskrevet i<a href=\"{docUrl}\">tips for bedre sikkerhet ↗</a>.", "Shared" : "Delt", @@ -159,6 +163,7 @@ "Press Ctrl-C to copy." : "Trykk Ctrl-C for å kopiere", "Resharing is not allowed" : "Videre deling er ikke tillatt", "Share to {name}" : "Dele med {name}", + "Copy link" : "Kopier lenke", "Link" : "Lenke", "Password protect" : "Passordbeskyttet", "Allow editing" : "Tillat redigering", @@ -176,6 +181,7 @@ "Shared with you and the group {group} by {owner}" : "Delt med deg og gruppen {group} av {owner}", "Shared with you and {circle} by {owner}" : "Delt med deg og {circle} av {owner}", "Shared with you and the conversation {conversation} by {owner}" : "Delt med deg og samtalen {conversation} av {owner}", + "Shared with you in a conversation by {owner}" : "Delt md deg i samtale med {owner}", "Shared with you by {owner}" : "Delt med deg av {owner}", "Choose a password for the mail share" : "Velg et passord for e-postlageret", "group" : "gruppe", @@ -192,6 +198,7 @@ "Can delete" : "Kan slette", "Password protect by Talk" : "Passord beskyttet av Talk", "Access control" : "Tilgangskontroll", + "{shareInitiatorDisplayName} shared via link" : "{shareInitiatorDisplayName} delt via lenke", "Could not unshare" : "Kunne ikke avslutte deling", "Error while sharing" : "Feil under deling", "Share details could not be loaded for this item." : "Klarte ikke å laste inn detaljer om deling for dette elementet.", @@ -201,12 +208,8 @@ "No users found for {search}" : "Ingen brukere funnet for {search}", "An error occurred (\"{message}\"). Please try again" : "En feil inntraff (\"{message}\"). Prøv igjen", "An error occurred. Please try again" : "Det oppstod en feil. Prøv igjen", - "{sharee} (group)" : "{sharee} (gruppe)", - "{sharee} (remote)" : "{sharee} (ekstern)", "{sharee} (remote group)" : "{sharee} (remote group)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (conversation)", "Share" : "Del", "Name or email address..." : "Navn eller e-postadresse…", "Name or federated cloud ID..." : "Navn eller sammenknyttet sky-ID…", @@ -248,6 +251,8 @@ "Help" : "Hjelp", "Access forbidden" : "Tilgang nektet", "File not found" : "Finner ikke filen", + "The document could not be found on the server. Maybe the share was deleted or has expired?" : "Dokumentasjon kan ikke finnes på server. Er deling slettet eller utløpt?", + "Back to %s" : "Tilbake til %s", "Internal Server Error" : "Intern tjenerfeil.", "The server was unable to complete your request." : "Tjeneren kunne ikke fullføre din forespørsel.", "If this happens again, please send the technical details below to the server administrator." : "Hvis dette skjer igjen, send de tekniske detaljene nedenfor til tjeneradministratoren.", @@ -309,23 +314,30 @@ "Forgot password?" : "Glemt passord?", "Back to login" : "Tilbake til innlogging", "Connect to your account" : "Koble til kontoen din", + "Please log in before granting %1$s access to your %2$s account." : "Logg inn før du tildeler %1$stilgang til din %2$skonto.", "App token" : "Program-symbol", "Grant access" : "Gi tilgang", "Alternative log in using app token" : "Alternativ logg inn ved hjelp av program kode", "Account access" : "Kontotilgang", + "You are about to grant %1$s access to your %2$s account." : "Du er i ferd med å tildele %1$s tilgang til din %2$skonto.", "Redirecting …" : "Videresender…", "New password" : "Nytt passord", "New Password" : "Nytt passord", "This share is password-protected" : "Denne deling er beskyttet med passord", "The password is wrong. Try again." : "Feil passord, forsøk igjen", "Two-factor authentication" : "Tofaktor autentisering", + "Enhanced security is enabled for your account. Choose a second factor for authentication:" : "Utvidet sikkerhet er tilgjengelig fo rdin konto. Velg en to-faktor for autentisering.", "Could not load at least one of your enabled two-factor auth methods. Please contact your admin." : "Kunne ikke laste minst en av de aktiverte tofaktor metodene. Ta kontakt med administrasjonen din.", + "Two-factor authentication is enforced but has not been configured on your account. Contact your admin for assistance." : "To-faktor autentisering er aktivert men er ikke satt opp for din konto. Kontakt administrator for hjelp.", + "Two-factor authentication is enforced but has not been configured on your account. Use one of your backup codes to log in or contact your admin for assistance." : "To-faktor autentisering er aktivert men er ikke satt opp for din konto. Bruk en av dine sikkerhet koder for å logge inn eller kontakt administrator for hjelp.", "Use backup code" : "Bruker sikkerhetskopi kode", "Cancel log in" : "Avbryt innlogging", "Error while validating your second factor" : "Feil under validering av din andre faktor", "Access through untrusted domain" : "Nå gjennom ubetrodd domene", "Please contact your administrator. If you are an administrator, edit the \"trusted_domains\" setting in config/config.php like the example in config.sample.php." : "Kontakt din administrator. Hvis du er en administrator, sett opp innstillingen \"trusted_domains\" i config/config.php som eksemplet i config/config.sample.php.", + "Further information how to configure this can be found in the %1$sdocumentation%2$s." : "Ytterligere informasojn om oppsett finnes i %1$sdokumentasjon%2$s.", "App update required" : "Program-oppdatering kreves", + "%1$s will be updated to version %2$s" : "%1$soppdateres til versjon %2$s", "These apps will be updated:" : "Disse programmene vil bli oppdatert:", "These incompatible apps will be disabled:" : "Disse ikke-kompatible programmene vil bli deaktivert:", "The theme %s has been disabled." : "Drakten %s har blitt deaktivert.", @@ -338,7 +350,9 @@ "For help, see the <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"%s\">documentation</a>." : "For hjelp, les <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"%s\">dokumentasjonen</a>.", "I know that if I continue doing the update via web UI has the risk, that the request runs into a timeout and could cause data loss, but I have a backup and know how to restore my instance in case of a failure." : "Jeg vet at hvis jeg fortsetter oppdateringen via vev-grensesnittet er det en mulighet for datatap som følge av tidsavbrudd, men jeg har en sikkerhetskopi og vet hvordan jeg skal gjenopprette min installasjon hvis den feiler.", "Upgrade via web on my own risk" : "Oppgrader via vev på min egen risikio", + "Maintenance mode" : "Modus for vedlikehold", "This %s instance is currently in maintenance mode, which may take a while." : "Denne %s-instansen er for øyeblikket i vedlikeholdsmodus, noe som kan vare en stund.", + "This page will refresh itself when the instance is available again." : "Siden vil oppdatere seg selv når instans er tilgjengelig igjen.", "Contact your system administrator if this message persists or appeared unexpectedly." : "Kontakt systemadministratoren hvis denne meldingen var uventet eller ikke forsvinner.", "Updated \"%s\" to %s" : "Oppdaterte \"%s\" til %s", "%s (3rdparty)" : "%s (tredjepart)", @@ -362,6 +376,9 @@ "Error setting expiration date" : "Kan ikke sette utløpsdato", "The public link will expire no later than {days} days after it is created" : "Den offentlige lenken vil utløpe senest {days} dager etter at den lages", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} delt via lenke", + "{sharee} (group)" : "{sharee} (gruppe)", + "{sharee} (remote)" : "{sharee} (ekstern)", + "{sharee} (email)" : "{sharee} (email)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Del med andre ved å skrive inn en bruker, en gruppe, en sammenknyttet sky-ID eller en e-postadresse.", "Share with other people by entering a user or group or a federated cloud ID." : "Del med andre ved å skrive inn en bruker, en gruppe eller en sammenknyttet sky-ID", "Share with other people by entering a user or group or an email address." : "Del med andre ved å skrive inn en bruker, en gruppe, eller en e-postadresse.", @@ -392,6 +409,8 @@ "Back to log in" : "Tilbake til innlogging", "You are about to grant %s access to your %s account." : "Du er i ferd med å gi %s tilgang til din %s konto.", "Depending on your configuration, this button could also work to trust the domain:" : "Avhengig av ditt oppsett, kan denne knappen også betro domenet.", + "Copy URL" : "Kopier URL", + "{sharee} (conversation)" : "{sharee} (conversation)", "Please log in before granting %s access to your %s account." : "Logg inn før du innvilger %s tilgang til din %s konto.", "Further information how to configure this can be found in the %sdocumentation%s." : "Ytterligere informasjon om hvordan du konfigurerer dette kan du finne i %sdokumentasjon%s." },"pluralForm" :"nplurals=2; plural=(n != 1);" diff --git a/core/l10n/nl.js b/core/l10n/nl.js index e79ab4ab6a8..6296051f8d9 100644 --- a/core/l10n/nl.js +++ b/core/l10n/nl.js @@ -210,12 +210,8 @@ OC.L10N.register( "No users found for {search}" : "Geen gebruikers gevonden voor {search}", "An error occurred (\"{message}\"). Please try again" : "Er heeft zich een fout voorgedaan (\"{message}\"). Probeer het opnieuw", "An error occurred. Please try again" : "Er trad een fout op. Probeer het opnieuw", - "{sharee} (group)" : "{sharee} (groep)", - "{sharee} (remote)" : "{sharee} (extern)", "{sharee} (remote group)" : "{sharee} (remote group)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (gesprek)", "Share" : "Delen", "Name or email address..." : "Naam of emailadres...", "Name or federated cloud ID..." : "Naam of gefedereerd Cloud ID:", @@ -382,6 +378,9 @@ OC.L10N.register( "Error setting expiration date" : "Fout tijdens het instellen van de vervaldatum", "The public link will expire no later than {days} days after it is created" : "De openbare link vervalt niet eerder dan {days} dagen na het aanmaken", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} delen via link", + "{sharee} (group)" : "{sharee} (groep)", + "{sharee} (remote)" : "{sharee} (extern)", + "{sharee} (email)" : "{sharee} (email)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Deel met anderen door het invullen van een gebruiker, groep, gefedereerd cloud ID of een emailadres.", "Share with other people by entering a user or group or a federated cloud ID." : "Deel met anderen door middel van gebruikers, groep of een gefedereerd cloud ID.", "Share with other people by entering a user or group or an email address." : "Deel met anderen door het invullen van een gebruiker, groep of een emailadres.", @@ -413,6 +412,7 @@ OC.L10N.register( "You are about to grant %s access to your %s account." : "Je staat op het punt om %s toegang te verlenen to je %s account.", "Depending on your configuration, this button could also work to trust the domain:" : "Afhankelijk van je configuratie kan deze knop ook werken om het volgende domein te vertrouwen:", "Copy URL" : "Kopiëren URL", + "{sharee} (conversation)" : "{sharee} (gesprek)", "Please log in before granting %s access to your %s account." : "Log alsjeblieft in voordat je %s toegang geeft tot je %s account.", "Further information how to configure this can be found in the %sdocumentation%s." : "Verdere informatie over hoe je dit insteld staat in de %s documentatie %s." }, diff --git a/core/l10n/nl.json b/core/l10n/nl.json index f4b753fe016..ef3359e4005 100644 --- a/core/l10n/nl.json +++ b/core/l10n/nl.json @@ -208,12 +208,8 @@ "No users found for {search}" : "Geen gebruikers gevonden voor {search}", "An error occurred (\"{message}\"). Please try again" : "Er heeft zich een fout voorgedaan (\"{message}\"). Probeer het opnieuw", "An error occurred. Please try again" : "Er trad een fout op. Probeer het opnieuw", - "{sharee} (group)" : "{sharee} (groep)", - "{sharee} (remote)" : "{sharee} (extern)", "{sharee} (remote group)" : "{sharee} (remote group)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (gesprek)", "Share" : "Delen", "Name or email address..." : "Naam of emailadres...", "Name or federated cloud ID..." : "Naam of gefedereerd Cloud ID:", @@ -380,6 +376,9 @@ "Error setting expiration date" : "Fout tijdens het instellen van de vervaldatum", "The public link will expire no later than {days} days after it is created" : "De openbare link vervalt niet eerder dan {days} dagen na het aanmaken", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} delen via link", + "{sharee} (group)" : "{sharee} (groep)", + "{sharee} (remote)" : "{sharee} (extern)", + "{sharee} (email)" : "{sharee} (email)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Deel met anderen door het invullen van een gebruiker, groep, gefedereerd cloud ID of een emailadres.", "Share with other people by entering a user or group or a federated cloud ID." : "Deel met anderen door middel van gebruikers, groep of een gefedereerd cloud ID.", "Share with other people by entering a user or group or an email address." : "Deel met anderen door het invullen van een gebruiker, groep of een emailadres.", @@ -411,6 +410,7 @@ "You are about to grant %s access to your %s account." : "Je staat op het punt om %s toegang te verlenen to je %s account.", "Depending on your configuration, this button could also work to trust the domain:" : "Afhankelijk van je configuratie kan deze knop ook werken om het volgende domein te vertrouwen:", "Copy URL" : "Kopiëren URL", + "{sharee} (conversation)" : "{sharee} (gesprek)", "Please log in before granting %s access to your %s account." : "Log alsjeblieft in voordat je %s toegang geeft tot je %s account.", "Further information how to configure this can be found in the %sdocumentation%s." : "Verdere informatie over hoe je dit insteld staat in de %s documentatie %s." },"pluralForm" :"nplurals=2; plural=(n != 1);" diff --git a/core/l10n/pl.js b/core/l10n/pl.js index c74cda973e7..b4562c98aaf 100644 --- a/core/l10n/pl.js +++ b/core/l10n/pl.js @@ -206,12 +206,8 @@ OC.L10N.register( "No users found for {search}" : "Nie znaleziono użytkowników dla {search}", "An error occurred (\"{message}\"). Please try again" : "Wystąpił błąd (\"{message}\"). Spróbuj ponownie", "An error occurred. Please try again" : "Wystąpił błąd. Proszę spróbować ponownie.", - "{sharee} (group)" : "{sharee} (grupa)", - "{sharee} (remote)" : "{sharee} (zdalny)", "{sharee} (remote group)" : "{sharee} (zdalna grupa)", - "{sharee} (email)" : "{sharee} (e-mail)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (konwersacja)", "Share" : "Udostępnij", "Name or email address..." : "Nazwa lub adres e-mail…", "Name or federated cloud ID..." : "Nazwa lub ID chmury stowarzyszonej…", @@ -370,6 +366,9 @@ OC.L10N.register( "Error setting expiration date" : "Błąd podczas ustawiania daty wygaśnięcia", "The public link will expire no later than {days} days after it is created" : "Link publiczny wygaśnie nie później niż po {days} dniach od utworzenia", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} udostępniane za pośrednictwem łącza", + "{sharee} (group)" : "{sharee} (grupa)", + "{sharee} (remote)" : "{sharee} (zdalny)", + "{sharee} (email)" : "{sharee} (e-mail)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Współdziel z innymi osobami przez wpisanie użytkownika lub grupy, ID chmury stowarzyszonej lub adres e-mail.", "Share with other people by entering a user or group or a federated cloud ID." : "Współdziel z innymi osobami przez wpisanie użytkownika lub grupy lub ID chmury stowarzyszonej.", "Share with other people by entering a user or group or an email address." : "Współdziel z innymi osobami przez wpisanie użytkownika lub grupy lub adresu e-mail.", @@ -401,6 +400,7 @@ OC.L10N.register( "You are about to grant %s access to your %s account." : "Zamierzasz udzielić %s dostępu do Twojego konta %s.", "Depending on your configuration, this button could also work to trust the domain:" : "W zależności od Twojej konfiguracji, ten przycisk aby zaufać domenie powinien również zadziałać: ", "Copy URL" : "Skopiuj URL", + "{sharee} (conversation)" : "{sharee} (konwersacja)", "Please log in before granting %s access to your %s account." : "Zaloguj się aby udzielić %s dostępu do Twojego konta %s.", "Further information how to configure this can be found in the %sdocumentation%s." : "Więcej informacji o konfiguracji znajdziesz w %sdokumentacji%s." }, diff --git a/core/l10n/pl.json b/core/l10n/pl.json index f62f1ee31f6..be0ea0f0d69 100644 --- a/core/l10n/pl.json +++ b/core/l10n/pl.json @@ -204,12 +204,8 @@ "No users found for {search}" : "Nie znaleziono użytkowników dla {search}", "An error occurred (\"{message}\"). Please try again" : "Wystąpił błąd (\"{message}\"). Spróbuj ponownie", "An error occurred. Please try again" : "Wystąpił błąd. Proszę spróbować ponownie.", - "{sharee} (group)" : "{sharee} (grupa)", - "{sharee} (remote)" : "{sharee} (zdalny)", "{sharee} (remote group)" : "{sharee} (zdalna grupa)", - "{sharee} (email)" : "{sharee} (e-mail)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (konwersacja)", "Share" : "Udostępnij", "Name or email address..." : "Nazwa lub adres e-mail…", "Name or federated cloud ID..." : "Nazwa lub ID chmury stowarzyszonej…", @@ -368,6 +364,9 @@ "Error setting expiration date" : "Błąd podczas ustawiania daty wygaśnięcia", "The public link will expire no later than {days} days after it is created" : "Link publiczny wygaśnie nie później niż po {days} dniach od utworzenia", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} udostępniane za pośrednictwem łącza", + "{sharee} (group)" : "{sharee} (grupa)", + "{sharee} (remote)" : "{sharee} (zdalny)", + "{sharee} (email)" : "{sharee} (e-mail)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Współdziel z innymi osobami przez wpisanie użytkownika lub grupy, ID chmury stowarzyszonej lub adres e-mail.", "Share with other people by entering a user or group or a federated cloud ID." : "Współdziel z innymi osobami przez wpisanie użytkownika lub grupy lub ID chmury stowarzyszonej.", "Share with other people by entering a user or group or an email address." : "Współdziel z innymi osobami przez wpisanie użytkownika lub grupy lub adresu e-mail.", @@ -399,6 +398,7 @@ "You are about to grant %s access to your %s account." : "Zamierzasz udzielić %s dostępu do Twojego konta %s.", "Depending on your configuration, this button could also work to trust the domain:" : "W zależności od Twojej konfiguracji, ten przycisk aby zaufać domenie powinien również zadziałać: ", "Copy URL" : "Skopiuj URL", + "{sharee} (conversation)" : "{sharee} (konwersacja)", "Please log in before granting %s access to your %s account." : "Zaloguj się aby udzielić %s dostępu do Twojego konta %s.", "Further information how to configure this can be found in the %sdocumentation%s." : "Więcej informacji o konfiguracji znajdziesz w %sdokumentacji%s." },"pluralForm" :"nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);" diff --git a/core/l10n/pt_BR.js b/core/l10n/pt_BR.js index a797647db5d..db7a373647c 100644 --- a/core/l10n/pt_BR.js +++ b/core/l10n/pt_BR.js @@ -167,6 +167,7 @@ OC.L10N.register( "Share to {name}" : "Compartilhar com {name}", "Copy link" : "Copiar link", "Link" : "Link", + "Hide download" : "Ocultar download", "Password protect" : "Proteger com senha", "Allow editing" : "Permitir edição", "Email link to person" : "Enviar link por e-mail", @@ -210,12 +211,10 @@ OC.L10N.register( "No users found for {search}" : "Nenhum usuário encontrado para {search}", "An error occurred (\"{message}\"). Please try again" : "Ocorreu um erro (\"{message}\"). Tente novamente", "An error occurred. Please try again" : "Ocorreu um erro. Tente novamente", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", "{sharee} (remote group)" : "{sharee} (grupo remoto)", - "{sharee} (email)" : "{sharee} (e-mail)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (conversation)", + "Home" : "Home", + "Other" : "Outro", "Share" : "Compartilhar", "Name or email address..." : "Nome ou endereço de e-mail...", "Name or federated cloud ID..." : "Nome ou ID de cloud federada...", @@ -382,6 +381,9 @@ OC.L10N.register( "Error setting expiration date" : "Erro ao definir data de expiração", "The public link will expire no later than {days} days after it is created" : "O link público irá expirar não antes de {days} depois de criado", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatiorDisplayName}} compartilhou via link", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (e-mail)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Compartilhe com outras pessoas entrando um usuário, grupo, ID de cloud federada ou um e-mail.", "Share with other people by entering a user or group or a federated cloud ID." : "Compartilhe com outras pessoas entrando um usuário, grupo ou ID de nuvem federada.", "Share with other people by entering a user or group or an email address." : "Compartilhe com outras pessoas entrando um usuário, grupo ou um e-mail.", @@ -413,6 +415,7 @@ OC.L10N.register( "You are about to grant %s access to your %s account." : "Você está prestes a conceder acesso a %s à sua conta %s.", "Depending on your configuration, this button could also work to trust the domain:" : "Dependendo de sua configuração, este botão também pode funcionar para confiar no domínio.", "Copy URL" : "Copiar URL", + "{sharee} (conversation)" : "{sharee} (conversation)", "Please log in before granting %s access to your %s account." : " Por favor, faça o login antes de conceder %s acesso à sua %s conta.", "Further information how to configure this can be found in the %sdocumentation%s." : "Mais informações sobre configuração podem ser encontradas na %sdocumentação%s." }, diff --git a/core/l10n/pt_BR.json b/core/l10n/pt_BR.json index 319e7368521..99330296c3b 100644 --- a/core/l10n/pt_BR.json +++ b/core/l10n/pt_BR.json @@ -165,6 +165,7 @@ "Share to {name}" : "Compartilhar com {name}", "Copy link" : "Copiar link", "Link" : "Link", + "Hide download" : "Ocultar download", "Password protect" : "Proteger com senha", "Allow editing" : "Permitir edição", "Email link to person" : "Enviar link por e-mail", @@ -208,12 +209,10 @@ "No users found for {search}" : "Nenhum usuário encontrado para {search}", "An error occurred (\"{message}\"). Please try again" : "Ocorreu um erro (\"{message}\"). Tente novamente", "An error occurred. Please try again" : "Ocorreu um erro. Tente novamente", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", "{sharee} (remote group)" : "{sharee} (grupo remoto)", - "{sharee} (email)" : "{sharee} (e-mail)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (conversation)", + "Home" : "Home", + "Other" : "Outro", "Share" : "Compartilhar", "Name or email address..." : "Nome ou endereço de e-mail...", "Name or federated cloud ID..." : "Nome ou ID de cloud federada...", @@ -380,6 +379,9 @@ "Error setting expiration date" : "Erro ao definir data de expiração", "The public link will expire no later than {days} days after it is created" : "O link público irá expirar não antes de {days} depois de criado", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatiorDisplayName}} compartilhou via link", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (e-mail)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Compartilhe com outras pessoas entrando um usuário, grupo, ID de cloud federada ou um e-mail.", "Share with other people by entering a user or group or a federated cloud ID." : "Compartilhe com outras pessoas entrando um usuário, grupo ou ID de nuvem federada.", "Share with other people by entering a user or group or an email address." : "Compartilhe com outras pessoas entrando um usuário, grupo ou um e-mail.", @@ -411,6 +413,7 @@ "You are about to grant %s access to your %s account." : "Você está prestes a conceder acesso a %s à sua conta %s.", "Depending on your configuration, this button could also work to trust the domain:" : "Dependendo de sua configuração, este botão também pode funcionar para confiar no domínio.", "Copy URL" : "Copiar URL", + "{sharee} (conversation)" : "{sharee} (conversation)", "Please log in before granting %s access to your %s account." : " Por favor, faça o login antes de conceder %s acesso à sua %s conta.", "Further information how to configure this can be found in the %sdocumentation%s." : "Mais informações sobre configuração podem ser encontradas na %sdocumentação%s." },"pluralForm" :"nplurals=2; plural=(n > 1);" diff --git a/core/l10n/pt_PT.js b/core/l10n/pt_PT.js index 5e6ca82b373..5328b26d402 100644 --- a/core/l10n/pt_PT.js +++ b/core/l10n/pt_PT.js @@ -169,9 +169,6 @@ OC.L10N.register( "No users or groups found for {search}" : "Não foram encontrados nenhuns utilizadores ou grupos para {search}", "No users found for {search}" : "Não foram encontrados utilizadores para {search}", "An error occurred. Please try again" : "Ocorreu um erro. Por favor, tente de novo.", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Partilhar", "Name or email address..." : "Nome ou endereço de email...", @@ -315,6 +312,9 @@ OC.L10N.register( "Error setting expiration date" : "Erro ao definir a data de expiração", "The public link will expire no later than {days} days after it is created" : "A hiperligação pública irá expirar, o mais tardar {days} dias depois da sua criação", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} partilhado via ligação", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (email)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Partilhar com terceiros introduzindo um nome de utilizador ou grupo, um identificador de federação ou um endereço de e-mail.", "Share with other people by entering a user or group or a federated cloud ID." : "Partilhar com terceiros introduzindo um nome de utilizador ou grupo, um ID de cloud federada ou um endereço de e-mail.", "Share with other people by entering a user or group or an email address." : "Partilhar com terceiros introduzindo um nome de utilizador ou grupo ou um endereço de e-mail.", diff --git a/core/l10n/pt_PT.json b/core/l10n/pt_PT.json index 994cad2f5ca..1ff0eabc999 100644 --- a/core/l10n/pt_PT.json +++ b/core/l10n/pt_PT.json @@ -167,9 +167,6 @@ "No users or groups found for {search}" : "Não foram encontrados nenhuns utilizadores ou grupos para {search}", "No users found for {search}" : "Não foram encontrados utilizadores para {search}", "An error occurred. Please try again" : "Ocorreu um erro. Por favor, tente de novo.", - "{sharee} (group)" : "{sharee} (grupo)", - "{sharee} (remote)" : "{sharee} (remoto)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Partilhar", "Name or email address..." : "Nome ou endereço de email...", @@ -313,6 +310,9 @@ "Error setting expiration date" : "Erro ao definir a data de expiração", "The public link will expire no later than {days} days after it is created" : "A hiperligação pública irá expirar, o mais tardar {days} dias depois da sua criação", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} partilhado via ligação", + "{sharee} (group)" : "{sharee} (grupo)", + "{sharee} (remote)" : "{sharee} (remoto)", + "{sharee} (email)" : "{sharee} (email)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Partilhar com terceiros introduzindo um nome de utilizador ou grupo, um identificador de federação ou um endereço de e-mail.", "Share with other people by entering a user or group or a federated cloud ID." : "Partilhar com terceiros introduzindo um nome de utilizador ou grupo, um ID de cloud federada ou um endereço de e-mail.", "Share with other people by entering a user or group or an email address." : "Partilhar com terceiros introduzindo um nome de utilizador ou grupo ou um endereço de e-mail.", diff --git a/core/l10n/ro.js b/core/l10n/ro.js index aa63b37960c..de217f61e30 100644 --- a/core/l10n/ro.js +++ b/core/l10n/ro.js @@ -150,9 +150,6 @@ OC.L10N.register( "No users or groups found for {search}" : "Nu au fost găsiți utilizatori sau grupuri pentru {search}", "No users found for {search}" : "Nu au fost găsiți utilizatori pentru {search}", "An error occurred. Please try again" : "A apărut o eroare. Încearcă din nou", - "{sharee} (group)" : "{sharee} (grup)", - "{sharee} (remote)" : "{sharee} (distanță)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Partajează", "Name or email address..." : "Nume sau adresă de email...", @@ -272,6 +269,9 @@ OC.L10N.register( "Error setting expiration date" : "Eroare la specificarea datei de expirare", "The public link will expire no later than {days} days after it is created" : "Legătura publică va expira nu mai târziu de {days} zile de la ziua creării", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} partajat prin legătura", + "{sharee} (group)" : "{sharee} (grup)", + "{sharee} (remote)" : "{sharee} (distanță)", + "{sharee} (email)" : "{sharee} (email)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Partajează cu alte persoane prin introducerea unui utilizator sau grup, a unui ID de cloud federalizat sau a unei adrese de email.", "Share with other people by entering a user or group or a federated cloud ID." : "Partajează cu alte persoane prin introducerea unui utilizator sau grup sau a unui ID de cloud federalizat.", "Share with other people by entering a user or group or an email address." : "Partajează cu alte persoane prin introducerea unui utilizator sau grup sau a unei adrese de email.", diff --git a/core/l10n/ro.json b/core/l10n/ro.json index f6fac2234f5..d1d457aaab3 100644 --- a/core/l10n/ro.json +++ b/core/l10n/ro.json @@ -148,9 +148,6 @@ "No users or groups found for {search}" : "Nu au fost găsiți utilizatori sau grupuri pentru {search}", "No users found for {search}" : "Nu au fost găsiți utilizatori pentru {search}", "An error occurred. Please try again" : "A apărut o eroare. Încearcă din nou", - "{sharee} (group)" : "{sharee} (grup)", - "{sharee} (remote)" : "{sharee} (distanță)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Partajează", "Name or email address..." : "Nume sau adresă de email...", @@ -270,6 +267,9 @@ "Error setting expiration date" : "Eroare la specificarea datei de expirare", "The public link will expire no later than {days} days after it is created" : "Legătura publică va expira nu mai târziu de {days} zile de la ziua creării", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} partajat prin legătura", + "{sharee} (group)" : "{sharee} (grup)", + "{sharee} (remote)" : "{sharee} (distanță)", + "{sharee} (email)" : "{sharee} (email)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Partajează cu alte persoane prin introducerea unui utilizator sau grup, a unui ID de cloud federalizat sau a unei adrese de email.", "Share with other people by entering a user or group or a federated cloud ID." : "Partajează cu alte persoane prin introducerea unui utilizator sau grup sau a unui ID de cloud federalizat.", "Share with other people by entering a user or group or an email address." : "Partajează cu alte persoane prin introducerea unui utilizator sau grup sau a unei adrese de email.", diff --git a/core/l10n/ru.js b/core/l10n/ru.js index 5af259d99d1..a8e2f077b7e 100644 --- a/core/l10n/ru.js +++ b/core/l10n/ru.js @@ -210,12 +210,8 @@ OC.L10N.register( "No users found for {search}" : "Не найдено пользователей по запросу {search}", "An error occurred (\"{message}\"). Please try again" : "Произошла ошибка («{message}»). Попробуйте ещё раз", "An error occurred. Please try again" : "Произошла ошибка. Попробуйте ещё раз", - "{sharee} (group)" : "{sharee} (группа)", - "{sharee} (remote)" : "{sharee} (на другом сервере)", "{sharee} (remote group)" : "{sharee} (группа на другом сервере)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (разговор)", "Share" : "Поделиться", "Name or email address..." : "Имя или адрес email…", "Name or federated cloud ID..." : "Имя или ID межсерверного обмена…", @@ -380,6 +376,9 @@ OC.L10N.register( "Error setting expiration date" : "Ошибка при установке срока доступа", "The public link will expire no later than {days} days after it is created" : "Срок действия общедоступной ссылки истекает не позже чем через {days} дней после её создания", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} предоставил(а) доступ созданием ссылки", + "{sharee} (group)" : "{sharee} (группа)", + "{sharee} (remote)" : "{sharee} (на другом сервере)", + "{sharee} (email)" : "{sharee} (email)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Поделиться, указав имя пользователя или группы, ID межсерверного обмена хранилища или адрес эл. почты.", "Share with other people by entering a user or group or a federated cloud ID." : "Поделиться, указав имя пользователя или группы или ID межсерверного обмена.", "Share with other people by entering a user or group or an email address." : "Поделиться, указав имя пользователя или группы, либо адрес email.", @@ -411,6 +410,7 @@ OC.L10N.register( "You are about to grant %s access to your %s account." : "Вы собираетесь предоставить пользователю %s доступ к вашему аккаунту %s.", "Depending on your configuration, this button could also work to trust the domain:" : "В зависимости от конфигурации, эта кнопка может сделать доверенным следующий домен:", "Copy URL" : "Копировать ссылку", + "{sharee} (conversation)" : "{sharee} (разговор)", "Please log in before granting %s access to your %s account." : "Пожалуйста, авторизуйтесь до того, как предоставить пользователю %s доступ к вашей учётной записи %s.", "Further information how to configure this can be found in the %sdocumentation%s." : "Более подробная информация о том, как это сконфигурировать, может быть найдена в %sдокументации%s." }, diff --git a/core/l10n/ru.json b/core/l10n/ru.json index da774c5ee84..637b110e596 100644 --- a/core/l10n/ru.json +++ b/core/l10n/ru.json @@ -208,12 +208,8 @@ "No users found for {search}" : "Не найдено пользователей по запросу {search}", "An error occurred (\"{message}\"). Please try again" : "Произошла ошибка («{message}»). Попробуйте ещё раз", "An error occurred. Please try again" : "Произошла ошибка. Попробуйте ещё раз", - "{sharee} (group)" : "{sharee} (группа)", - "{sharee} (remote)" : "{sharee} (на другом сервере)", "{sharee} (remote group)" : "{sharee} (группа на другом сервере)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (разговор)", "Share" : "Поделиться", "Name or email address..." : "Имя или адрес email…", "Name or federated cloud ID..." : "Имя или ID межсерверного обмена…", @@ -378,6 +374,9 @@ "Error setting expiration date" : "Ошибка при установке срока доступа", "The public link will expire no later than {days} days after it is created" : "Срок действия общедоступной ссылки истекает не позже чем через {days} дней после её создания", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} предоставил(а) доступ созданием ссылки", + "{sharee} (group)" : "{sharee} (группа)", + "{sharee} (remote)" : "{sharee} (на другом сервере)", + "{sharee} (email)" : "{sharee} (email)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Поделиться, указав имя пользователя или группы, ID межсерверного обмена хранилища или адрес эл. почты.", "Share with other people by entering a user or group or a federated cloud ID." : "Поделиться, указав имя пользователя или группы или ID межсерверного обмена.", "Share with other people by entering a user or group or an email address." : "Поделиться, указав имя пользователя или группы, либо адрес email.", @@ -409,6 +408,7 @@ "You are about to grant %s access to your %s account." : "Вы собираетесь предоставить пользователю %s доступ к вашему аккаунту %s.", "Depending on your configuration, this button could also work to trust the domain:" : "В зависимости от конфигурации, эта кнопка может сделать доверенным следующий домен:", "Copy URL" : "Копировать ссылку", + "{sharee} (conversation)" : "{sharee} (разговор)", "Please log in before granting %s access to your %s account." : "Пожалуйста, авторизуйтесь до того, как предоставить пользователю %s доступ к вашей учётной записи %s.", "Further information how to configure this can be found in the %sdocumentation%s." : "Более подробная информация о том, как это сконфигурировать, может быть найдена в %sдокументации%s." },"pluralForm" :"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);" diff --git a/core/l10n/sk.js b/core/l10n/sk.js index 9a66d5e379e..d4e68d0216b 100644 --- a/core/l10n/sk.js +++ b/core/l10n/sk.js @@ -210,12 +210,8 @@ OC.L10N.register( "No users found for {search}" : "Výrazu {search} nezodpovedá žiadny používateľ", "An error occurred (\"{message}\"). Please try again" : "Nastala chyba (\"{message}\"). Prosím, skúste znova", "An error occurred. Please try again" : "Nastala chyba. Skúste to prosím znovu", - "{sharee} (group)" : "{sharee} (skupina)", - "{sharee} (remote)" : "{sharee} (vzdialene)", "{sharee} (remote group)" : "{sharee} (vzdialená skupina)", - "{sharee} (email)" : "{sharee} (pošta)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (rozhovor)", "Share" : "Sprístupniť", "Name or email address..." : "Meno alebo e-mailová adresa...", "Name or federated cloud ID..." : "Meno alebo federatívny cloud ID...", @@ -382,6 +378,9 @@ OC.L10N.register( "Error setting expiration date" : "Chyba pri nastavení dátumu expirácie", "The public link will expire no later than {days} days after it is created" : "Verejný odkaz nevyprší skôr než za {days} dní po vytvorení", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} zdieľal pomocou odkazu", + "{sharee} (group)" : "{sharee} (skupina)", + "{sharee} (remote)" : "{sharee} (vzdialene)", + "{sharee} (email)" : "{sharee} (pošta)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Sprístupniť iným ľuďom zadaním používateľa alebo skupiny, federatívneho cloud ID alebo e-mailovej adresy.", "Share with other people by entering a user or group or a federated cloud ID." : "Sprístupniť iným ľuďom zadaním používateľa alebo skupiny, federatívneho cloud ID.", "Share with other people by entering a user or group or an email address." : "Sprístupniť iným ľuďom zadaním používateľa, skupiny alebo e-mailovej adresy.", @@ -413,6 +412,7 @@ OC.L10N.register( "You are about to grant %s access to your %s account." : "Chystáte sa udeliť %s prístup k svojmu %s účtu.", "Depending on your configuration, this button could also work to trust the domain:" : "V závislosti od vašej konfigurácie by toto tlačidlo mohlo fungovať tak, že dôverujete doméne:", "Copy URL" : "Kopírovať URL", + "{sharee} (conversation)" : "{sharee} (rozhovor)", "Please log in before granting %s access to your %s account." : "Skôr než udelíte prístup pre %s do vášho účtu %s je potrebné sa prihlásiť.", "Further information how to configure this can be found in the %sdocumentation%s." : "Viac informácií o konfigurácii je možné nájsť v %sdokumentácii%s." }, diff --git a/core/l10n/sk.json b/core/l10n/sk.json index d6c86110020..12cfddd9888 100644 --- a/core/l10n/sk.json +++ b/core/l10n/sk.json @@ -208,12 +208,8 @@ "No users found for {search}" : "Výrazu {search} nezodpovedá žiadny používateľ", "An error occurred (\"{message}\"). Please try again" : "Nastala chyba (\"{message}\"). Prosím, skúste znova", "An error occurred. Please try again" : "Nastala chyba. Skúste to prosím znovu", - "{sharee} (group)" : "{sharee} (skupina)", - "{sharee} (remote)" : "{sharee} (vzdialene)", "{sharee} (remote group)" : "{sharee} (vzdialená skupina)", - "{sharee} (email)" : "{sharee} (pošta)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (rozhovor)", "Share" : "Sprístupniť", "Name or email address..." : "Meno alebo e-mailová adresa...", "Name or federated cloud ID..." : "Meno alebo federatívny cloud ID...", @@ -380,6 +376,9 @@ "Error setting expiration date" : "Chyba pri nastavení dátumu expirácie", "The public link will expire no later than {days} days after it is created" : "Verejný odkaz nevyprší skôr než za {days} dní po vytvorení", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} zdieľal pomocou odkazu", + "{sharee} (group)" : "{sharee} (skupina)", + "{sharee} (remote)" : "{sharee} (vzdialene)", + "{sharee} (email)" : "{sharee} (pošta)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Sprístupniť iným ľuďom zadaním používateľa alebo skupiny, federatívneho cloud ID alebo e-mailovej adresy.", "Share with other people by entering a user or group or a federated cloud ID." : "Sprístupniť iným ľuďom zadaním používateľa alebo skupiny, federatívneho cloud ID.", "Share with other people by entering a user or group or an email address." : "Sprístupniť iným ľuďom zadaním používateľa, skupiny alebo e-mailovej adresy.", @@ -411,6 +410,7 @@ "You are about to grant %s access to your %s account." : "Chystáte sa udeliť %s prístup k svojmu %s účtu.", "Depending on your configuration, this button could also work to trust the domain:" : "V závislosti od vašej konfigurácie by toto tlačidlo mohlo fungovať tak, že dôverujete doméne:", "Copy URL" : "Kopírovať URL", + "{sharee} (conversation)" : "{sharee} (rozhovor)", "Please log in before granting %s access to your %s account." : "Skôr než udelíte prístup pre %s do vášho účtu %s je potrebné sa prihlásiť.", "Further information how to configure this can be found in the %sdocumentation%s." : "Viac informácií o konfigurácii je možné nájsť v %sdokumentácii%s." },"pluralForm" :"nplurals=4; plural=(n % 1 == 0 && n == 1 ? 0 : n % 1 == 0 && n >= 2 && n <= 4 ? 1 : n % 1 != 0 ? 2: 3);" diff --git a/core/l10n/sl.js b/core/l10n/sl.js index 1a6bf3a645e..0b8772f9b2c 100644 --- a/core/l10n/sl.js +++ b/core/l10n/sl.js @@ -152,9 +152,6 @@ OC.L10N.register( "No users or groups found for {search}" : "Ni najdenih uporabnikov ali skupin za {search}", "No users found for {search}" : "Ni uporabnikov, skladnih z iskalnim nizom {search}", "An error occurred. Please try again" : "Prišlo je do napake. Poskusite znova.", - "{sharee} (group)" : "{sharee} (skupina)", - "{sharee} (remote)" : "{sharee} (oddaljeno)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Souporaba", "Name or email address..." : "Ime ali e-poštni naslov...", @@ -265,6 +262,9 @@ OC.L10N.register( "Updated \"%s\" to %s" : "Datoteka \"%s\" je posodobljena na %s", "Error setting expiration date" : "Napaka nastavljanja datuma preteka", "The public link will expire no later than {days} days after it is created" : "Javna povezava bo potekla {days} dni po ustvarjanju.", + "{sharee} (group)" : "{sharee} (skupina)", + "{sharee} (remote)" : "{sharee} (oddaljeno)", + "{sharee} (email)" : "{sharee} (email)", "The specified document has not been found on the server." : "Določenega dokumenta na strežniku ni mogoče najti.", "You can click here to return to %s." : "S klikom na povezavo boste vrnjeni na %s.", "Wrong password. Reset it?" : "Napačno geslo. Ali ga želite ponastaviti?", diff --git a/core/l10n/sl.json b/core/l10n/sl.json index 15ffbd56712..662667a7dd6 100644 --- a/core/l10n/sl.json +++ b/core/l10n/sl.json @@ -150,9 +150,6 @@ "No users or groups found for {search}" : "Ni najdenih uporabnikov ali skupin za {search}", "No users found for {search}" : "Ni uporabnikov, skladnih z iskalnim nizom {search}", "An error occurred. Please try again" : "Prišlo je do napake. Poskusite znova.", - "{sharee} (group)" : "{sharee} (skupina)", - "{sharee} (remote)" : "{sharee} (oddaljeno)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Souporaba", "Name or email address..." : "Ime ali e-poštni naslov...", @@ -263,6 +260,9 @@ "Updated \"%s\" to %s" : "Datoteka \"%s\" je posodobljena na %s", "Error setting expiration date" : "Napaka nastavljanja datuma preteka", "The public link will expire no later than {days} days after it is created" : "Javna povezava bo potekla {days} dni po ustvarjanju.", + "{sharee} (group)" : "{sharee} (skupina)", + "{sharee} (remote)" : "{sharee} (oddaljeno)", + "{sharee} (email)" : "{sharee} (email)", "The specified document has not been found on the server." : "Določenega dokumenta na strežniku ni mogoče najti.", "You can click here to return to %s." : "S klikom na povezavo boste vrnjeni na %s.", "Wrong password. Reset it?" : "Napačno geslo. Ali ga želite ponastaviti?", diff --git a/core/l10n/sq.js b/core/l10n/sq.js index f67d4ff4646..1375211f79e 100644 --- a/core/l10n/sq.js +++ b/core/l10n/sq.js @@ -153,9 +153,6 @@ OC.L10N.register( "No users or groups found for {search}" : "S’u gjetën përdorues ose grupe për {search}", "No users found for {search}" : "S’u gjet përdorues për {search}", "An error occurred. Please try again" : "Ndodhi një gabim. Ju lutemi, riprovoni", - "{sharee} (group)" : "{sharee} (grup)", - "{sharee} (remote)" : "{sharee} (i largët)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Ndaje", "Name or email address..." : "Emri ose adresa e email-it", @@ -277,6 +274,9 @@ OC.L10N.register( "Error setting expiration date" : "Gabim në caktimin e datës së skadimit", "The public link will expire no later than {days} days after it is created" : "Lidhja publike do të skadojë jo më vonë se {days} ditë pas krijimit të saj", "{{shareInitiatorDisplayName}} shared via link" : "{{shpërndaEmrinEShfaqurTëNismëtarit}} shpërnda nëpërmjet linkut", + "{sharee} (group)" : "{sharee} (grup)", + "{sharee} (remote)" : "{sharee} (i largët)", + "{sharee} (email)" : "{sharee} (email)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Shpërndaje me persona të tjerë duke vendosur një përdorues ose një grup, një ID reje të federuar ose një adresë emaili", "Share with other people by entering a user or group or a federated cloud ID." : "Ndaj me njerëz të tjerë duke futur një pëdorues ose grup ose një ID reje federale.", "Share with other people by entering a user or group or an email address." : "Shpërndaje me persona të tjerë duke vendosur një perdorues ose një grup ose një adresë emaili", diff --git a/core/l10n/sq.json b/core/l10n/sq.json index 216537139b5..0085599091e 100644 --- a/core/l10n/sq.json +++ b/core/l10n/sq.json @@ -151,9 +151,6 @@ "No users or groups found for {search}" : "S’u gjetën përdorues ose grupe për {search}", "No users found for {search}" : "S’u gjet përdorues për {search}", "An error occurred. Please try again" : "Ndodhi një gabim. Ju lutemi, riprovoni", - "{sharee} (group)" : "{sharee} (grup)", - "{sharee} (remote)" : "{sharee} (i largët)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Ndaje", "Name or email address..." : "Emri ose adresa e email-it", @@ -275,6 +272,9 @@ "Error setting expiration date" : "Gabim në caktimin e datës së skadimit", "The public link will expire no later than {days} days after it is created" : "Lidhja publike do të skadojë jo më vonë se {days} ditë pas krijimit të saj", "{{shareInitiatorDisplayName}} shared via link" : "{{shpërndaEmrinEShfaqurTëNismëtarit}} shpërnda nëpërmjet linkut", + "{sharee} (group)" : "{sharee} (grup)", + "{sharee} (remote)" : "{sharee} (i largët)", + "{sharee} (email)" : "{sharee} (email)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Shpërndaje me persona të tjerë duke vendosur një përdorues ose një grup, një ID reje të federuar ose një adresë emaili", "Share with other people by entering a user or group or a federated cloud ID." : "Ndaj me njerëz të tjerë duke futur një pëdorues ose grup ose një ID reje federale.", "Share with other people by entering a user or group or an email address." : "Shpërndaje me persona të tjerë duke vendosur një perdorues ose një grup ose një adresë emaili", diff --git a/core/l10n/sr.js b/core/l10n/sr.js index 1d371ee480b..6302fb88b77 100644 --- a/core/l10n/sr.js +++ b/core/l10n/sr.js @@ -210,12 +210,8 @@ OC.L10N.register( "No users found for {search}" : "Није нађен ниједан корисник за претрагу {search}", "An error occurred (\"{message}\"). Please try again" : "Десила се грешка (\"{message}\"). Покушајте поново.", "An error occurred. Please try again" : "Дошло је до грешке. Покушајте поново", - "{sharee} (group)" : "{sharee} (група)", - "{sharee} (remote)" : "{sharee} (удаљено)", "{sharee} (remote group)" : "{sharee} (удаљена група)", - "{sharee} (email)" : "{sharee} (е-пошта)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (разговор)", "Share" : "Дели", "Name or email address..." : "Име или адреса е-поште...", "Name or federated cloud ID..." : "Име или ID здруженог облака...", @@ -382,6 +378,9 @@ OC.L10N.register( "Error setting expiration date" : "Грешка при постављању датума истека", "The public link will expire no later than {days} days after it is created" : "Јавна веза ће престати да важи {days} дана након стварања", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} је поделио преко везе", + "{sharee} (group)" : "{sharee} (група)", + "{sharee} (remote)" : "{sharee} (удаљено)", + "{sharee} (email)" : "{sharee} (е-пошта)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Делите са другим људима тако што унесете корисника, групу, ID здруженог облака или адресу е-поште. ", "Share with other people by entering a user or group or a federated cloud ID." : "Делите са другим људима тако што унесете корисника, групу или ID здруженог облака.", "Share with other people by entering a user or group or an email address." : "Делите са другим људима тако што унесете корисника или групу.", @@ -413,6 +412,7 @@ OC.L10N.register( "You are about to grant %s access to your %s account." : "Управо ћете одобрити %s приступ Вашем %s налогу.", "Depending on your configuration, this button could also work to trust the domain:" : "У зависности од Ваше конфигурације, овим дугметом може да послужи да почнете да верујете овом домену:", "Copy URL" : "Копирај URL", + "{sharee} (conversation)" : "{sharee} (разговор)", "Please log in before granting %s access to your %s account." : "Прво се пријавите пре него што одобрите привилегију %s приступ Вашем налогу %s.", "Further information how to configure this can be found in the %sdocumentation%s." : "Више информација о томе како ово подесити можете да нађете у %s документацији%s." }, diff --git a/core/l10n/sr.json b/core/l10n/sr.json index f6a3c9a2ed4..11245f5bcf4 100644 --- a/core/l10n/sr.json +++ b/core/l10n/sr.json @@ -208,12 +208,8 @@ "No users found for {search}" : "Није нађен ниједан корисник за претрагу {search}", "An error occurred (\"{message}\"). Please try again" : "Десила се грешка (\"{message}\"). Покушајте поново.", "An error occurred. Please try again" : "Дошло је до грешке. Покушајте поново", - "{sharee} (group)" : "{sharee} (група)", - "{sharee} (remote)" : "{sharee} (удаљено)", "{sharee} (remote group)" : "{sharee} (удаљена група)", - "{sharee} (email)" : "{sharee} (е-пошта)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (разговор)", "Share" : "Дели", "Name or email address..." : "Име или адреса е-поште...", "Name or federated cloud ID..." : "Име или ID здруженог облака...", @@ -380,6 +376,9 @@ "Error setting expiration date" : "Грешка при постављању датума истека", "The public link will expire no later than {days} days after it is created" : "Јавна веза ће престати да важи {days} дана након стварања", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} је поделио преко везе", + "{sharee} (group)" : "{sharee} (група)", + "{sharee} (remote)" : "{sharee} (удаљено)", + "{sharee} (email)" : "{sharee} (е-пошта)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Делите са другим људима тако што унесете корисника, групу, ID здруженог облака или адресу е-поште. ", "Share with other people by entering a user or group or a federated cloud ID." : "Делите са другим људима тако што унесете корисника, групу или ID здруженог облака.", "Share with other people by entering a user or group or an email address." : "Делите са другим људима тако што унесете корисника или групу.", @@ -411,6 +410,7 @@ "You are about to grant %s access to your %s account." : "Управо ћете одобрити %s приступ Вашем %s налогу.", "Depending on your configuration, this button could also work to trust the domain:" : "У зависности од Ваше конфигурације, овим дугметом може да послужи да почнете да верујете овом домену:", "Copy URL" : "Копирај URL", + "{sharee} (conversation)" : "{sharee} (разговор)", "Please log in before granting %s access to your %s account." : "Прво се пријавите пре него што одобрите привилегију %s приступ Вашем налогу %s.", "Further information how to configure this can be found in the %sdocumentation%s." : "Више информација о томе како ово подесити можете да нађете у %s документацији%s." },"pluralForm" :"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/core/l10n/sv.js b/core/l10n/sv.js index f48fc60e087..4a3299422e5 100644 --- a/core/l10n/sv.js +++ b/core/l10n/sv.js @@ -170,9 +170,6 @@ OC.L10N.register( "No users found for {search}" : "Inga användare funna för {search}", "An error occurred (\"{message}\"). Please try again" : "Ett fel uppstod (\"{message}\"). Försök igen", "An error occurred. Please try again" : "Ett fel uppstod. Vänligen försök igen", - "{sharee} (group)" : "{sharee} (grupp)", - "{sharee} (remote)" : "{sharee} (externt)", - "{sharee} (email)" : "{sharee} (e-post)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Dela", "Name or email address..." : "Namn eller e-postadress", @@ -322,6 +319,9 @@ OC.L10N.register( "Error setting expiration date" : "Fel vid val av utgångsdatum", "The public link will expire no later than {days} days after it is created" : "Den offentliga länken kommer sluta gälla inte senare än {days} dagar efter att den skapades", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} delad via länk", + "{sharee} (group)" : "{sharee} (grupp)", + "{sharee} (remote)" : "{sharee} (externt)", + "{sharee} (email)" : "{sharee} (e-post)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Dela med andra personer genom att ange användarnamn, grupp, ett federerat moln-ID eller en e-postadress.", "Share with other people by entering a user or group or a federated cloud ID." : "Dela med andra personer genom att ange användarnamn, grupp eller ett federerat moln-ID.", "Share with other people by entering a user or group or an email address." : "Dela med andra personer genom att ange användarnamn, grupp eller en e-postadress.", diff --git a/core/l10n/sv.json b/core/l10n/sv.json index 2d20e804a8d..5a8c4dc866f 100644 --- a/core/l10n/sv.json +++ b/core/l10n/sv.json @@ -168,9 +168,6 @@ "No users found for {search}" : "Inga användare funna för {search}", "An error occurred (\"{message}\"). Please try again" : "Ett fel uppstod (\"{message}\"). Försök igen", "An error occurred. Please try again" : "Ett fel uppstod. Vänligen försök igen", - "{sharee} (group)" : "{sharee} (grupp)", - "{sharee} (remote)" : "{sharee} (externt)", - "{sharee} (email)" : "{sharee} (e-post)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Dela", "Name or email address..." : "Namn eller e-postadress", @@ -320,6 +317,9 @@ "Error setting expiration date" : "Fel vid val av utgångsdatum", "The public link will expire no later than {days} days after it is created" : "Den offentliga länken kommer sluta gälla inte senare än {days} dagar efter att den skapades", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} delad via länk", + "{sharee} (group)" : "{sharee} (grupp)", + "{sharee} (remote)" : "{sharee} (externt)", + "{sharee} (email)" : "{sharee} (e-post)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Dela med andra personer genom att ange användarnamn, grupp, ett federerat moln-ID eller en e-postadress.", "Share with other people by entering a user or group or a federated cloud ID." : "Dela med andra personer genom att ange användarnamn, grupp eller ett federerat moln-ID.", "Share with other people by entering a user or group or an email address." : "Dela med andra personer genom att ange användarnamn, grupp eller en e-postadress.", diff --git a/core/l10n/tr.js b/core/l10n/tr.js index e5c85dfc7a6..080a6bc46f8 100644 --- a/core/l10n/tr.js +++ b/core/l10n/tr.js @@ -167,6 +167,7 @@ OC.L10N.register( "Share to {name}" : "{name} ile paylaş", "Copy link" : "Bağlantıyı kopyala", "Link" : "Bağlantı", + "Hide download" : "İndirmeyi gizle", "Password protect" : "Parola koruması", "Allow editing" : "Düzenlenebilsin", "Email link to person" : "Bağlantıyı e-posta ile gönder", @@ -210,12 +211,10 @@ OC.L10N.register( "No users found for {search}" : "{search} araması sonucunda uygun bir kullanıcı bulunamadı", "An error occurred (\"{message}\"). Please try again" : "Bir sorun çıktı (\"{message}\"). Lütfen yeniden deneyin.", "An error occurred. Please try again" : "Bir sorun çıktı. Lütfen yeniden deneyin", - "{sharee} (group)" : "{sharee} (grup)", - "{sharee} (remote)" : "{sharee} (uzak)", "{sharee} (remote group)" : "{sharee} (uzak grup)", - "{sharee} (email)" : "{sharee} (e-posta)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (görüşme)", + "Home" : "Giriş", + "Other" : "Diğer", "Share" : "Paylaş", "Name or email address..." : "Ad ya da e-posta adresi...", "Name or federated cloud ID..." : "Ad ya da birleşmiş bulut kodu...", @@ -382,6 +381,9 @@ OC.L10N.register( "Error setting expiration date" : "Son kullanma tarihi ayarlanırken sorun çıktı", "The public link will expire no later than {days} days after it is created" : "Herkese açık bağlantı, oluşturulduktan {days} gün sonra kullanımdan kaldırılacak", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} bağlantı ile paylaşılmış", + "{sharee} (group)" : "{sharee} (grup)", + "{sharee} (remote)" : "{sharee} (uzak)", + "{sharee} (email)" : "{sharee} (e-posta)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Bir kullanıcı, grup, birleşmiş bulut kodu ya da e-posta adresi yazarak başkaları ile paylaşın.", "Share with other people by entering a user or group or a federated cloud ID." : "Bir kullanıcı, grup ya da birleşmiş bulut kodu yazarak başkaları ile paylaşın.", "Share with other people by entering a user or group or an email address." : "Bir kullanıcı, grup ya da e-posta adresi yazarak başkaları ile paylaşın.", @@ -413,6 +415,7 @@ OC.L10N.register( "You are about to grant %s access to your %s account." : "%s erişim iznini %s hesabınız için vermek üzeresiniz.", "Depending on your configuration, this button could also work to trust the domain:" : "Yapılandırmanıza bağlı olarak, bu düğme etki alanına güvenmek için de kullanılabilir:", "Copy URL" : "Adresi Kopyala", + "{sharee} (conversation)" : "{sharee} (görüşme)", "Please log in before granting %s access to your %s account." : "Lütfen %s erişim izni %s vermeden önce oturum açın.", "Further information how to configure this can be found in the %sdocumentation%s." : "Bu ayar ile ilgili ayrıntılı bilgi almak için %sbelgelere%s bakabilirsiniz." }, diff --git a/core/l10n/tr.json b/core/l10n/tr.json index a97bd488941..fb66979b76f 100644 --- a/core/l10n/tr.json +++ b/core/l10n/tr.json @@ -165,6 +165,7 @@ "Share to {name}" : "{name} ile paylaş", "Copy link" : "Bağlantıyı kopyala", "Link" : "Bağlantı", + "Hide download" : "İndirmeyi gizle", "Password protect" : "Parola koruması", "Allow editing" : "Düzenlenebilsin", "Email link to person" : "Bağlantıyı e-posta ile gönder", @@ -208,12 +209,10 @@ "No users found for {search}" : "{search} araması sonucunda uygun bir kullanıcı bulunamadı", "An error occurred (\"{message}\"). Please try again" : "Bir sorun çıktı (\"{message}\"). Lütfen yeniden deneyin.", "An error occurred. Please try again" : "Bir sorun çıktı. Lütfen yeniden deneyin", - "{sharee} (group)" : "{sharee} (grup)", - "{sharee} (remote)" : "{sharee} (uzak)", "{sharee} (remote group)" : "{sharee} (uzak grup)", - "{sharee} (email)" : "{sharee} (e-posta)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (görüşme)", + "Home" : "Giriş", + "Other" : "Diğer", "Share" : "Paylaş", "Name or email address..." : "Ad ya da e-posta adresi...", "Name or federated cloud ID..." : "Ad ya da birleşmiş bulut kodu...", @@ -380,6 +379,9 @@ "Error setting expiration date" : "Son kullanma tarihi ayarlanırken sorun çıktı", "The public link will expire no later than {days} days after it is created" : "Herkese açık bağlantı, oluşturulduktan {days} gün sonra kullanımdan kaldırılacak", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} bağlantı ile paylaşılmış", + "{sharee} (group)" : "{sharee} (grup)", + "{sharee} (remote)" : "{sharee} (uzak)", + "{sharee} (email)" : "{sharee} (e-posta)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Bir kullanıcı, grup, birleşmiş bulut kodu ya da e-posta adresi yazarak başkaları ile paylaşın.", "Share with other people by entering a user or group or a federated cloud ID." : "Bir kullanıcı, grup ya da birleşmiş bulut kodu yazarak başkaları ile paylaşın.", "Share with other people by entering a user or group or an email address." : "Bir kullanıcı, grup ya da e-posta adresi yazarak başkaları ile paylaşın.", @@ -411,6 +413,7 @@ "You are about to grant %s access to your %s account." : "%s erişim iznini %s hesabınız için vermek üzeresiniz.", "Depending on your configuration, this button could also work to trust the domain:" : "Yapılandırmanıza bağlı olarak, bu düğme etki alanına güvenmek için de kullanılabilir:", "Copy URL" : "Adresi Kopyala", + "{sharee} (conversation)" : "{sharee} (görüşme)", "Please log in before granting %s access to your %s account." : "Lütfen %s erişim izni %s vermeden önce oturum açın.", "Further information how to configure this can be found in the %sdocumentation%s." : "Bu ayar ile ilgili ayrıntılı bilgi almak için %sbelgelere%s bakabilirsiniz." },"pluralForm" :"nplurals=2; plural=(n > 1);" diff --git a/core/l10n/uk.js b/core/l10n/uk.js index c5013f0ae59..d6d44f57788 100644 --- a/core/l10n/uk.js +++ b/core/l10n/uk.js @@ -152,9 +152,6 @@ OC.L10N.register( "No users or groups found for {search}" : "Не знайдено груп або користувачів за пошуком {search}", "No users found for {search}" : "Не знайдено жодного користувача для {search}", "An error occurred. Please try again" : "Сталася помилка. Спробуйте ще раз", - "{sharee} (group)" : "{sharee} (група)", - "{sharee} (remote)" : "{sharee} (віддалений)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Поділитися", "Name or email address..." : "Ім'я або адреса електронної пошти...", @@ -259,6 +256,9 @@ OC.L10N.register( "Updated \"%s\" to %s" : "Оновлено \"%s\" до %s", "Error setting expiration date" : "Помилка при встановленні терміну дії", "The public link will expire no later than {days} days after it is created" : "Доступ до опублікованого посилання буде припинено не пізніше ніж через {days} днів з моменту створення", + "{sharee} (group)" : "{sharee} (група)", + "{sharee} (remote)" : "{sharee} (віддалений)", + "{sharee} (email)" : "{sharee} (email)", "The specified document has not been found on the server." : "Не вдалось знайти вказаний документ на сервері.", "You can click here to return to %s." : "Ви можете натиснути тут для повернення до %s.", "Wrong password. Reset it?" : "Невірний пароль. Скинути його?", diff --git a/core/l10n/uk.json b/core/l10n/uk.json index 5eb7b3b93c2..af612818e9f 100644 --- a/core/l10n/uk.json +++ b/core/l10n/uk.json @@ -150,9 +150,6 @@ "No users or groups found for {search}" : "Не знайдено груп або користувачів за пошуком {search}", "No users found for {search}" : "Не знайдено жодного користувача для {search}", "An error occurred. Please try again" : "Сталася помилка. Спробуйте ще раз", - "{sharee} (group)" : "{sharee} (група)", - "{sharee} (remote)" : "{sharee} (віддалений)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Поділитися", "Name or email address..." : "Ім'я або адреса електронної пошти...", @@ -257,6 +254,9 @@ "Updated \"%s\" to %s" : "Оновлено \"%s\" до %s", "Error setting expiration date" : "Помилка при встановленні терміну дії", "The public link will expire no later than {days} days after it is created" : "Доступ до опублікованого посилання буде припинено не пізніше ніж через {days} днів з моменту створення", + "{sharee} (group)" : "{sharee} (група)", + "{sharee} (remote)" : "{sharee} (віддалений)", + "{sharee} (email)" : "{sharee} (email)", "The specified document has not been found on the server." : "Не вдалось знайти вказаний документ на сервері.", "You can click here to return to %s." : "Ви можете натиснути тут для повернення до %s.", "Wrong password. Reset it?" : "Невірний пароль. Скинути його?", diff --git a/core/l10n/vi.js b/core/l10n/vi.js index a6615109218..16882d7cc7d 100644 --- a/core/l10n/vi.js +++ b/core/l10n/vi.js @@ -159,9 +159,6 @@ OC.L10N.register( "No users found for {search}" : "Không tìm thấy người dùng cho {search}", "An error occurred (\"{message}\"). Please try again" : "Đã xảy ra lỗi (\"{message}\"). Hãy thử lại", "An error occurred. Please try again" : "Có lỗi vừa xảy ra. Xin vui lòng thử lại", - "{sharee} (group)" : "{sharee} (nhóm)", - "{sharee} (remote)" : "{sharee} (từ xa)", - "{sharee} (email)" : "{sharee} (thư điện tử)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Chia sẻ", "Name or email address..." : "Tên hoặc địa chỉ email.", @@ -292,6 +289,9 @@ OC.L10N.register( "Error setting expiration date" : "Lỗi cấu hình ngày kết thúc", "The public link will expire no later than {days} days after it is created" : "Liên kết công khai sẽ hết hạn sau {days} ngày sau khi được tạo", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} chia sẻ qua liên kết", + "{sharee} (group)" : "{sharee} (nhóm)", + "{sharee} (remote)" : "{sharee} (từ xa)", + "{sharee} (email)" : "{sharee} (thư điện tử)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Chia sẻ với người khác bằng cách nhập tên người dùng hoặc tên nhóm, ID đám mây liên kết hoặc địa chỉ email.", "Share with other people by entering a user or group or a federated cloud ID." : "Chia sẻ với người khác bằng cách nhập tên người dùng hoặc tên nhóm, ID đám mây liên kết.", "Share with other people by entering a user or group or an email address." : "Chia sẻ với người khác bằng cách nhập tên người dùng hoặc tên nhóm, hoặc địa chỉ email.", diff --git a/core/l10n/vi.json b/core/l10n/vi.json index cee3000c91a..ff500a839b4 100644 --- a/core/l10n/vi.json +++ b/core/l10n/vi.json @@ -157,9 +157,6 @@ "No users found for {search}" : "Không tìm thấy người dùng cho {search}", "An error occurred (\"{message}\"). Please try again" : "Đã xảy ra lỗi (\"{message}\"). Hãy thử lại", "An error occurred. Please try again" : "Có lỗi vừa xảy ra. Xin vui lòng thử lại", - "{sharee} (group)" : "{sharee} (nhóm)", - "{sharee} (remote)" : "{sharee} (từ xa)", - "{sharee} (email)" : "{sharee} (thư điện tử)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", "Share" : "Chia sẻ", "Name or email address..." : "Tên hoặc địa chỉ email.", @@ -290,6 +287,9 @@ "Error setting expiration date" : "Lỗi cấu hình ngày kết thúc", "The public link will expire no later than {days} days after it is created" : "Liên kết công khai sẽ hết hạn sau {days} ngày sau khi được tạo", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} chia sẻ qua liên kết", + "{sharee} (group)" : "{sharee} (nhóm)", + "{sharee} (remote)" : "{sharee} (từ xa)", + "{sharee} (email)" : "{sharee} (thư điện tử)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "Chia sẻ với người khác bằng cách nhập tên người dùng hoặc tên nhóm, ID đám mây liên kết hoặc địa chỉ email.", "Share with other people by entering a user or group or a federated cloud ID." : "Chia sẻ với người khác bằng cách nhập tên người dùng hoặc tên nhóm, ID đám mây liên kết.", "Share with other people by entering a user or group or an email address." : "Chia sẻ với người khác bằng cách nhập tên người dùng hoặc tên nhóm, hoặc địa chỉ email.", diff --git a/core/l10n/zh_CN.js b/core/l10n/zh_CN.js index e6de190ac2b..815c457edf9 100644 --- a/core/l10n/zh_CN.js +++ b/core/l10n/zh_CN.js @@ -104,8 +104,8 @@ OC.L10N.register( "({count} selected)" : "(选择了 {count} 个)", "Error loading file exists template" : "加载文件存在性模板失败", "Pending" : "等待", - "Copy to {folder}" : "复制{文件夹}", - "Move to {folder}" : "移动{文件夹}", + "Copy to {folder}" : "复制到 {folder}", + "Move to {folder}" : "移动到 {folder}", "New in" : "新品", "View changelog" : "查看更新记录", "Very weak password" : "非常弱的密码", @@ -122,6 +122,9 @@ OC.L10N.register( "The PHP module \"fileinfo\" is missing. It is strongly recommended to enable this module to get the best results with MIME type detection." : "未找到 PHP 的 \"fileinfo\" 模块。强烈推荐启用该模块,从而获得更好的 MIME 类型探测结果。", "{name} below version {version} is installed, for stability and performance reasons it is recommended to update to a newer {name} version." : "{name} 已安装 {version} 版本,出于稳定和性能的考虑,建议更新到 {name} 版本。", "Transactional file locking is disabled, this might lead to issues with race conditions. Enable \"filelocking.enabled\" in config.php to avoid these problems. See the <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">documentation ↗</a> for more information." : "已禁用事务性文件锁定,这可能在竞争条件下导致问题。在 config.php 中启用 \"filelocking.enabled\" 可以避免此问题。详情查阅 <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">文档 ↗</a>。", + "If your installation is not installed at the root of the domain and uses system cron, there can be issues with the URL generation. To avoid these problems, please set the \"overwrite.cli.url\" option in your config.php file to the webroot path of your installation (suggestion: \"{suggestedOverwriteCliURL}\")" : "如果没有将 Nextcloud 安装到域名根目录并使用系统计划任务,生成超链接就会出现问题。为避免此问题,请在 config.php 配置文件中将 \"overwrite.cli.url\" 设置为你 Nextcloud 安装的路径。(建议:\"{suggestedOverwriteCliURL}\")", + "It was not possible to execute the cron job via CLI. The following technical errors have appeared:" : "无法通过 CLI 执行计划任务,请查看以下技术错误:", + "Last background job execution ran {relativeTime}. Something seems wrong." : "最近一次执行后台任务运行时间为 {relativeTime},似乎哪里出了问题。", "Check the background job settings" : "请检查后台任务设置", "This server has no working Internet connection: Multiple endpoints could not be reached. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. Establish a connection from this server to the Internet to enjoy all features." : "此服务器没有可用的互联网连接:多个节点无法访问。这意味着某些功能比如挂载外部存储,更新通知以及安装第三方应用将无法工作。远程访问文件和发送通知邮件可能也不工作。启用这台服务器上的互联网连接以享用所有功能。", "No memory cache has been configured. To enhance performance, please configure a memcache, if available. Further information can be found in the <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">documentation</a>." : "内存缓存未配置,为了提升使用体验,请尽量配置内存缓存。更多信息请参见<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">文档</a>。", @@ -130,16 +133,26 @@ OC.L10N.register( "The reverse proxy header configuration is incorrect, or you are accessing Nextcloud from a trusted proxy. If not, this is a security issue and can allow an attacker to spoof their IP address as visible to the Nextcloud. Further information can be found in the <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">documentation</a>." : "反向代理头部配置错误,或者您正在通过可信的代理访问 Nextcloud。如果您不是通过可信代理访问 Nextcloud,这是一个安全问题,它允许攻击者通过伪装 IP 地址访问 Nextcloud。更多信息请查看<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">文档</a>。", "Memcached is configured as distributed cache, but the wrong PHP module \"memcache\" is installed. \\OC\\Memcache\\Memcached only supports \"memcached\" and not \"memcache\". See the <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{wikiLink}\">memcached wiki about both modules</a>." : "Memcached 当前配置为分布式缓存, 但是当前安装的 PHP 模块是 \"memcache\". \\OC\\Memcache\\Memcached 仅支持 \"memcached\" 而不是 \"memcache\". 点击 <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{wikiLink}\">memcached wiki </a>了解两者的差别。", "Some files have not passed the integrity check. Further information on how to resolve this issue can be found in the <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">documentation</a>. (<a href=\"{codeIntegrityDownloadEndpoint}\">List of invalid files…</a> / <a href=\"{rescanEndpoint}\">Rescan…</a>)" : "一些文件没有通过完整性检查。了解如何解决该问题请查看我们的 <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">文档</a>。(<a href=\"{codeIntegrityDownloadEndpoint}\">无效文件列表…</a> / <a href=\"{rescanEndpoint}\">重新扫描…</a>)", + "The PHP OPcache module is not loaded. <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">For better performance it is recommended</a> to load it into your PHP installation." : "PHP 的 OPcache 模块未载入。<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">推荐开启获得更好的性能</a>。", "The PHP OPcache is not properly configured. <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">For better performance it is recommended</a> to use the following settings in the <code>php.ini</code>:" : "PHP 的组件 OPcache 没有正确配置。 <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">为了提供更好的性能</a>,我们建议在 <code>php.ini</code>中使用下列设置:", "The PHP function \"set_time_limit\" is not available. This could result in scripts being halted mid-execution, breaking your installation. Enabling this function is strongly recommended." : "PHP函数“set_time_limit”不可用。 这可能会导致脚本在执行过程中暂停,从而导致安装中断。 我们强烈建议启用此功能。", "Your PHP does not have FreeType support, resulting in breakage of profile pictures and the settings interface." : "您的 PHP 没有 FreeType 支持,导致配置文件图片和设置界面中断。", "Missing index \"{indexName}\" in table \"{tableName}\"." : "在数据表 \"{tableName}\" 中无法找到索引 \"{indexName}\" .", + "The database is missing some indexes. Due to the fact that adding indexes on big tables could take some time they were not added automatically. By running \"occ db:add-missing-indices\" those missing indexes could be added manually while the instance keeps running. Once the indexes are added queries to those tables are usually much faster." : "数据库丢失了一些索引。由于给大的数据表添加索引会耗费一些时间,因此程序没有自动对其进行修复。您可以在 Nextcloud 运行时通过命令行手动执行 \"occ db:add-missing-indices\" 命令修复丢失的索引。索引修复后会大大提高相应表的查询速度。", + "SQLite is currently being used as the backend database. For larger installations we recommend that you switch to a different database backend." : "当前正在使用 SQLite 作为后端数据库。多用户使用时,推荐您改用其他的数据库。", + "This is particularly recommended when using the desktop client for file synchronisation." : "特别推荐使用桌面客户端同步的用户选择。", + "To migrate to another database use the command line tool: 'occ db:convert-type', or see the <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">documentation ↗</a>." : "迁移到其他数据库,使用命令:'occ db:convert-type' 或查阅 <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">文档↗</a>。", + "Use of the the built in php mailer is no longer supported. <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">Please update your email server settings ↗<a/>." : "PHP 内建的邮件发送器已不再受支持。<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">请更新你的 E-mail 服务器设置↗<a/>。", "The PHP memory limit is below the recommended value of 512MB." : "PHP内存限制低于建议值512MB.", + "Some app directories are owned by a different user than the web server one. This may be the case if apps have been installed manually. Check the permissions of the following app directories:" : "有些应用程序目录是由与 Web 服务器不同的用户拥有的。如果应用程序是手动安装的,情况可能是这样的。检查以下应用程序目录的权限:", "Error occurred while checking server setup" : "检查服务器设置时出错", "Your data directory and files are probably accessible from the Internet. The .htaccess file is not working. It is strongly recommended that you configure your web server so that the data directory is no longer accessible, or move the data directory outside the web server document root." : "您的数据目录和文件可以从互联网直接访问。.htaccess 文件不起作用。强烈建议您配置 Web 服务器,以便数据目录不再可访问,或者你可以将数据目录移动到 Web 服务器文档根目录。", "The \"{header}\" HTTP header is not set to \"{expected}\". This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly." : "HTTP 请求头 \"{header}\" 没有配置为 \"{expected}\"。这是一个潜在的安全或隐私风险, 我们建议您调整这项设置.", "The \"{header}\" HTTP header is not set to \"{expected}\". Some features might not work correctly, as it is recommended to adjust this setting accordingly." : "HTTP 请求头 \"{header}\" 没有配置为 \"{expected}\"。某些功能可能无法正常工作,因此建议相应地调整此设置。", + "The \"{header}\" HTTP header doesn't contain \"{expected}\". This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly." : "HTTP 头 \"{header}\" 未包含 \"{expected}\"。这是一种潜在的安全或隐私风险,因此推荐调整此项设置。", + "The \"{header}\" HTTP header is not set to \"{val1}\", \"{val2}\", \"{val3}\", \"{val4}\" or \"{val5}\". This can leak referer information. See the <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{link}\">W3C Recommendation ↗</a>." : "HTTP 头 \"{header}\" 未设置成 \"{val1}\",\"{val2}\",\"{val3}\",\"{val4}\" 或 \"{val5}\"。这会泄露更多的信息。请查阅 <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{link}\">W3C 建议↗</a>。", "The \"Strict-Transport-Security\" HTTP header is not set to at least \"{seconds}\" seconds. For enhanced security, it is recommended to enable HSTS as described in the <a href=\"{docUrl}\" rel=\"noreferrer noopener\">security tips ↗</a>." : "HTTP的请求头 \"Strict-Transport-Security\" 未设置为至少 \"{seconds}\" 秒. 为了提高安全性,建议参照<a href=\"{docUrl}\" rel=\"noreferrer noopener\">security tips ↗</a>中的说明启用HSTS.", + "Accessing site insecurely via HTTP. You are strongly adviced to set up your server to require HTTPS instead, as described in the <a href=\"{docUrl}\">security tips ↗</a>." : "通过 HTTP 访问网站不安全。强烈建议您将服务器设置成 HTTPS 协议,请查阅 <a href=\"{docUrl}\">安全贴士↗</a>。", "Shared" : "已共享", "Shared with" : "共享给", "Shared by" : "共享人", @@ -151,6 +164,7 @@ OC.L10N.register( "Press Ctrl-C to copy." : "按 Ctrl + C 进行复制.", "Resharing is not allowed" : "不允许二次共享", "Share to {name}" : "共享给{name}", + "Copy link" : "复制链接", "Link" : "链接", "Password protect" : "密码保护", "Allow editing" : "允许编辑", @@ -162,17 +176,20 @@ OC.L10N.register( "Set expiration date" : "设置过期日期", "Expiration" : "过期", "Expiration date" : "过期日期", + "Note to recipient" : "备注", "Share link" : "共享链接", "Enable" : "启用", "Shared with you and the group {group} by {owner}" : "{owner} 共享给您及 {group} 分组", "Shared with you and {circle} by {owner}" : "{owner} 共享给您及 {circle}", "Shared with you and the conversation {conversation} by {owner}" : "{owner} 共享给您及对话 {conversation}", + "Shared with you in a conversation by {owner}" : "由 {owner} 通过一个对话与你分享", "Shared with you by {owner}" : "{owner} 共享给您", "Choose a password for the mail share" : "为电子邮件共享选择一个密码", "group" : "群组", "remote" : "外部", "remote group" : "远程群组", "email" : "邮件", + "conversation" : "对话", "shared by {sharer}" : "由 {sharer} 共享", "Unshare" : "取消共享", "Can reshare" : "可以再次共享", @@ -180,7 +197,9 @@ OC.L10N.register( "Can create" : "可以创建", "Can change" : "可以修改", "Can delete" : "可以删除", + "Password protect by Talk" : "通过 Talk 保护密码", "Access control" : "访问控制", + "{shareInitiatorDisplayName} shared via link" : "{shareInitiatorDisplayName} 通过链接共享", "Could not unshare" : "无法共享", "Error while sharing" : "共享时出错", "Share details could not be loaded for this item." : "无法加载这个项目的共享详情.", @@ -190,9 +209,7 @@ OC.L10N.register( "No users found for {search}" : "没有找到 {search} 用户", "An error occurred (\"{message}\"). Please try again" : "发生错误 (\"{message}\"). 请重试", "An error occurred. Please try again" : "发生错误. 请重试", - "{sharee} (group)" : "{sharee} (分组)", - "{sharee} (remote)" : "{sharee} (外部)", - "{sharee} (email)" : "{sharee} (邮件)", + "{sharee} (remote group)" : "{sharee}(远程组)", "{sharee} ({type}, {owner})" : "{share}({type},{owner})", "Share" : "共享", "Name or email address..." : "姓名或电子邮件地址...", @@ -235,6 +252,8 @@ OC.L10N.register( "Help" : "帮助", "Access forbidden" : "访问禁止", "File not found" : "文件未找到", + "The document could not be found on the server. Maybe the share was deleted or has expired?" : "服务器上找不到该文档。可能此共享已被删除或过期。", + "Back to %s" : "返回 %s", "Internal Server Error" : "内部服务器错误", "The server was unable to complete your request." : "服务器不能完成你的请求。", "If this happens again, please send the technical details below to the server administrator." : "如果再次发生,请在下方将技术详情发送给服务器管理员。", @@ -274,6 +293,8 @@ OC.L10N.register( "Need help?" : "需要帮助?", "See the documentation" : "查看文档", "This application requires JavaScript for correct operation. Please {linkstart}enable JavaScript{linkend} and reload the page." : "对于正确的操作, 该应用需要使用 JavaScript. 请 {linkstart}启用 JavaScript{linkend}, 并重新加载页面.", + "Skip to main content" : "跳过主内容", + "Skip to navigation of app" : "跳过应用向导", "More apps" : "更多的应用程序", "More apps menu" : "更多的应用菜单", "Search" : "搜索", @@ -294,22 +315,30 @@ OC.L10N.register( "Forgot password?" : "忘记密码?", "Back to login" : "返回登录", "Connect to your account" : "连接您的账户", + "Please log in before granting %1$s access to your %2$s account." : "在授权 %1$s 访问您的 %2$s 账户之前,请先登录。", "App token" : "App 令牌", "Grant access" : "授权访问", "Alternative log in using app token" : "使用应用程序令牌替代登录", "Account access" : "账户访问", + "You are about to grant %1$s access to your %2$s account." : "您正在授权 %1$s 访问您的 %2$s 账户。", "Redirecting …" : "正在跳转 …", "New password" : "新密码", "New Password" : "新密码", "This share is password-protected" : "这个共享是被密码保护的", "The password is wrong. Try again." : "密码错误.请重试.", "Two-factor authentication" : "双重认证", + "Enhanced security is enabled for your account. Choose a second factor for authentication:" : "您的账户已启用安全增强。请选择第二种验证方式。", + "Could not load at least one of your enabled two-factor auth methods. Please contact your admin." : "无法载入你启用的任何双因素验证方法。请联系管理员。", + "Two-factor authentication is enforced but has not been configured on your account. Contact your admin for assistance." : "双因素验证是强制性的,但你的账户似乎未做配置。请联系管理员获得支持。", + "Two-factor authentication is enforced but has not been configured on your account. Use one of your backup codes to log in or contact your admin for assistance." : "双因素验证是强制性的,但你的账户似乎未做配置。使用你的备份代码登录或求助管理员。", "Use backup code" : "使用备用口令", "Cancel log in" : "取消登录", "Error while validating your second factor" : "验证您的第二项时出错", "Access through untrusted domain" : "通过不被信任的域名访问", "Please contact your administrator. If you are an administrator, edit the \"trusted_domains\" setting in config/config.php like the example in config.sample.php." : "请联系你的管理员。如果你就是管理员,请参照 config.sample.php 中的示例编辑 config/config.php 中的 \"trusted_domains\" 设置。", + "Further information how to configure this can be found in the %1$sdocumentation%2$s." : "配置此项的详细内容请查阅 %1$s文档%2$s。", "App update required" : "必须的应用更新", + "%1$s will be updated to version %2$s" : "%1$s 将被升级至版本 %2$s", "These apps will be updated:" : "以下应用将被更新:", "These incompatible apps will be disabled:" : "下述不兼容的应用将被禁用:", "The theme %s has been disabled." : "%s 主题已被禁用.", @@ -322,7 +351,9 @@ OC.L10N.register( "For help, see the <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"%s\">documentation</a>." : "获取更多帮助,请查看<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"%s\">文档</a>。", "I know that if I continue doing the update via web UI has the risk, that the request runs into a timeout and could cause data loss, but I have a backup and know how to restore my instance in case of a failure." : "我知道继续通过Web UI进行更新的风险,请求超时运行,并可能导致数据丢失,但我有一个备份,并知道如何恢复。", "Upgrade via web on my own risk" : "通过网络升级的风险", + "Maintenance mode" : "维护模式", "This %s instance is currently in maintenance mode, which may take a while." : "该实例 %s 当前处于维护模式, 这将花费一些时间.", + "This page will refresh itself when the instance is available again." : "当实力再次可用时,页面会自动刷新。", "Contact your system administrator if this message persists or appeared unexpectedly." : "如果这个消息一直存在或不停出现, 请联系你的系统管理员.", "Updated \"%s\" to %s" : "更新 \"%s\" 为 %s", "%s (3rdparty)" : "%s(第三方)", @@ -346,6 +377,9 @@ OC.L10N.register( "Error setting expiration date" : "设置过期日期时出错", "The public link will expire no later than {days} days after it is created" : "该共享链接将在创建后 {days} 天失效", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} 通过链接共享", + "{sharee} (group)" : "{sharee} (分组)", + "{sharee} (remote)" : "{sharee} (外部)", + "{sharee} (email)" : "{sharee} (邮件)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "通过输入用户或组,联合云ID或电子邮件地址与其他人共享。", "Share with other people by entering a user or group or a federated cloud ID." : "通过输入用户或组或联合云ID与其他人共享。", "Share with other people by entering a user or group or an email address." : "输入用户/组织或邮箱地址来共享给其他人.", @@ -376,6 +410,8 @@ OC.L10N.register( "Back to log in" : "返回登录", "You are about to grant %s access to your %s account." : "你将分配 %s 访问权限给你的 %s 账户。", "Depending on your configuration, this button could also work to trust the domain:" : "取决于配置,此按钮也可用作设置信任域名:", + "Copy URL" : "复制超链接", + "{sharee} (conversation)" : "{sharee}(对话)", "Please log in before granting %s access to your %s account." : "请在登录之前授权 %s 访问你的 %s 账户。", "Further information how to configure this can be found in the %sdocumentation%s." : "更多配置信息可以查看 %s文档%s。" }, diff --git a/core/l10n/zh_CN.json b/core/l10n/zh_CN.json index f9406028c0c..87f1b38c1f5 100644 --- a/core/l10n/zh_CN.json +++ b/core/l10n/zh_CN.json @@ -102,8 +102,8 @@ "({count} selected)" : "(选择了 {count} 个)", "Error loading file exists template" : "加载文件存在性模板失败", "Pending" : "等待", - "Copy to {folder}" : "复制{文件夹}", - "Move to {folder}" : "移动{文件夹}", + "Copy to {folder}" : "复制到 {folder}", + "Move to {folder}" : "移动到 {folder}", "New in" : "新品", "View changelog" : "查看更新记录", "Very weak password" : "非常弱的密码", @@ -120,6 +120,9 @@ "The PHP module \"fileinfo\" is missing. It is strongly recommended to enable this module to get the best results with MIME type detection." : "未找到 PHP 的 \"fileinfo\" 模块。强烈推荐启用该模块,从而获得更好的 MIME 类型探测结果。", "{name} below version {version} is installed, for stability and performance reasons it is recommended to update to a newer {name} version." : "{name} 已安装 {version} 版本,出于稳定和性能的考虑,建议更新到 {name} 版本。", "Transactional file locking is disabled, this might lead to issues with race conditions. Enable \"filelocking.enabled\" in config.php to avoid these problems. See the <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">documentation ↗</a> for more information." : "已禁用事务性文件锁定,这可能在竞争条件下导致问题。在 config.php 中启用 \"filelocking.enabled\" 可以避免此问题。详情查阅 <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">文档 ↗</a>。", + "If your installation is not installed at the root of the domain and uses system cron, there can be issues with the URL generation. To avoid these problems, please set the \"overwrite.cli.url\" option in your config.php file to the webroot path of your installation (suggestion: \"{suggestedOverwriteCliURL}\")" : "如果没有将 Nextcloud 安装到域名根目录并使用系统计划任务,生成超链接就会出现问题。为避免此问题,请在 config.php 配置文件中将 \"overwrite.cli.url\" 设置为你 Nextcloud 安装的路径。(建议:\"{suggestedOverwriteCliURL}\")", + "It was not possible to execute the cron job via CLI. The following technical errors have appeared:" : "无法通过 CLI 执行计划任务,请查看以下技术错误:", + "Last background job execution ran {relativeTime}. Something seems wrong." : "最近一次执行后台任务运行时间为 {relativeTime},似乎哪里出了问题。", "Check the background job settings" : "请检查后台任务设置", "This server has no working Internet connection: Multiple endpoints could not be reached. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. Establish a connection from this server to the Internet to enjoy all features." : "此服务器没有可用的互联网连接:多个节点无法访问。这意味着某些功能比如挂载外部存储,更新通知以及安装第三方应用将无法工作。远程访问文件和发送通知邮件可能也不工作。启用这台服务器上的互联网连接以享用所有功能。", "No memory cache has been configured. To enhance performance, please configure a memcache, if available. Further information can be found in the <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">documentation</a>." : "内存缓存未配置,为了提升使用体验,请尽量配置内存缓存。更多信息请参见<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">文档</a>。", @@ -128,16 +131,26 @@ "The reverse proxy header configuration is incorrect, or you are accessing Nextcloud from a trusted proxy. If not, this is a security issue and can allow an attacker to spoof their IP address as visible to the Nextcloud. Further information can be found in the <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">documentation</a>." : "反向代理头部配置错误,或者您正在通过可信的代理访问 Nextcloud。如果您不是通过可信代理访问 Nextcloud,这是一个安全问题,它允许攻击者通过伪装 IP 地址访问 Nextcloud。更多信息请查看<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">文档</a>。", "Memcached is configured as distributed cache, but the wrong PHP module \"memcache\" is installed. \\OC\\Memcache\\Memcached only supports \"memcached\" and not \"memcache\". See the <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{wikiLink}\">memcached wiki about both modules</a>." : "Memcached 当前配置为分布式缓存, 但是当前安装的 PHP 模块是 \"memcache\". \\OC\\Memcache\\Memcached 仅支持 \"memcached\" 而不是 \"memcache\". 点击 <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{wikiLink}\">memcached wiki </a>了解两者的差别。", "Some files have not passed the integrity check. Further information on how to resolve this issue can be found in the <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">documentation</a>. (<a href=\"{codeIntegrityDownloadEndpoint}\">List of invalid files…</a> / <a href=\"{rescanEndpoint}\">Rescan…</a>)" : "一些文件没有通过完整性检查。了解如何解决该问题请查看我们的 <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">文档</a>。(<a href=\"{codeIntegrityDownloadEndpoint}\">无效文件列表…</a> / <a href=\"{rescanEndpoint}\">重新扫描…</a>)", + "The PHP OPcache module is not loaded. <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">For better performance it is recommended</a> to load it into your PHP installation." : "PHP 的 OPcache 模块未载入。<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">推荐开启获得更好的性能</a>。", "The PHP OPcache is not properly configured. <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">For better performance it is recommended</a> to use the following settings in the <code>php.ini</code>:" : "PHP 的组件 OPcache 没有正确配置。 <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">为了提供更好的性能</a>,我们建议在 <code>php.ini</code>中使用下列设置:", "The PHP function \"set_time_limit\" is not available. This could result in scripts being halted mid-execution, breaking your installation. Enabling this function is strongly recommended." : "PHP函数“set_time_limit”不可用。 这可能会导致脚本在执行过程中暂停,从而导致安装中断。 我们强烈建议启用此功能。", "Your PHP does not have FreeType support, resulting in breakage of profile pictures and the settings interface." : "您的 PHP 没有 FreeType 支持,导致配置文件图片和设置界面中断。", "Missing index \"{indexName}\" in table \"{tableName}\"." : "在数据表 \"{tableName}\" 中无法找到索引 \"{indexName}\" .", + "The database is missing some indexes. Due to the fact that adding indexes on big tables could take some time they were not added automatically. By running \"occ db:add-missing-indices\" those missing indexes could be added manually while the instance keeps running. Once the indexes are added queries to those tables are usually much faster." : "数据库丢失了一些索引。由于给大的数据表添加索引会耗费一些时间,因此程序没有自动对其进行修复。您可以在 Nextcloud 运行时通过命令行手动执行 \"occ db:add-missing-indices\" 命令修复丢失的索引。索引修复后会大大提高相应表的查询速度。", + "SQLite is currently being used as the backend database. For larger installations we recommend that you switch to a different database backend." : "当前正在使用 SQLite 作为后端数据库。多用户使用时,推荐您改用其他的数据库。", + "This is particularly recommended when using the desktop client for file synchronisation." : "特别推荐使用桌面客户端同步的用户选择。", + "To migrate to another database use the command line tool: 'occ db:convert-type', or see the <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">documentation ↗</a>." : "迁移到其他数据库,使用命令:'occ db:convert-type' 或查阅 <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">文档↗</a>。", + "Use of the the built in php mailer is no longer supported. <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">Please update your email server settings ↗<a/>." : "PHP 内建的邮件发送器已不再受支持。<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{docLink}\">请更新你的 E-mail 服务器设置↗<a/>。", "The PHP memory limit is below the recommended value of 512MB." : "PHP内存限制低于建议值512MB.", + "Some app directories are owned by a different user than the web server one. This may be the case if apps have been installed manually. Check the permissions of the following app directories:" : "有些应用程序目录是由与 Web 服务器不同的用户拥有的。如果应用程序是手动安装的,情况可能是这样的。检查以下应用程序目录的权限:", "Error occurred while checking server setup" : "检查服务器设置时出错", "Your data directory and files are probably accessible from the Internet. The .htaccess file is not working. It is strongly recommended that you configure your web server so that the data directory is no longer accessible, or move the data directory outside the web server document root." : "您的数据目录和文件可以从互联网直接访问。.htaccess 文件不起作用。强烈建议您配置 Web 服务器,以便数据目录不再可访问,或者你可以将数据目录移动到 Web 服务器文档根目录。", "The \"{header}\" HTTP header is not set to \"{expected}\". This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly." : "HTTP 请求头 \"{header}\" 没有配置为 \"{expected}\"。这是一个潜在的安全或隐私风险, 我们建议您调整这项设置.", "The \"{header}\" HTTP header is not set to \"{expected}\". Some features might not work correctly, as it is recommended to adjust this setting accordingly." : "HTTP 请求头 \"{header}\" 没有配置为 \"{expected}\"。某些功能可能无法正常工作,因此建议相应地调整此设置。", + "The \"{header}\" HTTP header doesn't contain \"{expected}\". This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly." : "HTTP 头 \"{header}\" 未包含 \"{expected}\"。这是一种潜在的安全或隐私风险,因此推荐调整此项设置。", + "The \"{header}\" HTTP header is not set to \"{val1}\", \"{val2}\", \"{val3}\", \"{val4}\" or \"{val5}\". This can leak referer information. See the <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{link}\">W3C Recommendation ↗</a>." : "HTTP 头 \"{header}\" 未设置成 \"{val1}\",\"{val2}\",\"{val3}\",\"{val4}\" 或 \"{val5}\"。这会泄露更多的信息。请查阅 <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"{link}\">W3C 建议↗</a>。", "The \"Strict-Transport-Security\" HTTP header is not set to at least \"{seconds}\" seconds. For enhanced security, it is recommended to enable HSTS as described in the <a href=\"{docUrl}\" rel=\"noreferrer noopener\">security tips ↗</a>." : "HTTP的请求头 \"Strict-Transport-Security\" 未设置为至少 \"{seconds}\" 秒. 为了提高安全性,建议参照<a href=\"{docUrl}\" rel=\"noreferrer noopener\">security tips ↗</a>中的说明启用HSTS.", + "Accessing site insecurely via HTTP. You are strongly adviced to set up your server to require HTTPS instead, as described in the <a href=\"{docUrl}\">security tips ↗</a>." : "通过 HTTP 访问网站不安全。强烈建议您将服务器设置成 HTTPS 协议,请查阅 <a href=\"{docUrl}\">安全贴士↗</a>。", "Shared" : "已共享", "Shared with" : "共享给", "Shared by" : "共享人", @@ -149,6 +162,7 @@ "Press Ctrl-C to copy." : "按 Ctrl + C 进行复制.", "Resharing is not allowed" : "不允许二次共享", "Share to {name}" : "共享给{name}", + "Copy link" : "复制链接", "Link" : "链接", "Password protect" : "密码保护", "Allow editing" : "允许编辑", @@ -160,17 +174,20 @@ "Set expiration date" : "设置过期日期", "Expiration" : "过期", "Expiration date" : "过期日期", + "Note to recipient" : "备注", "Share link" : "共享链接", "Enable" : "启用", "Shared with you and the group {group} by {owner}" : "{owner} 共享给您及 {group} 分组", "Shared with you and {circle} by {owner}" : "{owner} 共享给您及 {circle}", "Shared with you and the conversation {conversation} by {owner}" : "{owner} 共享给您及对话 {conversation}", + "Shared with you in a conversation by {owner}" : "由 {owner} 通过一个对话与你分享", "Shared with you by {owner}" : "{owner} 共享给您", "Choose a password for the mail share" : "为电子邮件共享选择一个密码", "group" : "群组", "remote" : "外部", "remote group" : "远程群组", "email" : "邮件", + "conversation" : "对话", "shared by {sharer}" : "由 {sharer} 共享", "Unshare" : "取消共享", "Can reshare" : "可以再次共享", @@ -178,7 +195,9 @@ "Can create" : "可以创建", "Can change" : "可以修改", "Can delete" : "可以删除", + "Password protect by Talk" : "通过 Talk 保护密码", "Access control" : "访问控制", + "{shareInitiatorDisplayName} shared via link" : "{shareInitiatorDisplayName} 通过链接共享", "Could not unshare" : "无法共享", "Error while sharing" : "共享时出错", "Share details could not be loaded for this item." : "无法加载这个项目的共享详情.", @@ -188,9 +207,7 @@ "No users found for {search}" : "没有找到 {search} 用户", "An error occurred (\"{message}\"). Please try again" : "发生错误 (\"{message}\"). 请重试", "An error occurred. Please try again" : "发生错误. 请重试", - "{sharee} (group)" : "{sharee} (分组)", - "{sharee} (remote)" : "{sharee} (外部)", - "{sharee} (email)" : "{sharee} (邮件)", + "{sharee} (remote group)" : "{sharee}(远程组)", "{sharee} ({type}, {owner})" : "{share}({type},{owner})", "Share" : "共享", "Name or email address..." : "姓名或电子邮件地址...", @@ -233,6 +250,8 @@ "Help" : "帮助", "Access forbidden" : "访问禁止", "File not found" : "文件未找到", + "The document could not be found on the server. Maybe the share was deleted or has expired?" : "服务器上找不到该文档。可能此共享已被删除或过期。", + "Back to %s" : "返回 %s", "Internal Server Error" : "内部服务器错误", "The server was unable to complete your request." : "服务器不能完成你的请求。", "If this happens again, please send the technical details below to the server administrator." : "如果再次发生,请在下方将技术详情发送给服务器管理员。", @@ -272,6 +291,8 @@ "Need help?" : "需要帮助?", "See the documentation" : "查看文档", "This application requires JavaScript for correct operation. Please {linkstart}enable JavaScript{linkend} and reload the page." : "对于正确的操作, 该应用需要使用 JavaScript. 请 {linkstart}启用 JavaScript{linkend}, 并重新加载页面.", + "Skip to main content" : "跳过主内容", + "Skip to navigation of app" : "跳过应用向导", "More apps" : "更多的应用程序", "More apps menu" : "更多的应用菜单", "Search" : "搜索", @@ -292,22 +313,30 @@ "Forgot password?" : "忘记密码?", "Back to login" : "返回登录", "Connect to your account" : "连接您的账户", + "Please log in before granting %1$s access to your %2$s account." : "在授权 %1$s 访问您的 %2$s 账户之前,请先登录。", "App token" : "App 令牌", "Grant access" : "授权访问", "Alternative log in using app token" : "使用应用程序令牌替代登录", "Account access" : "账户访问", + "You are about to grant %1$s access to your %2$s account." : "您正在授权 %1$s 访问您的 %2$s 账户。", "Redirecting …" : "正在跳转 …", "New password" : "新密码", "New Password" : "新密码", "This share is password-protected" : "这个共享是被密码保护的", "The password is wrong. Try again." : "密码错误.请重试.", "Two-factor authentication" : "双重认证", + "Enhanced security is enabled for your account. Choose a second factor for authentication:" : "您的账户已启用安全增强。请选择第二种验证方式。", + "Could not load at least one of your enabled two-factor auth methods. Please contact your admin." : "无法载入你启用的任何双因素验证方法。请联系管理员。", + "Two-factor authentication is enforced but has not been configured on your account. Contact your admin for assistance." : "双因素验证是强制性的,但你的账户似乎未做配置。请联系管理员获得支持。", + "Two-factor authentication is enforced but has not been configured on your account. Use one of your backup codes to log in or contact your admin for assistance." : "双因素验证是强制性的,但你的账户似乎未做配置。使用你的备份代码登录或求助管理员。", "Use backup code" : "使用备用口令", "Cancel log in" : "取消登录", "Error while validating your second factor" : "验证您的第二项时出错", "Access through untrusted domain" : "通过不被信任的域名访问", "Please contact your administrator. If you are an administrator, edit the \"trusted_domains\" setting in config/config.php like the example in config.sample.php." : "请联系你的管理员。如果你就是管理员,请参照 config.sample.php 中的示例编辑 config/config.php 中的 \"trusted_domains\" 设置。", + "Further information how to configure this can be found in the %1$sdocumentation%2$s." : "配置此项的详细内容请查阅 %1$s文档%2$s。", "App update required" : "必须的应用更新", + "%1$s will be updated to version %2$s" : "%1$s 将被升级至版本 %2$s", "These apps will be updated:" : "以下应用将被更新:", "These incompatible apps will be disabled:" : "下述不兼容的应用将被禁用:", "The theme %s has been disabled." : "%s 主题已被禁用.", @@ -320,7 +349,9 @@ "For help, see the <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"%s\">documentation</a>." : "获取更多帮助,请查看<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"%s\">文档</a>。", "I know that if I continue doing the update via web UI has the risk, that the request runs into a timeout and could cause data loss, but I have a backup and know how to restore my instance in case of a failure." : "我知道继续通过Web UI进行更新的风险,请求超时运行,并可能导致数据丢失,但我有一个备份,并知道如何恢复。", "Upgrade via web on my own risk" : "通过网络升级的风险", + "Maintenance mode" : "维护模式", "This %s instance is currently in maintenance mode, which may take a while." : "该实例 %s 当前处于维护模式, 这将花费一些时间.", + "This page will refresh itself when the instance is available again." : "当实力再次可用时,页面会自动刷新。", "Contact your system administrator if this message persists or appeared unexpectedly." : "如果这个消息一直存在或不停出现, 请联系你的系统管理员.", "Updated \"%s\" to %s" : "更新 \"%s\" 为 %s", "%s (3rdparty)" : "%s(第三方)", @@ -344,6 +375,9 @@ "Error setting expiration date" : "设置过期日期时出错", "The public link will expire no later than {days} days after it is created" : "该共享链接将在创建后 {days} 天失效", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} 通过链接共享", + "{sharee} (group)" : "{sharee} (分组)", + "{sharee} (remote)" : "{sharee} (外部)", + "{sharee} (email)" : "{sharee} (邮件)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "通过输入用户或组,联合云ID或电子邮件地址与其他人共享。", "Share with other people by entering a user or group or a federated cloud ID." : "通过输入用户或组或联合云ID与其他人共享。", "Share with other people by entering a user or group or an email address." : "输入用户/组织或邮箱地址来共享给其他人.", @@ -374,6 +408,8 @@ "Back to log in" : "返回登录", "You are about to grant %s access to your %s account." : "你将分配 %s 访问权限给你的 %s 账户。", "Depending on your configuration, this button could also work to trust the domain:" : "取决于配置,此按钮也可用作设置信任域名:", + "Copy URL" : "复制超链接", + "{sharee} (conversation)" : "{sharee}(对话)", "Please log in before granting %s access to your %s account." : "请在登录之前授权 %s 访问你的 %s 账户。", "Further information how to configure this can be found in the %sdocumentation%s." : "更多配置信息可以查看 %s文档%s。" },"pluralForm" :"nplurals=1; plural=0;" diff --git a/core/l10n/zh_TW.js b/core/l10n/zh_TW.js index db99f2107a3..89787aa34aa 100644 --- a/core/l10n/zh_TW.js +++ b/core/l10n/zh_TW.js @@ -193,12 +193,8 @@ OC.L10N.register( "No users found for {search}" : "沒有使用者符合 {search}", "An error occurred (\"{message}\"). Please try again" : "發生錯誤({message}),請再試一次", "An error occurred. Please try again" : "發生錯誤,請再試一次", - "{sharee} (group)" : "{sharee} (群組)", - "{sharee} (remote)" : "{sharee} (遠端)", "{sharee} (remote group)" : "{sharee} (遠端群組)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (對話)", "Share" : "分享", "Name or email address..." : "名字或電子郵件地址", "Name or federated cloud ID..." : "名稱或者聯盟式雲端ID...", @@ -353,6 +349,9 @@ OC.L10N.register( "Error setting expiration date" : "設定到期日發生錯誤", "The public link will expire no later than {days} days after it is created" : "這個公開連結會在 {days} 天內失效", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} 分享了連結", + "{sharee} (group)" : "{sharee} (群組)", + "{sharee} (remote)" : "{sharee} (遠端)", + "{sharee} (email)" : "{sharee} (email)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "透過輸入使用者、群組名稱,聯盟式雲端ID或e-mail信箱來分享給其他人。 ", "Share with other people by entering a user or group or a federated cloud ID." : "透過輸入使用者、群組名稱,聯盟式雲端ID來分享給其他人。", "Share with other people by entering a user or group or an email address." : "透過輸入使用者、群組名稱或email來分享給其他人。", @@ -379,6 +378,7 @@ OC.L10N.register( "Back to log in" : "回到登入頁面", "You are about to grant %s access to your %s account." : "您將授予「%s」存取您的 %s 帳戶", "Depending on your configuration, this button could also work to trust the domain:" : "根據你的設定值,此按鈕也可用於信任以下網域:", + "{sharee} (conversation)" : "{sharee} (對話)", "Please log in before granting %s access to your %s account." : "請登入後再授權 %s 存取你的 %s 帳號", "Further information how to configure this can be found in the %sdocumentation%s." : "關於如何設定這個的更多訊息,請見 %s 文件 %s" }, diff --git a/core/l10n/zh_TW.json b/core/l10n/zh_TW.json index 45c57f4bc38..a82889658ea 100644 --- a/core/l10n/zh_TW.json +++ b/core/l10n/zh_TW.json @@ -191,12 +191,8 @@ "No users found for {search}" : "沒有使用者符合 {search}", "An error occurred (\"{message}\"). Please try again" : "發生錯誤({message}),請再試一次", "An error occurred. Please try again" : "發生錯誤,請再試一次", - "{sharee} (group)" : "{sharee} (群組)", - "{sharee} (remote)" : "{sharee} (遠端)", "{sharee} (remote group)" : "{sharee} (遠端群組)", - "{sharee} (email)" : "{sharee} (email)", "{sharee} ({type}, {owner})" : "{sharee} ({type}, {owner})", - "{sharee} (conversation)" : "{sharee} (對話)", "Share" : "分享", "Name or email address..." : "名字或電子郵件地址", "Name or federated cloud ID..." : "名稱或者聯盟式雲端ID...", @@ -351,6 +347,9 @@ "Error setting expiration date" : "設定到期日發生錯誤", "The public link will expire no later than {days} days after it is created" : "這個公開連結會在 {days} 天內失效", "{{shareInitiatorDisplayName}} shared via link" : "{{shareInitiatorDisplayName}} 分享了連結", + "{sharee} (group)" : "{sharee} (群組)", + "{sharee} (remote)" : "{sharee} (遠端)", + "{sharee} (email)" : "{sharee} (email)", "Share with other people by entering a user or group, a federated cloud ID or an email address." : "透過輸入使用者、群組名稱,聯盟式雲端ID或e-mail信箱來分享給其他人。 ", "Share with other people by entering a user or group or a federated cloud ID." : "透過輸入使用者、群組名稱,聯盟式雲端ID來分享給其他人。", "Share with other people by entering a user or group or an email address." : "透過輸入使用者、群組名稱或email來分享給其他人。", @@ -377,6 +376,7 @@ "Back to log in" : "回到登入頁面", "You are about to grant %s access to your %s account." : "您將授予「%s」存取您的 %s 帳戶", "Depending on your configuration, this button could also work to trust the domain:" : "根據你的設定值,此按鈕也可用於信任以下網域:", + "{sharee} (conversation)" : "{sharee} (對話)", "Please log in before granting %s access to your %s account." : "請登入後再授權 %s 存取你的 %s 帳號", "Further information how to configure this can be found in the %sdocumentation%s." : "關於如何設定這個的更多訊息,請見 %s 文件 %s" },"pluralForm" :"nplurals=1; plural=0;" diff --git a/core/register_command.php b/core/register_command.php index af8d9977c7f..9c3591c8afe 100644 --- a/core/register_command.php +++ b/core/register_command.php @@ -65,6 +65,7 @@ if (\OC::$server->getConfig()->getSystemValue('installed', false)) { $application->add(new OC\Core\Command\App\Install()); $application->add(new OC\Core\Command\App\GetPath()); $application->add(new OC\Core\Command\App\ListApps(\OC::$server->getAppManager())); + $application->add(new OC\Core\Command\App\Remove(\OC::$server->getAppManager(), \OC::$server->query(\OC\Installer::class), \OC::$server->getLogger())); $application->add(\OC::$server->query(\OC\Core\Command\TwoFactorAuth\Cleanup::class)); $application->add(\OC::$server->query(\OC\Core\Command\TwoFactorAuth\Enforce::class)); diff --git a/core/routes.php b/core/routes.php index f3884a765a2..f5e6d8e7d21 100644 --- a/core/routes.php +++ b/core/routes.php @@ -61,9 +61,9 @@ $application->registerRoutes($this, [ ['name' => 'OCJS#getConfig', 'url' => '/core/js/oc.js', 'verb' => 'GET'], ['name' => 'Preview#getPreviewByFileId', 'url' => '/core/preview', 'verb' => 'GET'], ['name' => 'Preview#getPreview', 'url' => '/core/preview.png', 'verb' => 'GET'], - ['name' => 'Svg#getSvgFromCore', 'url' => '/svg/core/{folder}/{fileName}/{color}', 'verb' => 'GET'], - ['name' => 'Svg#getSvgFromSettings', 'url' => '/svg/settings/{folder}/{fileName}/{color}', 'verb' => 'GET'], - ['name' => 'Svg#getSvgFromApp', 'url' => '/svg/{app}/{fileName}/{color}', 'verb' => 'GET'], + ['name' => 'Svg#getSvgFromCore', 'url' => '/svg/core/{folder}/{fileName}', 'verb' => 'GET'], + ['name' => 'Svg#getSvgFromSettings', 'url' => '/svg/settings/{folder}/{fileName}', 'verb' => 'GET'], + ['name' => 'Svg#getSvgFromApp', 'url' => '/svg/{app}/{fileName}', 'verb' => 'GET'], ['name' => 'Css#getCss', 'url' => '/css/{appName}/{fileName}', 'verb' => 'GET'], ['name' => 'Js#getJs', 'url' => '/js/{appName}/{fileName}', 'verb' => 'GET'], ['name' => 'contactsMenu#index', 'url' => '/contactsmenu/contacts', 'verb' => 'POST'], diff --git a/core/templates/layout.user.php b/core/templates/layout.user.php index d82043b2572..6f0344aa600 100644 --- a/core/templates/layout.user.php +++ b/core/templates/layout.user.php @@ -47,7 +47,7 @@ <ul id="appmenu" <?php if ($_['themingInvertMenu']) { ?>class="inverted"<?php } ?>> <?php foreach ($_['navigation'] as $entry): ?> - <li data-id="<?php p($entry['id']); ?>" class="hidden"> + <li data-id="<?php p($entry['id']); ?>" class="hidden" tabindex="-1"> <a href="<?php print_unescaped($entry['href']); ?>" <?php if ($entry['active']): ?> class="active"<?php endif; ?> aria-label="<?php p($entry['name']); ?>"> @@ -69,7 +69,7 @@ aria-haspopup="true" aria-controls="navigation" aria-expanded="false"> <a href="#" aria-label="<?php p($l->t('More apps')); ?>"> <div class="icon-more-white"></div> - <span><?php p($l->t('More apps')); ?></span> + <span><?php p($l->t('More')); ?></span> </a> </li> </ul> diff --git a/core/templates/login.php b/core/templates/login.php index 989ea1eaad5..3035d23da70 100644 --- a/core/templates/login.php +++ b/core/templates/login.php @@ -42,7 +42,7 @@ use OC\Core\Controller\LoginController; aria-label="<?php p($l->t('Username or email')); ?>" value="<?php p($_['loginName']); ?>" <?php p($_['user_autofocus'] ? 'autofocus' : ''); ?> - autocomplete="on" autocapitalize="none" autocorrect="off" required> + autocomplete="<?php p($_['login_form_autocomplete']); ?>" autocapitalize="none" autocorrect="off" required> <label for="user" class="infield"><?php p($l->t('Username or email')); ?></label> </p> @@ -51,7 +51,7 @@ use OC\Core\Controller\LoginController; placeholder="<?php p($l->t('Password')); ?>" aria-label="<?php p($l->t('Password')); ?>" <?php p($_['user_autofocus'] ? '' : 'autofocus'); ?> - autocomplete="on" autocapitalize="off" autocorrect="none" required> + autocomplete="<?php p($_['login_form_autocomplete']); ?>" autocapitalize="none" autocorrect="off" required> <label for="password" class="infield"><?php p($l->t('Password')); ?></label> </p> diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index 863d0e62837..8c6dc502487 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -231,7 +231,25 @@ return array( 'OCP\\Files\\Storage\\INotifyStorage' => $baseDir . '/lib/public/Files/Storage/INotifyStorage.php', 'OCP\\Files\\Storage\\IStorage' => $baseDir . '/lib/public/Files/Storage/IStorage.php', 'OCP\\Files\\Storage\\IStorageFactory' => $baseDir . '/lib/public/Files/Storage/IStorageFactory.php', + 'OCP\\Files\\Storage\\IWriteStreamStorage' => $baseDir . '/lib/public/Files/Storage/IWriteStreamStorage.php', 'OCP\\Files\\UnseekableException' => $baseDir . '/lib/public/Files/UnseekableException.php', + 'OCP\\Files_FullTextSearch\\Model\\AFilesDocument' => $baseDir . '/lib/public/Files_FullTextSearch/Model/AFilesDocument.php', + 'OCP\\FullTextSearch\\Exceptions\\FullTextSearchAppNotAvailableException' => $baseDir . '/lib/public/FullTextSearch/Exceptions/FullTextSearchAppNotAvailableException.php', + 'OCP\\FullTextSearch\\IFullTextSearchManager' => $baseDir . '/lib/public/FullTextSearch/IFullTextSearchManager.php', + 'OCP\\FullTextSearch\\IFullTextSearchPlatform' => $baseDir . '/lib/public/FullTextSearch/IFullTextSearchPlatform.php', + 'OCP\\FullTextSearch\\IFullTextSearchProvider' => $baseDir . '/lib/public/FullTextSearch/IFullTextSearchProvider.php', + 'OCP\\FullTextSearch\\Model\\DocumentAccess' => $baseDir . '/lib/public/FullTextSearch/Model/DocumentAccess.php', + 'OCP\\FullTextSearch\\Model\\IIndex' => $baseDir . '/lib/public/FullTextSearch/Model/IIndex.php', + 'OCP\\FullTextSearch\\Model\\IIndexOptions' => $baseDir . '/lib/public/FullTextSearch/Model/IIndexOptions.php', + 'OCP\\FullTextSearch\\Model\\IRunner' => $baseDir . '/lib/public/FullTextSearch/Model/IRunner.php', + 'OCP\\FullTextSearch\\Model\\ISearchRequest' => $baseDir . '/lib/public/FullTextSearch/Model/ISearchRequest.php', + 'OCP\\FullTextSearch\\Model\\ISearchResult' => $baseDir . '/lib/public/FullTextSearch/Model/ISearchResult.php', + 'OCP\\FullTextSearch\\Model\\IndexDocument' => $baseDir . '/lib/public/FullTextSearch/Model/IndexDocument.php', + 'OCP\\FullTextSearch\\Model\\SearchOption' => $baseDir . '/lib/public/FullTextSearch/Model/SearchOption.php', + 'OCP\\FullTextSearch\\Model\\SearchTemplate' => $baseDir . '/lib/public/FullTextSearch/Model/SearchTemplate.php', + 'OCP\\FullTextSearch\\Service\\IIndexService' => $baseDir . '/lib/public/FullTextSearch/Service/IIndexService.php', + 'OCP\\FullTextSearch\\Service\\IProviderService' => $baseDir . '/lib/public/FullTextSearch/Service/IProviderService.php', + 'OCP\\FullTextSearch\\Service\\ISearchService' => $baseDir . '/lib/public/FullTextSearch/Service/ISearchService.php', 'OCP\\GlobalScale\\IConfig' => $baseDir . '/lib/public/GlobalScale/IConfig.php', 'OCP\\GroupInterface' => $baseDir . '/lib/public/GroupInterface.php', 'OCP\\Group\\Backend\\ABackend' => $baseDir . '/lib/public/Group/Backend/ABackend.php', @@ -458,6 +476,7 @@ return array( 'OC\\Archive\\Archive' => $baseDir . '/lib/private/Archive/Archive.php', 'OC\\Archive\\TAR' => $baseDir . '/lib/private/Archive/TAR.php', 'OC\\Archive\\ZIP' => $baseDir . '/lib/private/Archive/ZIP.php', + 'OC\\Authentication\\Exceptions\\ExpiredTokenException' => $baseDir . '/lib/private/Authentication/Exceptions/ExpiredTokenException.php', 'OC\\Authentication\\Exceptions\\InvalidProviderException' => $baseDir . '/lib/private/Authentication/Exceptions/InvalidProviderException.php', 'OC\\Authentication\\Exceptions\\InvalidTokenException' => $baseDir . '/lib/private/Authentication/Exceptions/InvalidTokenException.php', 'OC\\Authentication\\Exceptions\\LoginRequiredException' => $baseDir . '/lib/private/Authentication/Exceptions/LoginRequiredException.php', @@ -471,7 +490,6 @@ return array( 'OC\\Authentication\\Token\\DefaultTokenCleanupJob' => $baseDir . '/lib/private/Authentication/Token/DefaultTokenCleanupJob.php', 'OC\\Authentication\\Token\\DefaultTokenMapper' => $baseDir . '/lib/private/Authentication/Token/DefaultTokenMapper.php', 'OC\\Authentication\\Token\\DefaultTokenProvider' => $baseDir . '/lib/private/Authentication/Token/DefaultTokenProvider.php', - 'OC\\Authentication\\Token\\ExpiredTokenException' => $baseDir . '/lib/private/Authentication/Exceptions/ExpiredTokenException.php', 'OC\\Authentication\\Token\\IProvider' => $baseDir . '/lib/private/Authentication/Token/IProvider.php', 'OC\\Authentication\\Token\\IToken' => $baseDir . '/lib/private/Authentication/Token/IToken.php', 'OC\\Authentication\\Token\\Manager' => $baseDir . '/lib/private/Authentication/Token/Manager.php', @@ -539,6 +557,7 @@ return array( 'OC\\Core\\Command\\App\\GetPath' => $baseDir . '/core/Command/App/GetPath.php', 'OC\\Core\\Command\\App\\Install' => $baseDir . '/core/Command/App/Install.php', 'OC\\Core\\Command\\App\\ListApps' => $baseDir . '/core/Command/App/ListApps.php', + 'OC\\Core\\Command\\App\\Remove' => $baseDir . '/core/Command/App/Remove.php', 'OC\\Core\\Command\\Background\\Ajax' => $baseDir . '/core/Command/Background/Ajax.php', 'OC\\Core\\Command\\Background\\Base' => $baseDir . '/core/Command/Background/Base.php', 'OC\\Core\\Command\\Background\\Cron' => $baseDir . '/core/Command/Background/Cron.php', @@ -651,6 +670,7 @@ return array( 'OC\\Core\\Migrations\\Version14000Date20180710092004' => $baseDir . '/core/Migrations/Version14000Date20180710092004.php', 'OC\\Core\\Migrations\\Version14000Date20180712153140' => $baseDir . '/core/Migrations/Version14000Date20180712153140.php', 'OC\\Core\\Migrations\\Version15000Date20180926101451' => $baseDir . '/core/Migrations/Version15000Date20180926101451.php', + 'OC\\Core\\Migrations\\Version15000Date20181015062942' => $baseDir . '/core/Migrations/Version15000Date20181015062942.php', 'OC\\DB\\Adapter' => $baseDir . '/lib/private/DB/Adapter.php', 'OC\\DB\\AdapterMySQL' => $baseDir . '/lib/private/DB/AdapterMySQL.php', 'OC\\DB\\AdapterOCI8' => $baseDir . '/lib/private/DB/AdapterOCI8.php', @@ -802,6 +822,7 @@ return array( 'OC\\Files\\Storage\\Wrapper\\PermissionsMask' => $baseDir . '/lib/private/Files/Storage/Wrapper/PermissionsMask.php', 'OC\\Files\\Storage\\Wrapper\\Quota' => $baseDir . '/lib/private/Files/Storage/Wrapper/Quota.php', 'OC\\Files\\Storage\\Wrapper\\Wrapper' => $baseDir . '/lib/private/Files/Storage/Wrapper/Wrapper.php', + 'OC\\Files\\Stream\\CountReadStream' => $baseDir . '/lib/private/Files/Stream/CountReadStream.php', 'OC\\Files\\Stream\\Encryption' => $baseDir . '/lib/private/Files/Stream/Encryption.php', 'OC\\Files\\Stream\\Quota' => $baseDir . '/lib/private/Files/Stream/Quota.php', 'OC\\Files\\Type\\Detection' => $baseDir . '/lib/private/Files/Type/Detection.php', @@ -810,6 +831,7 @@ return array( 'OC\\Files\\Utils\\Scanner' => $baseDir . '/lib/private/Files/Utils/Scanner.php', 'OC\\Files\\View' => $baseDir . '/lib/private/Files/View.php', 'OC\\ForbiddenException' => $baseDir . '/lib/private/ForbiddenException.php', + 'OC\\FullTextSearch\\FullTextSearchManager' => $baseDir . '/lib/private/FullTextSearch/FullTextSearchManager.php', 'OC\\GlobalScale\\Config' => $baseDir . '/lib/private/GlobalScale/Config.php', 'OC\\Group\\Backend' => $baseDir . '/lib/private/Group/Backend.php', 'OC\\Group\\Database' => $baseDir . '/lib/private/Group/Database.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index b14376045ab..2a46e99e020 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -261,7 +261,25 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OCP\\Files\\Storage\\INotifyStorage' => __DIR__ . '/../../..' . '/lib/public/Files/Storage/INotifyStorage.php', 'OCP\\Files\\Storage\\IStorage' => __DIR__ . '/../../..' . '/lib/public/Files/Storage/IStorage.php', 'OCP\\Files\\Storage\\IStorageFactory' => __DIR__ . '/../../..' . '/lib/public/Files/Storage/IStorageFactory.php', + 'OCP\\Files\\Storage\\IWriteStreamStorage' => __DIR__ . '/../../..' . '/lib/public/Files/Storage/IWriteStreamStorage.php', 'OCP\\Files\\UnseekableException' => __DIR__ . '/../../..' . '/lib/public/Files/UnseekableException.php', + 'OCP\\Files_FullTextSearch\\Model\\AFilesDocument' => __DIR__ . '/../../..' . '/lib/public/Files_FullTextSearch/Model/AFilesDocument.php', + 'OCP\\FullTextSearch\\Exceptions\\FullTextSearchAppNotAvailableException' => __DIR__ . '/../../..' . '/lib/public/FullTextSearch/Exceptions/FullTextSearchAppNotAvailableException.php', + 'OCP\\FullTextSearch\\IFullTextSearchManager' => __DIR__ . '/../../..' . '/lib/public/FullTextSearch/IFullTextSearchManager.php', + 'OCP\\FullTextSearch\\IFullTextSearchPlatform' => __DIR__ . '/../../..' . '/lib/public/FullTextSearch/IFullTextSearchPlatform.php', + 'OCP\\FullTextSearch\\IFullTextSearchProvider' => __DIR__ . '/../../..' . '/lib/public/FullTextSearch/IFullTextSearchProvider.php', + 'OCP\\FullTextSearch\\Model\\DocumentAccess' => __DIR__ . '/../../..' . '/lib/public/FullTextSearch/Model/DocumentAccess.php', + 'OCP\\FullTextSearch\\Model\\IIndex' => __DIR__ . '/../../..' . '/lib/public/FullTextSearch/Model/IIndex.php', + 'OCP\\FullTextSearch\\Model\\IIndexOptions' => __DIR__ . '/../../..' . '/lib/public/FullTextSearch/Model/IIndexOptions.php', + 'OCP\\FullTextSearch\\Model\\IRunner' => __DIR__ . '/../../..' . '/lib/public/FullTextSearch/Model/IRunner.php', + 'OCP\\FullTextSearch\\Model\\ISearchRequest' => __DIR__ . '/../../..' . '/lib/public/FullTextSearch/Model/ISearchRequest.php', + 'OCP\\FullTextSearch\\Model\\ISearchResult' => __DIR__ . '/../../..' . '/lib/public/FullTextSearch/Model/ISearchResult.php', + 'OCP\\FullTextSearch\\Model\\IndexDocument' => __DIR__ . '/../../..' . '/lib/public/FullTextSearch/Model/IndexDocument.php', + 'OCP\\FullTextSearch\\Model\\SearchOption' => __DIR__ . '/../../..' . '/lib/public/FullTextSearch/Model/SearchOption.php', + 'OCP\\FullTextSearch\\Model\\SearchTemplate' => __DIR__ . '/../../..' . '/lib/public/FullTextSearch/Model/SearchTemplate.php', + 'OCP\\FullTextSearch\\Service\\IIndexService' => __DIR__ . '/../../..' . '/lib/public/FullTextSearch/Service/IIndexService.php', + 'OCP\\FullTextSearch\\Service\\IProviderService' => __DIR__ . '/../../..' . '/lib/public/FullTextSearch/Service/IProviderService.php', + 'OCP\\FullTextSearch\\Service\\ISearchService' => __DIR__ . '/../../..' . '/lib/public/FullTextSearch/Service/ISearchService.php', 'OCP\\GlobalScale\\IConfig' => __DIR__ . '/../../..' . '/lib/public/GlobalScale/IConfig.php', 'OCP\\GroupInterface' => __DIR__ . '/../../..' . '/lib/public/GroupInterface.php', 'OCP\\Group\\Backend\\ABackend' => __DIR__ . '/../../..' . '/lib/public/Group/Backend/ABackend.php', @@ -488,6 +506,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OC\\Archive\\Archive' => __DIR__ . '/../../..' . '/lib/private/Archive/Archive.php', 'OC\\Archive\\TAR' => __DIR__ . '/../../..' . '/lib/private/Archive/TAR.php', 'OC\\Archive\\ZIP' => __DIR__ . '/../../..' . '/lib/private/Archive/ZIP.php', + 'OC\\Authentication\\Exceptions\\ExpiredTokenException' => __DIR__ . '/../../..' . '/lib/private/Authentication/Exceptions/ExpiredTokenException.php', 'OC\\Authentication\\Exceptions\\InvalidProviderException' => __DIR__ . '/../../..' . '/lib/private/Authentication/Exceptions/InvalidProviderException.php', 'OC\\Authentication\\Exceptions\\InvalidTokenException' => __DIR__ . '/../../..' . '/lib/private/Authentication/Exceptions/InvalidTokenException.php', 'OC\\Authentication\\Exceptions\\LoginRequiredException' => __DIR__ . '/../../..' . '/lib/private/Authentication/Exceptions/LoginRequiredException.php', @@ -501,7 +520,6 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OC\\Authentication\\Token\\DefaultTokenCleanupJob' => __DIR__ . '/../../..' . '/lib/private/Authentication/Token/DefaultTokenCleanupJob.php', 'OC\\Authentication\\Token\\DefaultTokenMapper' => __DIR__ . '/../../..' . '/lib/private/Authentication/Token/DefaultTokenMapper.php', 'OC\\Authentication\\Token\\DefaultTokenProvider' => __DIR__ . '/../../..' . '/lib/private/Authentication/Token/DefaultTokenProvider.php', - 'OC\\Authentication\\Token\\ExpiredTokenException' => __DIR__ . '/../../..' . '/lib/private/Authentication/Exceptions/ExpiredTokenException.php', 'OC\\Authentication\\Token\\IProvider' => __DIR__ . '/../../..' . '/lib/private/Authentication/Token/IProvider.php', 'OC\\Authentication\\Token\\IToken' => __DIR__ . '/../../..' . '/lib/private/Authentication/Token/IToken.php', 'OC\\Authentication\\Token\\Manager' => __DIR__ . '/../../..' . '/lib/private/Authentication/Token/Manager.php', @@ -569,6 +587,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OC\\Core\\Command\\App\\GetPath' => __DIR__ . '/../../..' . '/core/Command/App/GetPath.php', 'OC\\Core\\Command\\App\\Install' => __DIR__ . '/../../..' . '/core/Command/App/Install.php', 'OC\\Core\\Command\\App\\ListApps' => __DIR__ . '/../../..' . '/core/Command/App/ListApps.php', + 'OC\\Core\\Command\\App\\Remove' => __DIR__ . '/../../..' . '/core/Command/App/Remove.php', 'OC\\Core\\Command\\Background\\Ajax' => __DIR__ . '/../../..' . '/core/Command/Background/Ajax.php', 'OC\\Core\\Command\\Background\\Base' => __DIR__ . '/../../..' . '/core/Command/Background/Base.php', 'OC\\Core\\Command\\Background\\Cron' => __DIR__ . '/../../..' . '/core/Command/Background/Cron.php', @@ -681,6 +700,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OC\\Core\\Migrations\\Version14000Date20180710092004' => __DIR__ . '/../../..' . '/core/Migrations/Version14000Date20180710092004.php', 'OC\\Core\\Migrations\\Version14000Date20180712153140' => __DIR__ . '/../../..' . '/core/Migrations/Version14000Date20180712153140.php', 'OC\\Core\\Migrations\\Version15000Date20180926101451' => __DIR__ . '/../../..' . '/core/Migrations/Version15000Date20180926101451.php', + 'OC\\Core\\Migrations\\Version15000Date20181015062942' => __DIR__ . '/../../..' . '/core/Migrations/Version15000Date20181015062942.php', 'OC\\DB\\Adapter' => __DIR__ . '/../../..' . '/lib/private/DB/Adapter.php', 'OC\\DB\\AdapterMySQL' => __DIR__ . '/../../..' . '/lib/private/DB/AdapterMySQL.php', 'OC\\DB\\AdapterOCI8' => __DIR__ . '/../../..' . '/lib/private/DB/AdapterOCI8.php', @@ -832,6 +852,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OC\\Files\\Storage\\Wrapper\\PermissionsMask' => __DIR__ . '/../../..' . '/lib/private/Files/Storage/Wrapper/PermissionsMask.php', 'OC\\Files\\Storage\\Wrapper\\Quota' => __DIR__ . '/../../..' . '/lib/private/Files/Storage/Wrapper/Quota.php', 'OC\\Files\\Storage\\Wrapper\\Wrapper' => __DIR__ . '/../../..' . '/lib/private/Files/Storage/Wrapper/Wrapper.php', + 'OC\\Files\\Stream\\CountReadStream' => __DIR__ . '/../../..' . '/lib/private/Files/Stream/CountReadStream.php', 'OC\\Files\\Stream\\Encryption' => __DIR__ . '/../../..' . '/lib/private/Files/Stream/Encryption.php', 'OC\\Files\\Stream\\Quota' => __DIR__ . '/../../..' . '/lib/private/Files/Stream/Quota.php', 'OC\\Files\\Type\\Detection' => __DIR__ . '/../../..' . '/lib/private/Files/Type/Detection.php', @@ -840,6 +861,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OC\\Files\\Utils\\Scanner' => __DIR__ . '/../../..' . '/lib/private/Files/Utils/Scanner.php', 'OC\\Files\\View' => __DIR__ . '/../../..' . '/lib/private/Files/View.php', 'OC\\ForbiddenException' => __DIR__ . '/../../..' . '/lib/private/ForbiddenException.php', + 'OC\\FullTextSearch\\FullTextSearchManager' => __DIR__ . '/../../..' . '/lib/private/FullTextSearch/FullTextSearchManager.php', 'OC\\GlobalScale\\Config' => __DIR__ . '/../../..' . '/lib/private/GlobalScale/Config.php', 'OC\\Group\\Backend' => __DIR__ . '/../../..' . '/lib/private/Group/Backend.php', 'OC\\Group\\Database' => __DIR__ . '/../../..' . '/lib/private/Group/Database.php', diff --git a/lib/private/AppFramework/Http/Request.php b/lib/private/AppFramework/Http/Request.php index 0485d178b49..2c745973ed2 100644 --- a/lib/private/AppFramework/Http/Request.php +++ b/lib/private/AppFramework/Http/Request.php @@ -320,14 +320,18 @@ class Request implements \ArrayAccess, \Countable, IRequest { // There's a few headers that seem to end up in the top-level // server array. - switch($name) { + switch ($name) { case 'CONTENT_TYPE' : case 'CONTENT_LENGTH' : if (isset($this->server[$name])) { return $this->server[$name]; } break; - + case 'REMOTE_ADDR' : + if (isset($this->server[$name])) { + return $this->server[$name]; + } + break; } return ''; @@ -595,6 +599,44 @@ class Request implements \ArrayAccess, \Countable, IRequest { } /** + * Checks if given $remoteAddress matches given $trustedProxy. + * If $trustedProxy is an IPv4 IP range given in CIDR notation, true will be returned if + * $remoteAddress is an IPv4 address within that IP range. + * Otherwise $remoteAddress will be compared to $trustedProxy literally and the result + * will be returned. + * @return boolean true if $remoteAddress matches $trustedProxy, false otherwise + */ + protected function matchesTrustedProxy($trustedProxy, $remoteAddress) { + $cidrre = '/^([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})\/([0-9]{1,2})$/'; + + if (preg_match($cidrre, $trustedProxy, $match)) { + $net = $match[1]; + $shiftbits = min(32, max(0, 32 - intval($match[2]))); + $netnum = ip2long($net) >> $shiftbits; + $ipnum = ip2long($remoteAddress) >> $shiftbits; + + return $ipnum === $netnum; + } + + return $trustedProxy === $remoteAddress; + } + + /** + * Checks if given $remoteAddress matches any entry in the given array $trustedProxies. + * For details regarding what "match" means, refer to `matchesTrustedProxy`. + * @return boolean true if $remoteAddress matches any entry in $trustedProxies, false otherwise + */ + protected function isTrustedProxy($trustedProxies, $remoteAddress) { + foreach ($trustedProxies as $tp) { + if ($this->matchesTrustedProxy($tp, $remoteAddress)) { + return true; + } + } + + return false; + } + + /** * Returns the remote address, if the connection came from a trusted proxy * and `forwarded_for_headers` has been configured then the IP address * specified in this header will be returned instead. @@ -605,7 +647,7 @@ class Request implements \ArrayAccess, \Countable, IRequest { $remoteAddress = isset($this->server['REMOTE_ADDR']) ? $this->server['REMOTE_ADDR'] : ''; $trustedProxies = $this->config->getSystemValue('trusted_proxies', []); - if(\is_array($trustedProxies) && \in_array($remoteAddress, $trustedProxies)) { + if(\is_array($trustedProxies) && $this->isTrustedProxy($trustedProxies, $remoteAddress)) { $forwardedForHeaders = $this->config->getSystemValue('forwarded_for_headers', [ 'HTTP_X_FORWARDED_FOR' // only have one default, so we cannot ship an insecure product out of the box diff --git a/lib/private/AppFramework/Middleware/Security/PasswordConfirmationMiddleware.php b/lib/private/AppFramework/Middleware/Security/PasswordConfirmationMiddleware.php index 463e7cd93c9..7c1c4595e9a 100644 --- a/lib/private/AppFramework/Middleware/Security/PasswordConfirmationMiddleware.php +++ b/lib/private/AppFramework/Middleware/Security/PasswordConfirmationMiddleware.php @@ -39,6 +39,8 @@ class PasswordConfirmationMiddleware extends Middleware { private $userSession; /** @var ITimeFactory */ private $timeFactory; + /** @var array */ + private $excludedUserBackEnds = ['user_saml' => true, 'user_globalsiteselector' => true]; /** * PasswordConfirmationMiddleware constructor. @@ -73,7 +75,7 @@ class PasswordConfirmationMiddleware extends Middleware { $lastConfirm = (int) $this->session->get('last-password-confirm'); // we can't check the password against a SAML backend, so skip password confirmation in this case - if ($backendClassName !== 'user_saml' && $lastConfirm < ($this->timeFactory->getTime() - (30 * 60 + 15))) { // allow 15 seconds delay + if (!isset($this->excludedUserBackEnds[$backendClassName]) && $lastConfirm < ($this->timeFactory->getTime() - (30 * 60 + 15))) { // allow 15 seconds delay throw new NotConfirmedException(); } } diff --git a/lib/private/Authentication/Exceptions/ExpiredTokenException.php b/lib/private/Authentication/Exceptions/ExpiredTokenException.php index a45ca5b6955..d5b2e2cbca7 100644 --- a/lib/private/Authentication/Exceptions/ExpiredTokenException.php +++ b/lib/private/Authentication/Exceptions/ExpiredTokenException.php @@ -21,9 +21,9 @@ declare(strict_types=1); * along with this program. If not, see <http://www.gnu.org/licenses/>. * */ -namespace OC\Authentication\Token; +namespace OC\Authentication\Exceptions; -use OC\Authentication\Exceptions\InvalidTokenException; +use OC\Authentication\Token\IToken; class ExpiredTokenException extends InvalidTokenException { /** @var IToken */ diff --git a/lib/private/Authentication/Token/DefaultTokenProvider.php b/lib/private/Authentication/Token/DefaultTokenProvider.php index a27a875a27f..98609a3f14b 100644 --- a/lib/private/Authentication/Token/DefaultTokenProvider.php +++ b/lib/private/Authentication/Token/DefaultTokenProvider.php @@ -29,6 +29,7 @@ declare(strict_types=1); namespace OC\Authentication\Token; use Exception; +use OC\Authentication\Exceptions\ExpiredTokenException; use OC\Authentication\Exceptions\InvalidTokenException; use OC\Authentication\Exceptions\PasswordlessTokenException; use OCP\AppFramework\Db\DoesNotExistException; diff --git a/lib/private/Authentication/Token/IProvider.php b/lib/private/Authentication/Token/IProvider.php index 7ee76b7b384..21223cecdf7 100644 --- a/lib/private/Authentication/Token/IProvider.php +++ b/lib/private/Authentication/Token/IProvider.php @@ -26,6 +26,7 @@ declare(strict_types=1); namespace OC\Authentication\Token; +use OC\Authentication\Exceptions\ExpiredTokenException; use OC\Authentication\Exceptions\InvalidTokenException; use OC\Authentication\Exceptions\PasswordlessTokenException; diff --git a/lib/private/Authentication/Token/Manager.php b/lib/private/Authentication/Token/Manager.php index 98a48f41523..3174599221d 100644 --- a/lib/private/Authentication/Token/Manager.php +++ b/lib/private/Authentication/Token/Manager.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace OC\Authentication\Token; +use OC\Authentication\Exceptions\ExpiredTokenException; use OC\Authentication\Exceptions\InvalidTokenException; use OC\Authentication\Exceptions\PasswordlessTokenException; diff --git a/lib/private/Authentication/Token/PublicKeyTokenProvider.php b/lib/private/Authentication/Token/PublicKeyTokenProvider.php index 33c0b1d59eb..9f596ac4568 100644 --- a/lib/private/Authentication/Token/PublicKeyTokenProvider.php +++ b/lib/private/Authentication/Token/PublicKeyTokenProvider.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace OC\Authentication\Token; +use OC\Authentication\Exceptions\ExpiredTokenException; use OC\Authentication\Exceptions\InvalidTokenException; use OC\Authentication\Exceptions\PasswordlessTokenException; use OCP\AppFramework\Db\DoesNotExistException; diff --git a/lib/private/Collaboration/Collaborators/MailPlugin.php b/lib/private/Collaboration/Collaborators/MailPlugin.php index 101d6845ec3..6faa5d5d125 100644 --- a/lib/private/Collaboration/Collaborators/MailPlugin.php +++ b/lib/private/Collaboration/Collaborators/MailPlugin.php @@ -84,11 +84,17 @@ class MailPlugin implements ISearchPlugin { foreach ($addressBookContacts as $contact) { if (isset($contact['EMAIL'])) { $emailAddresses = $contact['EMAIL']; - if (!is_array($emailAddresses)) { + if (\is_string($emailAddresses)) { $emailAddresses = [$emailAddresses]; } - foreach ($emailAddresses as $emailAddress) { + foreach ($emailAddresses as $type => $emailAddress) { $displayName = $emailAddress; + $emailAddressType = null; + if (\is_array($emailAddress)) { + $emailAddressData = $emailAddress; + $emailAddress = $emailAddressData['value']; + $emailAddressType = $emailAddressData['type']; + } if (isset($contact['FN'])) { $displayName = $contact['FN'] . ' (' . $emailAddress . ')'; } @@ -121,6 +127,8 @@ class MailPlugin implements ISearchPlugin { if (!$this->isCurrentUser($cloud) && !$searchResult->hasResult($userType, $cloud->getUser())) { $singleResult = [[ 'label' => $displayName, + 'uuid' => $contact['UID'], + 'name' => $contact['FN'], 'value' => [ 'shareType' => Share::SHARE_TYPE_USER, 'shareWith' => $cloud->getUser(), @@ -142,6 +150,8 @@ class MailPlugin implements ISearchPlugin { if (!$this->isCurrentUser($cloud) && !$searchResult->hasResult($userType, $cloud->getUser())) { $userResults['wide'][] = [ 'label' => $displayName, + 'uuid' => $contact['UID'], + 'name' => $contact['FN'], 'value' => [ 'shareType' => Share::SHARE_TYPE_USER, 'shareWith' => $cloud->getUser(), @@ -160,6 +170,9 @@ class MailPlugin implements ISearchPlugin { } $result['exact'][] = [ 'label' => $displayName, + 'uuid' => $contact['UID'], + 'name' => $contact['FN'], + 'type' => $emailAddressType ?? '', 'value' => [ 'shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => $emailAddress, @@ -168,6 +181,9 @@ class MailPlugin implements ISearchPlugin { } else { $result['wide'][] = [ 'label' => $displayName, + 'uuid' => $contact['UID'], + 'name' => $contact['FN'], + 'type' => $emailAddressType ?? '', 'value' => [ 'shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => $emailAddress, @@ -194,6 +210,7 @@ class MailPlugin implements ISearchPlugin { if (!$searchResult->hasExactIdMatch($emailType) && filter_var($search, FILTER_VALIDATE_EMAIL)) { $result['exact'][] = [ 'label' => $search, + 'uuid' => $search, 'value' => [ 'shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => $search, diff --git a/lib/private/Collaboration/Collaborators/RemotePlugin.php b/lib/private/Collaboration/Collaborators/RemotePlugin.php index e0f5298f83b..d877346b155 100644 --- a/lib/private/Collaboration/Collaborators/RemotePlugin.php +++ b/lib/private/Collaboration/Collaborators/RemotePlugin.php @@ -30,6 +30,8 @@ use OCP\Collaboration\Collaborators\SearchResultType; use OCP\Contacts\IManager; use OCP\Federation\ICloudIdManager; use OCP\IConfig; +use OCP\IUserManager; +use OCP\IUserSession; use OCP\Share; class RemotePlugin implements ISearchPlugin { @@ -41,12 +43,20 @@ class RemotePlugin implements ISearchPlugin { private $cloudIdManager; /** @var IConfig */ private $config; + /** @var IUserManager */ + private $userManager; + /** @var string */ + private $userId = ''; - public function __construct(IManager $contactsManager, ICloudIdManager $cloudIdManager, IConfig $config) { + public function __construct(IManager $contactsManager, ICloudIdManager $cloudIdManager, IConfig $config, IUserManager $userManager, IUserSession $userSession) { $this->contactsManager = $contactsManager; $this->cloudIdManager = $cloudIdManager; $this->config = $config; - + $this->userManager = $userManager; + $user = $userSession->getUser(); + if ($user !== null) { + $this->userId = $user->getUID(); + } $this->shareeEnumeration = $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes'; } @@ -63,23 +73,47 @@ class RemotePlugin implements ISearchPlugin { } if (isset($contact['CLOUD'])) { $cloudIds = $contact['CLOUD']; - if (!is_array($cloudIds)) { + if (is_string($cloudIds)) { $cloudIds = [$cloudIds]; } $lowerSearch = strtolower($search); foreach ($cloudIds as $cloudId) { + $cloudIdType = ''; + if (\is_array($cloudId)) { + $cloudIdData = $cloudId; + $cloudId = $cloudIdData['value']; + $cloudIdType = $cloudIdData['type']; + } try { - list(, $serverUrl) = $this->splitUserRemote($cloudId); + list($remoteUser, $serverUrl) = $this->splitUserRemote($cloudId); } catch (\InvalidArgumentException $e) { continue; } + $localUser = $this->userManager->get($remoteUser); + /** + * Add local share if remote cloud id matches a local user ones + */ + if ($localUser !== null && $remoteUser !== $this->userId && $cloudId === $localUser->getCloudId() ) { + $result['wide'][] = [ + 'label' => $contact['FN'], + 'uuid' => $contact['UID'], + 'value' => [ + 'shareType' => Share::SHARE_TYPE_USER, + 'shareWith' => $remoteUser + ] + ]; + } + if (strtolower($contact['FN']) === $lowerSearch || strtolower($cloudId) === $lowerSearch) { if (strtolower($cloudId) === $lowerSearch) { $searchResult->markExactIdMatch($resultType); } $result['exact'][] = [ 'label' => $contact['FN'] . " ($cloudId)", + 'uuid' => $contact['UID'], + 'name' => $contact['FN'], + 'type' => $cloudIdType, 'value' => [ 'shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => $cloudId, @@ -89,6 +123,9 @@ class RemotePlugin implements ISearchPlugin { } else { $result['wide'][] = [ 'label' => $contact['FN'] . " ($cloudId)", + 'uuid' => $contact['UID'], + 'name' => $contact['FN'], + 'type' => $cloudIdType, 'value' => [ 'shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => $cloudId, @@ -106,14 +143,24 @@ class RemotePlugin implements ISearchPlugin { $result['wide'] = array_slice($result['wide'], $offset, $limit); } + /** + * Add generic share with remote item for valid cloud ids that are not users of the local instance + */ if (!$searchResult->hasExactIdMatch($resultType) && $this->cloudIdManager->isValidCloudId($search) && $offset === 0) { - $result['exact'][] = [ - 'label' => $search, - 'value' => [ - 'shareType' => Share::SHARE_TYPE_REMOTE, - 'shareWith' => $search, - ], - ]; + try { + list($remoteUser, $serverUrl) = $this->splitUserRemote($search); + $localUser = $this->userManager->get($remoteUser); + if ($localUser === null || $search !== $localUser->getCloudId()) { + $result['exact'][] = [ + 'label' => $search, + 'value' => [ + 'shareType' => Share::SHARE_TYPE_REMOTE, + 'shareWith' => $search, + ], + ]; + } + } catch (\InvalidArgumentException $e) { + } } $searchResult->addResultSet($resultType, $result['wide'], $result['exact']); diff --git a/lib/private/Files/FileInfo.php b/lib/private/Files/FileInfo.php index 53f73f0f95d..575af56ceb5 100644 --- a/lib/private/Files/FileInfo.php +++ b/lib/private/Files/FileInfo.php @@ -390,4 +390,8 @@ class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess { public function getChecksum() { return $this->data['checksum']; } + + public function getExtension(): string { + return pathinfo($this->getName(), PATHINFO_EXTENSION); + } } diff --git a/lib/private/Files/Node/File.php b/lib/private/Files/Node/File.php index 7c411620ca0..a3eabbcc446 100644 --- a/lib/private/Files/Node/File.php +++ b/lib/private/Files/Node/File.php @@ -142,4 +142,8 @@ class File extends Node implements \OCP\Files\File { public function getChecksum() { return $this->getFileInfo()->getChecksum(); } + + public function getExtension(): string { + return $this->getFileInfo()->getExtension(); + } } diff --git a/lib/private/Files/Node/LazyRoot.php b/lib/private/Files/Node/LazyRoot.php index faa57ecb0b4..389a1a9f0ff 100644 --- a/lib/private/Files/Node/LazyRoot.php +++ b/lib/private/Files/Node/LazyRoot.php @@ -344,6 +344,10 @@ class LazyRoot implements IRootFolder { return $this->__call(__FUNCTION__, func_get_args()); } + public function getExtension(): string { + return $this->__call(__FUNCTION__, func_get_args()); + } + /** * @inheritDoc */ diff --git a/lib/private/Files/Node/Node.php b/lib/private/Files/Node/Node.php index d2232624b9b..590f1080617 100644 --- a/lib/private/Files/Node/Node.php +++ b/lib/private/Files/Node/Node.php @@ -354,6 +354,10 @@ class Node implements \OCP\Files\Node { public function getChecksum() { } + public function getExtension(): string { + return $this->getFileInfo()->getExtension(); + } + /** * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE * @throws \OCP\Lock\LockedException diff --git a/lib/private/Files/ObjectStore/ObjectStoreStorage.php b/lib/private/Files/ObjectStore/ObjectStoreStorage.php index 3ce919a4cbe..71acd27783c 100644 --- a/lib/private/Files/ObjectStore/ObjectStoreStorage.php +++ b/lib/private/Files/ObjectStore/ObjectStoreStorage.php @@ -28,6 +28,7 @@ namespace OC\Files\ObjectStore; use Icewind\Streams\CallbackWrapper; use Icewind\Streams\IteratorDirectory; use OC\Files\Cache\CacheEntry; +use OC\Files\Stream\CountReadStream; use OCP\Files\ObjectStore\IObjectStore; class ObjectStoreStorage extends \OC\Files\Storage\Common { @@ -382,25 +383,48 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common { } public function writeBack($tmpFile, $path) { + $size = filesize($tmpFile); + $this->writeStream($path, fopen($tmpFile, 'r'), $size); + } + + /** + * external changes are not supported, exclusive access to the object storage is assumed + * + * @param string $path + * @param int $time + * @return false + */ + public function hasUpdated($path, $time) { + return false; + } + + public function needsPartFile() { + return false; + } + + public function file_put_contents($path, $data) { + $stream = fopen('php://temp', 'r+'); + fwrite($stream, $data); + rewind($stream); + return $this->writeStream($path, $stream, strlen($data)) > 0; + } + + public function writeStream(string $path, $stream, int $size = null): int { $stat = $this->stat($path); if (empty($stat)) { // create new file - $stat = array( + $stat = [ 'permissions' => \OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_CREATE, - ); + ]; } // update stat with new data $mTime = time(); - $stat['size'] = filesize($tmpFile); + $stat['size'] = (int)$size; $stat['mtime'] = $mTime; $stat['storage_mtime'] = $mTime; - // run path based detection first, to use file extension because $tmpFile is only a random string $mimetypeDetector = \OC::$server->getMimeTypeDetector(); $mimetype = $mimetypeDetector->detectPath($path); - if ($mimetype === 'application/octet-stream') { - $mimetype = $mimetypeDetector->detect($tmpFile); - } $stat['mimetype'] = $mimetype; $stat['etag'] = $this->getETag($path); @@ -408,7 +432,20 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common { $fileId = $this->getCache()->put($path, $stat); try { //upload to object storage - $this->objectStore->writeObject($this->getURN($fileId), fopen($tmpFile, 'r')); + if ($size === null) { + $countStream = CountReadStream::wrap($stream, function ($writtenSize) use ($fileId, &$size) { + $this->getCache()->update($fileId, [ + 'size' => $writtenSize + ]); + $size = $writtenSize; + }); + $this->objectStore->writeObject($this->getURN($fileId), $countStream); + if (is_resource($countStream)) { + fclose($countStream); + } + } else { + $this->objectStore->writeObject($this->getURN($fileId), $stream); + } } catch (\Exception $ex) { $this->getCache()->remove($path); $this->logger->logException($ex, [ @@ -417,20 +454,7 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common { ]); throw $ex; // make this bubble up } - } - /** - * external changes are not supported, exclusive access to the object storage is assumed - * - * @param string $path - * @param int $time - * @return false - */ - public function hasUpdated($path, $time) { - return false; - } - - public function needsPartFile() { - return false; + return $size; } } diff --git a/lib/private/Files/Storage/Common.php b/lib/private/Files/Storage/Common.php index b6c82f3a1df..72fe3a79792 100644 --- a/lib/private/Files/Storage/Common.php +++ b/lib/private/Files/Storage/Common.php @@ -54,6 +54,7 @@ use OCP\Files\InvalidPathException; use OCP\Files\ReservedWordException; use OCP\Files\Storage\ILockingStorage; use OCP\Files\Storage\IStorage; +use OCP\Files\Storage\IWriteStreamStorage; use OCP\ILogger; use OCP\Lock\ILockingProvider; use OCP\Lock\LockedException; @@ -69,7 +70,7 @@ use OCP\Lock\LockedException; * Some \OC\Files\Storage\Common methods call functions which are first defined * in classes which extend it, e.g. $this->stat() . */ -abstract class Common implements Storage, ILockingStorage { +abstract class Common implements Storage, ILockingStorage, IWriteStreamStorage { use LocalTempFileTrait; @@ -809,4 +810,23 @@ abstract class Common implements Storage, ILockingStorage { public function needsPartFile() { return true; } + + /** + * fallback implementation + * + * @param string $path + * @param resource $stream + * @param int $size + * @return int + */ + public function writeStream(string $path, $stream, int $size = null): int { + $target = $this->fopen($path, 'w'); + if (!$target) { + return 0; + } + list($count, $result) = \OC_Helper::streamCopy($stream, $target); + fclose($stream); + fclose($target); + return $count; + } } diff --git a/lib/private/Files/Storage/Local.php b/lib/private/Files/Storage/Local.php index 46b53dcf95c..5f7232e64b3 100644 --- a/lib/private/Files/Storage/Local.php +++ b/lib/private/Files/Storage/Local.php @@ -462,4 +462,8 @@ class Local extends \OC\Files\Storage\Common { return parent::moveFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath); } } + + public function writeStream(string $path, $stream, int $size = null): int { + return (int)file_put_contents($this->getSourcePath($path), $stream); + } } diff --git a/lib/private/Files/Storage/Wrapper/Encryption.php b/lib/private/Files/Storage/Wrapper/Encryption.php index 42653b2d4a6..e1c1225e0cc 100644 --- a/lib/private/Files/Storage/Wrapper/Encryption.php +++ b/lib/private/Files/Storage/Wrapper/Encryption.php @@ -1029,4 +1029,13 @@ class Encryption extends Wrapper { } + public function writeStream(string $path, $stream, int $size = null): int { + // always fall back to fopen + $target = $this->fopen($path, 'w'); + list($count, $result) = \OC_Helper::streamCopy($stream, $target); + fclose($stream); + fclose($target); + return $count; + } + } diff --git a/lib/private/Files/Storage/Wrapper/Jail.php b/lib/private/Files/Storage/Wrapper/Jail.php index 56514af6d80..f21b5716467 100644 --- a/lib/private/Files/Storage/Wrapper/Jail.php +++ b/lib/private/Files/Storage/Wrapper/Jail.php @@ -29,6 +29,7 @@ use OC\Files\Cache\Wrapper\CacheJail; use OC\Files\Cache\Wrapper\JailPropagator; use OC\Files\Filesystem; use OCP\Files\Storage\IStorage; +use OCP\Files\Storage\IWriteStreamStorage; use OCP\Lock\ILockingProvider; /** @@ -515,4 +516,18 @@ class Jail extends Wrapper { $this->propagator = new JailPropagator($storage, \OC::$server->getDatabaseConnection()); return $this->propagator; } + + public function writeStream(string $path, $stream, int $size = null): int { + $storage = $this->getWrapperStorage(); + if ($storage->instanceOfStorage(IWriteStreamStorage::class)) { + /** @var IWriteStreamStorage $storage */ + return $storage->writeStream($this->getUnjailedPath($path), $stream, $size); + } else { + $target = $this->fopen($path, 'w'); + list($count, $result) = \OC_Helper::streamCopy($stream, $target); + fclose($stream); + fclose($target); + return $count; + } + } } diff --git a/lib/private/Files/Storage/Wrapper/Wrapper.php b/lib/private/Files/Storage/Wrapper/Wrapper.php index 060c596ad65..f9c84b89fe5 100644 --- a/lib/private/Files/Storage/Wrapper/Wrapper.php +++ b/lib/private/Files/Storage/Wrapper/Wrapper.php @@ -32,9 +32,10 @@ namespace OC\Files\Storage\Wrapper; use OCP\Files\InvalidPathException; use OCP\Files\Storage\ILockingStorage; use OCP\Files\Storage\IStorage; +use OCP\Files\Storage\IWriteStreamStorage; use OCP\Lock\ILockingProvider; -class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { +class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage, IWriteStreamStorage { /** * @var \OC\Files\Storage\Storage $storage */ @@ -621,4 +622,18 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage { public function needsPartFile() { return $this->getWrapperStorage()->needsPartFile(); } + + public function writeStream(string $path, $stream, int $size = null): int { + $storage = $this->getWrapperStorage(); + if ($storage->instanceOfStorage(IWriteStreamStorage::class)) { + /** @var IWriteStreamStorage $storage */ + return $storage->writeStream($path, $stream, $size); + } else { + $target = $this->fopen($path, 'w'); + list($count, $result) = \OC_Helper::streamCopy($stream, $target); + fclose($stream); + fclose($target); + return $count; + } + } } diff --git a/lib/private/Files/Stream/CountReadStream.php b/lib/private/Files/Stream/CountReadStream.php new file mode 100644 index 00000000000..93cadf8f214 --- /dev/null +++ b/lib/private/Files/Stream/CountReadStream.php @@ -0,0 +1,65 @@ +<?php declare(strict_types=1); +/** + * @copyright Copyright (c) 2018 Robin Appelman <robin@icewind.nl> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OC\Files\Stream; + +use Icewind\Streams\Wrapper; + +class CountReadStream extends Wrapper { + /** @var int */ + private $count; + + /** @var callback */ + private $callback; + + public static function wrap($source, $callback) { + $context = stream_context_create(array( + 'count' => array( + 'source' => $source, + 'callback' => $callback, + ) + )); + return Wrapper::wrapSource($source, $context, 'count', self::class); + } + + public function dir_opendir($path, $options) { + return false; + } + + public function stream_open($path, $mode, $options, &$opened_path) { + $context = $this->loadContext('count'); + + $this->callback = $context['callback']; + return true; + } + + public function stream_read($count) { + $result = parent::stream_read($count); + $this->count += strlen($result); + return $result; + } + + public function stream_close() { + $result = parent::stream_close(); + call_user_func($this->callback, $this->count); + return $result; + } +} diff --git a/lib/private/FullTextSearch/FullTextSearchManager.php b/lib/private/FullTextSearch/FullTextSearchManager.php new file mode 100644 index 00000000000..9a9b077cf23 --- /dev/null +++ b/lib/private/FullTextSearch/FullTextSearchManager.php @@ -0,0 +1,227 @@ +<?php +declare(strict_types=1); + + +/** + * FullTextSearch - Full text search framework for Nextcloud + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2018, Maxence Lange <maxence@artificial-owl.com> + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OC\FullTextSearch; + + +use OCP\FullTextSearch\Exceptions\FullTextSearchAppNotAvailableException; +use OCP\FullTextSearch\IFullTextSearchManager; +use OCP\FullTextSearch\Model\IIndex; +use OCP\FullTextSearch\Model\ISearchResult; +use OCP\FullTextSearch\Service\IIndexService; +use OCP\FullTextSearch\Service\IProviderService; +use OCP\FullTextSearch\Service\ISearchService; + + +/** + * Class FullTextSearchManager + * + * @package OC\FullTextSearch + */ +class FullTextSearchManager implements IFullTextSearchManager { + + + /** @var IProviderService */ + private $providerService; + + /** @var IIndexService */ + private $indexService; + + /** @var ISearchService */ + private $searchService; + + + /** + * @since 15.0.0 + * + * @param IProviderService $providerService + */ + public function registerProviderService(IProviderService $providerService) { + $this->providerService = $providerService; + } + + /** + * @since 15.0.0 + * + * @param IIndexService $indexService + */ + public function registerIndexService(IIndexService $indexService) { + $this->indexService = $indexService; + } + + /** + * @since 15.0.0 + * + * @param ISearchService $searchService + */ + public function registerSearchService(ISearchService $searchService) { + $this->searchService = $searchService; + } + + + /** + * @return IProviderService + * @throws FullTextSearchAppNotAvailableException + */ + private function getProviderService(): IProviderService { + if ($this->providerService === null) { + throw new FullTextSearchAppNotAvailableException('No IProviderService registered'); + } + + return $this->providerService; + } + + + /** + * @return IIndexService + * @throws FullTextSearchAppNotAvailableException + */ + private function getIndexService(): IIndexService { + if ($this->indexService === null) { + throw new FullTextSearchAppNotAvailableException('No IIndexService registered'); + } + + return $this->indexService; + } + + + /** + * @return ISearchService + * @throws FullTextSearchAppNotAvailableException + */ + private function getSearchService(): ISearchService { + if ($this->searchService === null) { + throw new FullTextSearchAppNotAvailableException('No ISearchService registered'); + } + + return $this->searchService; + } + + + /** + * @throws FullTextSearchAppNotAvailableException + */ + public function addJavascriptAPI() { + $this->getProviderService()->addJavascriptAPI(); + } + + + /** + * @param string $providerId + * + * @return bool + * @throws FullTextSearchAppNotAvailableException + */ + public function isProviderIndexed(string $providerId): bool { + return $this->getProviderService()->isProviderIndexed($providerId); + } + + + /** + * @param string $providerId + * @param string $documentId + * @return IIndex + * @throws FullTextSearchAppNotAvailableException + */ + public function getIndex(string $providerId, string $documentId): IIndex { + return $this->getIndexService()->getIndex($providerId, $documentId); + } + + /** + * @param string $providerId + * @param string $documentId + * @param string $userId + * @param int $status + * + * @see IIndex for available value for $status. + * + * @return IIndex + * @throws FullTextSearchAppNotAvailableException + */ + public function createIndex(string $providerId, string $documentId, string $userId, int $status = 0): IIndex { + return $this->getIndexService()->getIndex($providerId, $documentId); + } + + + /** + * @param string $providerId + * @param string $documentId + * @param int $status + * @param bool $reset + * + * @see IIndex for available value for $status. + * + * @throws FullTextSearchAppNotAvailableException + */ + public function updateIndexStatus(string $providerId, string $documentId, int $status, bool $reset = false) { + $this->getIndexService()->updateIndexStatus($providerId, $documentId, $status, $reset); + } + + /** + * @param string $providerId + * @param array $documentIds + * @param int $status + * @param bool $reset + * + * @see IIndex for available value for $status. + * + * @throws FullTextSearchAppNotAvailableException + */ + public function updateIndexesStatus(string $providerId, array $documentIds, int $status, bool $reset = false) { + $this->getIndexService()->updateIndexesStatus($providerId, $documentIds, $status, $reset); + } + + + /** + * @param IIndex[] $indexes + * + * @throws FullTextSearchAppNotAvailableException + */ + public function updateIndexes(array $indexes) { + $this->getIndexService()->updateIndexes($indexes); + } + + + /** + * @param array $request + * @param string $userId + * + * @return ISearchResult[] + * @throws FullTextSearchAppNotAvailableException + */ + public function search(array $request, string $userId = ''): array { + $searchRequest = $this->getSearchService()->generateSearchRequest($request); + + return $this->getSearchService()->search($userId, $searchRequest); + } + + +} + diff --git a/lib/private/Preview/Generator.php b/lib/private/Preview/Generator.php index 86579e3480b..1f7decf2b79 100644 --- a/lib/private/Preview/Generator.php +++ b/lib/private/Preview/Generator.php @@ -298,19 +298,23 @@ class Generator { if ($height !== $maxHeight && $width !== $maxWidth) { /* - * Scale to the nearest power of two + * Scale to the nearest power of four */ - $pow2height = 2 ** ceil(log($height) / log(2)); - $pow2width = 2 ** ceil(log($width) / log(2)); + $pow4height = 4 ** ceil(log($height) / log(4)); + $pow4width = 4 ** ceil(log($width) / log(4)); - $ratioH = $height / $pow2height; - $ratioW = $width / $pow2width; + // Minimum size is 64 + $pow4height = max($pow4height, 64); + $pow4width = max($pow4width, 64); + + $ratioH = $height / $pow4height; + $ratioW = $width / $pow4width; if ($ratioH < $ratioW) { - $width = $pow2width; + $width = $pow4width; $height /= $ratioW; } else { - $height = $pow2height; + $height = $pow4height; $width /= $ratioH; } } diff --git a/lib/private/Server.php b/lib/private/Server.php index 32d7705919c..ceecd059df2 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -82,6 +82,7 @@ use OC\Files\Node\LazyRoot; use OC\Files\Node\Root; use OC\Files\Storage\StorageFactory; use OC\Files\View; +use OC\FullTextSearch\FullTextSearchManager; use OC\Http\Client\ClientService; use OC\IntegrityCheck\Checker; use OC\IntegrityCheck\Helpers\AppLocator; @@ -138,6 +139,7 @@ use OCP\Federation\ICloudIdManager; use OCP\Authentication\LoginCredentials\IStore; use OCP\Files\NotFoundException; use OCP\Files\Storage\IStorageFactory; +use OCP\FullTextSearch\IFullTextSearchManager; use OCP\GlobalScale\IConfig; use OCP\ICacheFactory; use OCP\IDBConnection; @@ -758,7 +760,7 @@ class Server extends ServerContainer implements IServerContainer { $this->registerService('TrustedDomainHelper', function ($c) { return new TrustedDomainHelper($this->getConfig()); }); - $this->registerService('Throttler', function (Server $c) { + $this->registerService(Throttler::class, function (Server $c) { return new Throttler( $c->getDatabaseConnection(), new TimeFactory(), @@ -766,6 +768,7 @@ class Server extends ServerContainer implements IServerContainer { $c->getConfig() ); }); + $this->registerAlias('Throttler', Throttler::class); $this->registerService('IntegrityCodeChecker', function (Server $c) { // IConfig and IAppManager requires a working database. This code // might however be called when ownCloud is not yet setup. @@ -1183,6 +1186,7 @@ class Server extends ServerContainer implements IServerContainer { }); $this->registerAlias(IDashboardManager::class, Dashboard\DashboardManager::class); + $this->registerAlias(IFullTextSearchManager::class, FullTextSearchManager::class); $this->connectDispatcher(); } diff --git a/lib/private/Share20/DefaultShareProvider.php b/lib/private/Share20/DefaultShareProvider.php index 9c5d78a5958..3dcca0facbc 100644 --- a/lib/private/Share20/DefaultShareProvider.php +++ b/lib/private/Share20/DefaultShareProvider.php @@ -296,6 +296,7 @@ class DefaultShareProvider implements IShareProvider { ->set('token', $qb->createNamedParameter($share->getToken())) ->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE)) ->set('note', $qb->createNamedParameter($share->getNote())) + ->set('hide_download', $qb->createNamedParameter($share->getHideDownload() ? 1 : 0), IQueryBuilder::PARAM_INT) ->execute(); } @@ -953,6 +954,7 @@ class DefaultShareProvider implements IShareProvider { } $share->setProviderId($this->identifier()); + $share->setHideDownload((int)$data['hide_download'] === 1); return $share; } diff --git a/lib/private/Share20/Share.php b/lib/private/Share20/Share.php index 71c0453d9e5..e218360f87b 100644 --- a/lib/private/Share20/Share.php +++ b/lib/private/Share20/Share.php @@ -30,6 +30,7 @@ use OCP\Files\Node; use OCP\Files\NotFoundException; use OCP\IUserManager; use OCP\Share\Exceptions\IllegalIDChangeException; +use OCP\Share\IShare; class Share implements \OCP\Share\IShare { @@ -85,6 +86,9 @@ class Share implements \OCP\Share\IShare { /** @var ICacheEntry|null */ private $nodeCacheEntry; + /** @var bool */ + private $hideDownload = false; + public function __construct(IRootFolder $rootFolder, IUserManager $userManager) { $this->rootFolder = $rootFolder; $this->userManager = $userManager; @@ -514,4 +518,13 @@ class Share implements \OCP\Share\IShare { public function getNodeCacheEntry() { return $this->nodeCacheEntry; } + + public function setHideDownload(bool $hide): IShare { + $this->hideDownload = $hide; + return $this; + } + + public function getHideDownload(): bool { + return $this->hideDownload; + } } diff --git a/lib/private/Template/IconsCacher.php b/lib/private/Template/IconsCacher.php index c1a78a567f9..c91bf13ad53 100644 --- a/lib/private/Template/IconsCacher.php +++ b/lib/private/Template/IconsCacher.php @@ -47,7 +47,7 @@ class IconsCacher { protected $urlGenerator; /** @var string */ - private $iconVarRE = '/--(icon-[a-zA-Z0-9-]+):\s?url\(["\']?([a-zA-Z0-9-_\~\/\.\?\=\:\;\+\,]+)[^;]+;/m'; + private $iconVarRE = '/--(icon-[a-zA-Z0-9-]+):\s?url\(["\']?([a-zA-Z0-9-_\~\/\.\?\&\=\:\;\+\,]+)[^;]+;/m'; /** @var string */ private $fileName = 'icons-vars.css'; @@ -112,7 +112,10 @@ class IconsCacher { foreach ($icons as $icon => $url) { $list .= "--$icon: url('$url');"; list($location,$color) = $this->parseUrl($url); - $svg = file_get_contents($location); + $svg = false; + if ($location !== '') { + $svg = file_get_contents($location); + } if ($svg === false) { $this->logger->debug('Failed to get icon file ' . $location); $data .= "--$icon: url('$url');"; @@ -142,21 +145,20 @@ class IconsCacher { $base = $this->getRoutePrefix() . '/svg/'; $cleanUrl = \substr($url, \strlen($base)); if (\strpos($url, $base . 'core') === 0) { - $cleanUrl = \substr($cleanUrl, \strlen('core'), \strpos($cleanUrl, '?')-\strlen('core')); - $parts = \explode('/', $cleanUrl); - $color = \array_pop($parts); - $cleanUrl = \implode('/', $parts); - $location = \OC::$SERVERROOT . '/core/img/' . $cleanUrl . '.svg'; + $cleanUrl = \substr($cleanUrl, \strlen('core')); + if (\preg_match('/\/([a-zA-Z0-9-_\~\/\.\=\:\;\+\,]+)\?color=([0-9a-fA-F]{3,6})/', $cleanUrl, $matches)) { + list(,$cleanUrl,$color) = $matches; + $location = \OC::$SERVERROOT . '/core/img/' . $cleanUrl . '.svg'; + } } elseif (\strpos($url, $base) === 0) { - $cleanUrl = \substr($cleanUrl, 0, \strpos($cleanUrl, '?')); - $parts = \explode('/', $cleanUrl); - $app = \array_shift($parts); - $color = \array_pop($parts); - $cleanUrl = \implode('/', $parts); - $location = \OC_App::getAppPath($app) . '/img/' . $cleanUrl . '.svg'; - if ($app === 'settings') { - $location = \OC::$SERVERROOT . '/settings/img/' . $cleanUrl . '.svg'; + if(\preg_match('/([A-z0-9\_\-]+)\/([a-zA-Z0-9-_\~\/\.\=\:\;\+\,]+)\?color=([0-9a-fA-F]{3,6})/', $cleanUrl, $matches)) { + list(,$app,$cleanUrl, $color) = $matches; + $location = \OC_App::getAppPath($app) . '/img/' . $cleanUrl . '.svg'; + if ($app === 'settings') { + $location = \OC::$SERVERROOT . '/settings/img/' . $cleanUrl . '.svg'; + } } + } return [ $location, diff --git a/lib/private/Template/JSConfigHelper.php b/lib/private/Template/JSConfigHelper.php index b691a8a64cb..ad9ff0b6757 100644 --- a/lib/private/Template/JSConfigHelper.php +++ b/lib/private/Template/JSConfigHelper.php @@ -70,6 +70,9 @@ class JSConfigHelper { /** @var CapabilitiesManager */ private $capabilitiesManager; + /** @var array user back-ends excluded from password verification */ + private $excludedUserBackEnds = ['user_saml' => true, 'user_globalsiteselector' => true]; + /** * @param IL10N $l * @param Defaults $defaults @@ -158,7 +161,7 @@ class JSConfigHelper { $array = [ "oc_debug" => $this->config->getSystemValue('debug', false) ? 'true' : 'false', "oc_isadmin" => $this->groupManager->isAdmin($uid) ? 'true' : 'false', - "backendAllowsPasswordConfirmation" => $userBackend === 'user_saml'? 'false' : 'true', + "backendAllowsPasswordConfirmation" => !isset($this->excludedUserBackEnds[$userBackend]) ? 'true' : 'false', "oc_dataURL" => is_string($dataLocation) ? "\"".$dataLocation."\"" : 'false', "oc_webroot" => "\"".\OC::$WEBROOT."\"", "oc_appswebroots" => str_replace('\\/', '/', json_encode($apps_paths)), // Ugly unescape slashes waiting for better solution diff --git a/lib/private/User/Session.php b/lib/private/User/Session.php index a9c638dca93..674f38e2401 100644 --- a/lib/private/User/Session.php +++ b/lib/private/User/Session.php @@ -38,6 +38,7 @@ namespace OC\User; use OC; +use OC\Authentication\Exceptions\ExpiredTokenException; use OC\Authentication\Exceptions\InvalidTokenException; use OC\Authentication\Exceptions\PasswordlessTokenException; use OC\Authentication\Exceptions\PasswordLoginForbiddenException; @@ -401,7 +402,13 @@ class Session implements IUserSession, Emitter { $this->manager->emit('\OC\User', 'preLogin', array($user, $password)); } - $isTokenPassword = $this->isTokenPassword($password); + try { + $isTokenPassword = $this->isTokenPassword($password); + } catch (ExpiredTokenException $e) { + // Just return on an expired token no need to check further or record a failed login + return false; + } + if (!$isTokenPassword && $this->isTokenAuthEnforced()) { throw new PasswordLoginForbiddenException(); } @@ -474,11 +481,14 @@ class Session implements IUserSession, Emitter { * * @param string $password * @return boolean + * @throws ExpiredTokenException */ public function isTokenPassword($password) { try { $this->tokenProvider->getToken($password); return true; + } catch (ExpiredTokenException $e) { + throw $e; } catch (InvalidTokenException $ex) { return false; } diff --git a/lib/public/Files/File.php b/lib/public/Files/File.php index ad2cb7b55c2..29a83b4df7d 100644 --- a/lib/public/Files/File.php +++ b/lib/public/Files/File.php @@ -96,4 +96,12 @@ interface File extends Node { * @throws NotFoundException */ public function getChecksum(); + + /** + * Get the extension of this file + * + * @return string + * @since 15.0.0 + */ + public function getExtension(): string; } diff --git a/lib/public/Files/FileInfo.php b/lib/public/Files/FileInfo.php index 1fe71b356c5..e25a47e83cd 100644 --- a/lib/public/Files/FileInfo.php +++ b/lib/public/Files/FileInfo.php @@ -259,4 +259,12 @@ interface FileInfo { * @since 9.0.0 */ public function getChecksum(); + + /** + * Get the extension of the file + * + * @return string + * @since 15.0.0 + */ + public function getExtension(): string; } diff --git a/lib/public/Files/Storage/IWriteStreamStorage.php b/lib/public/Files/Storage/IWriteStreamStorage.php new file mode 100644 index 00000000000..39a28dd037b --- /dev/null +++ b/lib/public/Files/Storage/IWriteStreamStorage.php @@ -0,0 +1,40 @@ +<?php declare(strict_types=1); +/** + * @copyright Copyright (c) 2018 Robin Appelman <robin@icewind.nl> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCP\Files\Storage; + +/** + * Interface that adds the ability to write a stream directly to file + * + * @since 15.0.0 + */ +interface IWriteStreamStorage extends IStorage { + /** + * Write the data from a stream to a file + * + * @param string $path + * @param resource $stream + * @param int|null $size the size of the stream if known in advance + * @return int the number of bytes written + * @since 15.0.0 + */ + public function writeStream(string $path, $stream, int $size = null): int; +} diff --git a/lib/public/Files_FullTextSearch/Model/AFilesDocument.php b/lib/public/Files_FullTextSearch/Model/AFilesDocument.php new file mode 100644 index 00000000000..3eed956df84 --- /dev/null +++ b/lib/public/Files_FullTextSearch/Model/AFilesDocument.php @@ -0,0 +1,112 @@ +<?php +declare(strict_types=1); + + +/** + * Files_FullTextSearch - Index the content of your files + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2018 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCP\Files_FullTextSearch\Model; + + +use OCP\FullTextSearch\Model\IndexDocument; + + +/** + * Abstract Class AFilesDocument + * + * This is mostly used by 3rd party apps that want to complete the IndexDocument + * with more information about a file before its index: + * + * \OC::$server->getEventDispatcher()->addListener( + * '\OCA\Files_FullTextSearch::onFileIndexing', + * function(GenericEvent $e) { + * //@var \OCP\Files\Node $file + * $file = $e->getArgument('file'); + * + * // @var \OCP\Files_FullTextSearch\Model\AFilesDocument $document + * $document = $e->getArgument('document'); + * + * } + * ); + * + * @since 15.0.0 + * + * @package OCP\Files_FullTextSearch\Model + */ +abstract class AFilesDocument extends IndexDocument { + + + /** + * Returns the owner of the document/file. + * + * @since 15.0.0 + * + * @return string + */ + abstract public function getOwnerId(): string; + + + /** + * Returns the current viewer of the document/file. + * + * @since 15.0.0 + * + * @return string + */ + abstract public function getViewerId(): string; + + + /** + * Returns the type of the document/file. + * + * @since 15.0.0 + * + * @return string \OCP\Files\FileInfo::TYPE_FILE|\OCP\Files\FileInfo::TYPE_FOLDER + */ + abstract public function getType(): string; + + + /** + * Returns the mimetype of the document/file. + * + * @since 15.0.0 + * + * @return string + */ + abstract public function getMimetype(): string; + + /** + * Returns the path of the document/file. + * + * @since 15.0.0 + * + * @return string + */ + abstract public function getPath(): string; + + +} + diff --git a/lib/public/FullTextSearch/Exceptions/FullTextSearchAppNotAvailableException.php b/lib/public/FullTextSearch/Exceptions/FullTextSearchAppNotAvailableException.php new file mode 100644 index 00000000000..4363376f0f4 --- /dev/null +++ b/lib/public/FullTextSearch/Exceptions/FullTextSearchAppNotAvailableException.php @@ -0,0 +1,42 @@ +<?php +declare(strict_types=1); + + +/** + * FullTextSearch - Full text search framework for Nextcloud + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2018, Maxence Lange <maxence@artificial-owl.com> + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCP\FullTextSearch\Exceptions; + +/** + * @since 15.0.0 + * + * Class FullTextSearchAppNotAvailableException + * + * @package OCP\FullTextSearch\Exceptions + */ +class FullTextSearchAppNotAvailableException extends \Exception { +} + diff --git a/lib/public/FullTextSearch/IFullTextSearchManager.php b/lib/public/FullTextSearch/IFullTextSearchManager.php new file mode 100644 index 00000000000..1027f7ade75 --- /dev/null +++ b/lib/public/FullTextSearch/IFullTextSearchManager.php @@ -0,0 +1,186 @@ +<?php +declare(strict_types=1); + + +/** + * FullTextSearch - Full text search framework for Nextcloud + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2018, Maxence Lange <maxence@artificial-owl.com> + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCP\FullTextSearch; + + +use OCP\FullTextSearch\Model\IIndex; +use OCP\FullTextSearch\Model\ISearchResult; +use OCP\FullTextSearch\Service\IIndexService; +use OCP\FullTextSearch\Service\IProviderService; +use OCP\FullTextSearch\Service\ISearchService; + + +/** + * Interface IFullTextSearchManager + * + * Should be used to manage FullTextSearch from the app that contains your + * Content Provider/Search Platform. + * + * @since 15.0.0 + * + * @package OCP\FullTextSearch + */ +interface IFullTextSearchManager { + + + /** + * Register a IProviderService. + * + * @since 15.0.0 + * + * @param IProviderService $providerService + */ + public function registerProviderService(IProviderService $providerService); + + /** + * Register a IIndexService. + * + * @since 15.0.0 + * + * @param IIndexService $indexService + */ + public function registerIndexService(IIndexService $indexService); + + /** + * Register a ISearchService. + * + * @since 15.0.0 + * + * @param ISearchService $searchService + */ + public function registerSearchService(ISearchService $searchService); + + + /** + * Add the Javascript API in the navigation page of an app. + * Needed to replace the default search. + * + * @since 15.0.0 + */ + public function addJavascriptAPI(); + + + /** + * Check if the provider $providerId is already indexed. + * + * @since 15.0.0 + * + * @param string $providerId + * + * @return bool + */ + public function isProviderIndexed(string $providerId): bool; + + + /** + * Retrieve an Index from the database, based on the Id of the Provider + * and the Id of the Document + * + * @since 15.0.0 + * + * @param string $providerId + * @param string $documentId + * + * @return IIndex + */ + public function getIndex(string $providerId, string $documentId): IIndex; + + + /** + * Create a new Index. + * + * This method must be called when a new document is created. + * + * @since 15.0.0 + * + * @param string $providerId + * @param string $documentId + * @param string $userId + * @param int $status + * + * @return IIndex + */ + public function createIndex(string $providerId, string $documentId, string $userId, int $status = 0): IIndex; + + + /** + * Update the status of an Index. status is a bitflag, setting $reset to + * true will reset the status to the value defined in the parameter. + * + * @since 15.0.0 + * + * @param string $providerId + * @param string $documentId + * @param int $status + * @param bool $reset + */ + public function updateIndexStatus(string $providerId, string $documentId, int $status, bool $reset = false); + + + /** + * Update the status of an array of Index. status is a bit flag, setting $reset to + * true will reset the status to the value defined in the parameter. + * + * @since 15.0.0 + * + * @param string $providerId + * @param array $documentIds + * @param int $status + * @param bool $reset + */ + public function updateIndexesStatus(string $providerId, array $documentIds, int $status, bool $reset = false); + + /** + * Update an array of Index. + * + * @since 15.0.0 + * + * @param IIndex[] $indexes + */ + public function updateIndexes(array $indexes); + + /** + * Search using an array as request. If $userId is empty, will use the + * current session. + * + * @see ISearchService::generateSearchRequest + * + * @since 15.0.0 + * + * @param array $request + * @param string $userId + * @return ISearchResult[] + */ + public function search(array $request, string $userId = ''): array; + + +} + diff --git a/lib/public/FullTextSearch/IFullTextSearchPlatform.php b/lib/public/FullTextSearch/IFullTextSearchPlatform.php new file mode 100644 index 00000000000..f3f9a35bae2 --- /dev/null +++ b/lib/public/FullTextSearch/IFullTextSearchPlatform.php @@ -0,0 +1,227 @@ +<?php +declare(strict_types=1); + + +/** + * FullTextSearch - Full text search framework for Nextcloud + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2018 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCP\FullTextSearch; + + +use OCP\FullTextSearch\Model\DocumentAccess; +use OCP\FullTextSearch\Model\IIndex; +use OCP\FullTextSearch\Model\IndexDocument; +use OCP\FullTextSearch\Model\IRunner; +use OCP\FullTextSearch\Model\ISearchResult; + + +/** + * Interface IFullTextSearchPlatform + * + * This interface must be use when creating a Search Platform for FullTextSearch. + * + * A Search Platform is an extension to the FullTextSearch that will act as a + * a gateway between FullTextSearch and a search server (ie. ElasticSearch, + * Solr, ...) + * + * Multiple Search Platform can exist at the same time in Nextcloud, however only + * one Search Platform will be used by FullTextSearch. + * Administrator must select at least one Search Platform to be used by + * FullTextSearch in the admin settings page. + * + * The content provided by FullTextSearch comes in chunk from multiple Content + * Provider. Each chunk is identified by the ID of the Content Provider, and the + * ID of the document. + * + * + * To oversimplify the mechanism: + * + * - When indexing, FullTextSearch will send providerId, documentId, content. + * - When searching within the content of a Content Provider, identified by its + * providerId, FullTextSearch expect documentId as result. + * + * + * The Search Platform ia a PHP class that implement this interface and is defined + * in appinfo/info.xml of the app that contains that class: + * + * <fulltextsearch> + * <platform>OCA\YourApp\YourSearchPlatform</platform> + * </fulltextsearch> + * + * Multiple Search Platform can be defined in a single app. + * + * @since 15.0.0 + * + * @package OCP\FullTextSearch + */ +interface IFullTextSearchPlatform { + + + /** + * Must returns a unique Id used to identify the Search Platform. + * Id must contains only alphanumeric chars, with no space. + * + * @since 15.0.0 + * + * @return string + */ + public function getId(): string; + + + /** + * Must returns a descriptive name of the Search Platform. + * This is used mainly in the admin settings page to display the list of + * available Search Platform + * + * @since 15.0.0 + * + * @return string + */ + public function getName(): string; + + + /** + * should returns the current configuration of the Search Platform. + * This is used to display the configuration when using the + * ./occ fulltextsearch:check command line. + * + * @since 15.0.0 + * + * @return array + */ + public function getConfiguration(): array; + + + /** + * Set the wrapper of the currently executed process. + * Because the index process can be long and heavy, and because errors can + * be encountered during the process, the IRunner is a wrapper that allow the + * Search Platform to communicate with the process initiated by + * FullTextSearch. + * + * The IRunner is coming with some methods so the Search Platform can + * returns important information and errors to be displayed to the admin. + * + * @since 15.0.0 + * + * @param IRunner $runner + */ + public function setRunner(IRunner $runner); + + + /** + * Called when FullTextSearch is loading your Search Platform. + * + * @since 15.0.0 + */ + public function loadPlatform(); + + + /** + * Called to check that your Search Platform is correctly configured and that + * This is also the right place to check that the Search Service is available. + * + * @since 15.0.0 + * + * @return bool + */ + public function testPlatform(): bool; + + + /** + * Called before an index is initiated. + * Best place to initiate some stuff on the Search Server (mapping, ...) + * + * @since 15.0.0 + */ + public function initializeIndex(); + + + /** + * Reset the indexes for a specific providerId. + * $providerId can be 'all' if it is a global reset. + * + * @since 15.0.0 + * + * @param string $providerId + */ + public function resetIndex(string $providerId); + + + /** + * Deleting some IIndex, sent in an array + * + * @see IIndex + * + * @since 15.0.0 + * + * @param IIndex[] $indexes + */ + public function deleteIndexes(array $indexes); + + + /** + * Indexing a document. + * + * @see IndexDocument + * + * @since 15.0.0 + * + * @param IndexDocument $document + * + * @return IIndex + */ + public function indexDocument(IndexDocument $document): IIndex; + + + /** + * Searching documents, ISearchResult should be updated with the result of + * the search. + * + * @since 15.0.0 + * + * @param ISearchResult $result + * @param DocumentAccess $access + */ + public function searchRequest(ISearchResult $result, DocumentAccess $access); + + + /** + * Return a document based on its Id and the Provider. + * This is used when an admin execute ./occ fulltextsearch:document:platform + * + * @since 15.0.0 + * + * @param string $providerId + * @param string $documentId + * + * @return IndexDocument + */ + public function getDocument(string $providerId, string $documentId): IndexDocument; + + +} + diff --git a/lib/public/FullTextSearch/IFullTextSearchProvider.php b/lib/public/FullTextSearch/IFullTextSearchProvider.php new file mode 100644 index 00000000000..890b57d84c9 --- /dev/null +++ b/lib/public/FullTextSearch/IFullTextSearchProvider.php @@ -0,0 +1,304 @@ +<?php +declare(strict_types=1); + + +/** + * FullTextSearch - Full text search framework for Nextcloud + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2018 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCP\FullTextSearch; + + +use OCP\FullTextSearch\Model\IIndex; +use OCP\FullTextSearch\Model\IIndexOptions; +use OCP\FullTextSearch\Model\IndexDocument; +use OCP\FullTextSearch\Model\IRunner; +use OCP\FullTextSearch\Model\ISearchRequest; +use OCP\FullTextSearch\Model\ISearchResult; +use OCP\FullTextSearch\Model\SearchTemplate; + + +/** + * Interface IFullTextSearchProvider + * + * This interface must be use when creating a Content Provider for FullTextSearch. + * + * A Content Provider is an extension to the FullTextSearch that will extract and + * provide content to the FullTextSearch. + * + * There is no limit to the number of Content Provider that can be integrated to + * FullTextSearch. Each Content Provider corresponding to a type of content + * available in Nextcloud (files, bookmarks, notes, deck cards, mails, ...) + * + * Content is split in document identified by an ID and the ID of the Content + * Provider. The content is indexed by a Search Platform that will returns a + * documentId as a result on a search request. + * + * + * To oversimplify the mechanism: + * + * - When indexing, FullTextSearch will ask for documents to every Content Provider. + * - On search, results from the Search Platform, identified by documentId, will + * be improved by each relative Content Provider. + * + * + * The Content Provider is a PHP class that implement this interface and is defined + * in appinfo/info.xml of the app that contains that class: + * + * <fulltextsearch> + * <provider>OCA\YourApp\YourContentProvider</provider> + * </fulltextsearch> + * + * Multiple Content Provider can be defined in a single app. + * + * @since 15.0.0 + * + * @package OCP\FullTextSearch + */ +interface IFullTextSearchProvider { + + + /** + * Must returns a unique Id used to identify the Content Provider. + * Id must contains only alphanumeric chars, with no space. + * + * @since 15.0.0 + * + * @return string + */ + public function getId(): string; + + + /** + * Must returns a descriptive name of the Content Provider. + * This is used in multiple places, so better use a clear display name. + * + * @since 15.0.0 + * + * @return string + */ + public function getName(): string; + + + /** + * Should returns the current configuration of the Content Provider. + * This is used to display the configuration when using the + * ./occ fulltextsearch:check command line. + * + * @since 15.0.0 + * + * @return array + */ + public function getConfiguration(): array; + + + /** + * Must returns a SearchTemplate that contains displayable items and + * available options to users when searching. + * + * @see SearchTemplate + * + * @since 15.0.0 + * + * @return SearchTemplate + */ + public function getSearchTemplate(): SearchTemplate; + + + /** + * Called when FullTextSearch is loading your Content Provider. + * + * @since 15.0.0 + */ + public function loadProvider(); + + + /** + * Set the wrapper of the currently executed process. + * Because the index process can be long and heavy, and because errors can + * be encountered during the process, the IRunner is a wrapper that allow the + * Content Provider to communicate with the process initiated by + * FullTextSearch. + * + * The IRunner is coming with some methods so the Content Provider can + * returns important information and errors to be displayed to the admin. + * + * @since 15.0.0 + * + * @param IRunner $runner + */ + public function setRunner(IRunner $runner); + + + /** + * This method is called when the administrator specify options when running + * the ./occ fulltextsearch:index or ./occ fulltextsearch:live + * + * @since 15.0.0 + * + * @param IIndexOptions $options + */ + public function setIndexOptions(IIndexOptions $options); + + + /** + * Returns all indexable document for a user as an array of IndexDocument. + * + * There is no need to fill each IndexDocument with content; at this point, + * only fill the object with the minimum information to not waste memory while + * still being able to identify the document it is referring to. + * + * FullTextSearch will call 2 other methods of this interface for each + * IndexDocument of the array, prior to their indexing: + * + * - first, to compare the date of the last index, + * - then, to fill each IndexDocument with complete data + * + * @see IndexDocument + * + * @since 15.0.0 + * + * @param string $userId + * + * @return IndexDocument[] + */ + public function generateIndexableDocuments(string $userId): array; + + + /** + * Called to verify that the document is not already indexed and that the + * old index is not up-to-date, using the IIndex from + * IndexDocument->getIndex() + * + * Returning true will not queue the current IndexDocument to any further + * operation and will continue on the next element from the list returned by + * generateIndexableDocuments(). + * + * @since 15.0.0 + * + * @param IndexDocument $document + * + * @return bool + */ + public function isDocumentUpToDate(IndexDocument $document): bool; + + + /** + * Must fill IndexDocument with all information relative to the document, + * before its indexing by the Search Platform. + * + * Method is called for each element returned previously by + * generateIndexableDocuments(). + * + * @see IndexDocument + * + * @since 15.0.0 + * + * @param IndexDocument $document + */ + public function fillIndexDocument(IndexDocument $document); + + + /** + * The Search Provider must create and return an IndexDocument + * based on the IIndex and its status. The IndexDocument must contains all + * information as it will be send for indexing. + * + * Method is called during a cron or a ./occ fulltextsearch:live after a + * new document is created, or an old document is set as modified. + * + * @since 15.0.0 + * + * @param IIndex $index + * + * @return IndexDocument + */ + public function updateDocument(IIndex $index): IndexDocument; + + + /** + * Called when an index is initiated by the administrator. + * This is should only be used in case of a specific mapping is needed. + * (ie. _almost_ never) + * + * @since 15.0.0 + * + * @param IFullTextSearchPlatform $platform + */ + public function onInitializingIndex(IFullTextSearchPlatform $platform); + + + /** + * Called when administrator is resetting the index. + * This is should only be used in case of a specific mapping has been + * created. + * + * @since 15.0.0 + * + * @param IFullTextSearchPlatform $platform + */ + public function onResettingIndex(IFullTextSearchPlatform $platform); + + + /** + * Method is called when a search request is initiated by a user, prior to + * be sent to the Search Platform. + * + * Your Content Provider can interact with the ISearchRequest to apply the + * search options and make the search more precise. + * + * @see ISearchRequest + * + * @since 15.0.0 + * + * @param ISearchRequest $searchRequest + */ + public function improveSearchRequest(ISearchRequest $searchRequest); + + + /** + * Method is called after results of a search are returned by the + * Search Platform. + * + * Your Content Provider can detail each entry with local data to improve + * the display of the search result. + * + * @see ISearchResult + * + * @since 15.0.0 + * + * @param ISearchResult $searchResult + */ + public function improveSearchResult(ISearchResult $searchResult); + + + /** + * not used yet. + * + * @since 15.0.0 + */ + public function unloadProvider(); + +} diff --git a/lib/public/FullTextSearch/Model/DocumentAccess.php b/lib/public/FullTextSearch/Model/DocumentAccess.php new file mode 100644 index 00000000000..ef199fb7385 --- /dev/null +++ b/lib/public/FullTextSearch/Model/DocumentAccess.php @@ -0,0 +1,363 @@ +<?php +declare(strict_types=1); + + +/** + * FullTextSearch - Full text search framework for Nextcloud + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2018 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCP\FullTextSearch\Model; + + +use JsonSerializable; + + +/** + * Class DocumentAccess + * + * This object is used as a data transfer object when + * + * - indexing a document, + * - generating a search request. + * + * During the index, it is used to define which users, groups, circles, ... + * have access to the IndexDocument + * + * During the search, it is internally use to define to which group, circles, ... + * a user that perform the search belongs to. + * + * @see IndexDocument::setAccess + * + * @since 15.0.0 + * + * @package OCP\FullTextSearch\Model + */ +final class DocumentAccess implements JsonSerializable { + + /** @var string */ + private $ownerId; + + /** @var string */ + private $viewerId = ''; + + /** @var array */ + private $users = []; + + /** @var array */ + private $groups = []; + + /** @var array */ + private $circles = []; + + /** @var array */ + private $links = []; + + + /** + * Owner of the document can be set at the init of the object. + * + * @since 15.0.0 + * + * DocumentAccess constructor. + * + * @param string $ownerId + */ + public function __construct(string $ownerId = '') { + $this->setOwnerId($ownerId); + } + + + /** + * Set the Owner of the document. + * + * @since 15.0.0 + * + * @param string $ownerId + * + * @return DocumentAccess + */ + public function setOwnerId(string $ownerId) { + $this->ownerId = $ownerId; + + return $this; + } + + /** + * Get the Owner of the document. + * + * @since 15.0.0 + * + * @return string + */ + public function getOwnerId(): string { + return $this->ownerId; + } + + + /** + * Set the viewer of the document. + * + * @since 15.0.0 + * + * @param string $viewerId + * + * @return DocumentAccess + */ + public function setViewerId(string $viewerId): DocumentAccess { + $this->viewerId = $viewerId; + + return $this; + } + + /** + * Get the viewer of the document. + * + * @since 15.0.0 + * + * @return string + */ + public function getViewerId(): string { + return $this->viewerId; + } + + + /** + * Set the list of users that have read access to the document. + * + * @since 15.0.0 + * + * @param array $users + * + * @return DocumentAccess + */ + public function setUsers(array $users): DocumentAccess { + $this->users = $users; + + return $this; + } + + /** + * Add an entry to the list of users that have read access to the document. + * + * @since 15.0.0 + * + * @param string $user + * + * @return DocumentAccess + */ + public function addUser(string $user): DocumentAccess { + $this->users[] = $user; + + return $this; + } + + /** + * Add multiple entries to the list of users that have read access to the + * document. + * + * @since 15.0.0 + * + * @param array $users + * + * @return DocumentAccess + */ + public function addUsers($users): DocumentAccess { + $this->users = array_merge($this->users, $users); + + return $this; + } + + /** + * Get the complete list of users that have read access to the document. + * + * @since 15.0.0 + * + * @return array + */ + public function getUsers(): array { + return $this->users; + } + + + /** + * Set the list of groups that have read access to the document. + * + * @since 15.0.0 + * + * @param array $groups + * + * @return DocumentAccess + */ + public function setGroups(array $groups): DocumentAccess { + $this->groups = $groups; + + return $this; + } + + /** + * Add an entry to the list of groups that have read access to the document. + * + * @since 15.0.0 + * + * @param string $group + * + * @return DocumentAccess + */ + public function addGroup(string $group): DocumentAccess { + $this->groups[] = $group; + + return $this; + } + + /** + * Add multiple entries to the list of groups that have read access to the + * document. + * + * @since 15.0.0 + * + * @param array $groups + * + * @return DocumentAccess + */ + public function addGroups(array $groups) { + $this->groups = array_merge($this->groups, $groups); + + return $this; + } + + /** + * Get the complete list of groups that have read access to the document. + * + * @since 15.0.0 + * + * @return array + */ + public function getGroups(): array { + return $this->groups; + } + + + /** + * Set the list of circles that have read access to the document. + * + * @since 15.0.0 + * + * @param array $circles + * + * @return DocumentAccess + */ + public function setCircles(array $circles): DocumentAccess { + $this->circles = $circles; + + return $this; + } + + /** + * Add an entry to the list of circles that have read access to the document. + * + * @since 15.0.0 + * + * @param string $circle + * + * @return DocumentAccess + */ + public function addCircle(string $circle): DocumentAccess { + $this->circles[] = $circle; + + return $this; + } + + /** + * Add multiple entries to the list of groups that have read access to the + * document. + * + * @since 15.0.0 + * + * @param array $circles + * + * @return DocumentAccess + */ + public function addCircles(array $circles): DocumentAccess { + $this->circles = array_merge($this->circles, $circles); + + return $this; + } + + /** + * Get the complete list of circles that have read access to the document. + * + * @since 15.0.0 + * + * @return array + */ + public function getCircles(): array { + return $this->circles; + } + + + /** + * Set the list of links that have read access to the document. + * + * @since 15.0.0 + * + * @param array $links + * + * @return DocumentAccess + */ + public function setLinks(array $links): DocumentAccess { + $this->links = $links; + + return $this; + } + + /** + * Get the list of links that have read access to the document. + * + * @since 15.0.0 + * + * @return array + */ + public function getLinks(): array { + return $this->links; + } + + + /** + * @since 15.0.0 + * + * @return array + */ + public function jsonSerialize(): array { + return [ + 'ownerId' => $this->getOwnerId(), + 'viewerId' => $this->getViewerId(), + 'users' => $this->getUsers(), + 'groups' => $this->getGroups(), + 'circles' => $this->getCircles(), + 'links' => $this->getLinks() + ]; + } +} + diff --git a/lib/public/FullTextSearch/Model/IIndex.php b/lib/public/FullTextSearch/Model/IIndex.php new file mode 100644 index 00000000000..adfdf34aee6 --- /dev/null +++ b/lib/public/FullTextSearch/Model/IIndex.php @@ -0,0 +1,292 @@ +<?php +declare(strict_types=1); + + +/** + * FullTextSearch - Full text search framework for extcloud + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2018 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCP\FullTextSearch\Model; + + +/** + * Interface IIndex + * + * Index are generated by FullTextSearch to manage the status of a document + * regarding the date of the last index and the date of the last modification + * of the original document. + * + * The uniqueness of an IndexDocument is made by the Id of the Content Provider + * and the Id of the original document within the Content Provider. + * + * We will call original document the source from which the IndexDocument is + * generated. As an example, an original document can be a file, a mail, ... + * + * @since 15.0.0 + * + * @package OCP\FullTextSearch\Model + */ +interface IIndex { + + + const INDEX_OK = 1; + const INDEX_IGNORE = 2; + + const INDEX_META = 4; + const INDEX_CONTENT = 8; + const INDEX_FULL = 12; + const INDEX_REMOVE = 16; + + const INDEX_DONE = 32; + const INDEX_FAILED = 64; + + const ERROR_FAILED = 1; + const ERROR_FAILED2 = 2; + const ERROR_FAILED3 = 4; + + const ERROR_SEV_1 = 1; + const ERROR_SEV_2 = 2; + const ERROR_SEV_3 = 3; + const ERROR_SEV_4 = 4; + + + /** + * Get the Id of the Content Provider. + * + * @since 15.0.0 + * + * @return string + */ + public function getProviderId(): string; + + + /** + * Get the Id of the original document. + * + * @since 15.0.0 + * + * @return string + */ + public function getDocumentId(): string; + + + /** + * Set the source of the original document. + * + * @since 15.0.0 + * + * @param string $source + * + * @return IIndex + */ + public function setSource(string $source): IIndex; + + /** + * Get the source of the original document. + * + * @since 15.0.0 + * + * @return string + */ + public function getSource(): string; + + + /** + * Set the owner of the original document. + * + * @since 15.0.0 + * + * @param string $ownerId + * + * @return IIndex + */ + public function setOwnerId(string $ownerId): IIndex; + + /** + * Get the owner of the original document. + * + * @since 15.0.0 + * + * @return string + */ + public function getOwnerId(): string; + + + /** + * Set the current index status (bit flag) of the original document. + * If $reset is true, the status is reset to the defined value. + * + * @since 15.0.0 + * + * @param int $status + * @param bool $reset + * + * @return IIndex + */ + public function setStatus(int $status, bool $reset = false): IIndex; + + /** + * Get the current index status of the original document. + * + * @since 15.0.0 + * + * @return int + */ + public function getStatus(): int; + + /** + * Check if the document fit a specific status. + * + * @since 15.0.0 + * + * @param int $status + * + * @return bool + */ + public function isStatus(int $status): bool; + + /** + * Remove a status. + * + * @since 15.0.0 + * + * @param int $status + * + * @return IIndex + */ + public function unsetStatus(int $status): IIndex; + + + /** + * Add an option related to the original document (as string). + * + * @since 15.0.0 + * + * @param string $option + * @param string|int $value + * + * @return IIndex + */ + public function addOption(string $option, string $value): IIndex; + + /** + * Add an option related to the original document (as integer). + * + * @since 15.0.0 + * + * @param string $option + * @param int $value + * + * @return IIndex + */ + public function addOptionInt(string $option, int $value): IIndex; + + /** + * Get the option related to the original document (as string). + * + * @since 15.0.0 + * + * @param string $option + * @param string $default + * + * @return string + */ + public function getOption(string $option, string $default = ''): string; + + /** + * Get the option related to the original document (as integer). + * + * @since 15.0.0 + * + * @param string $option + * @param int $default + * + * @return int + */ + public function getOptionInt(string $option, int $default = 0): int; + + /** + * Get all options related to the original document. + * + * @since 15.0.0 + * + * @return array + */ + public function getOptions(): array; + + + /** + * Add an error log related to the Index. + * + * @since 15.0.0 + * + * @param string $message + * @param string $exception + * @param int $sev + * + * @return IIndex + */ + public function addError(string $message, string $exception = '', int $sev = self::ERROR_SEV_3): IIndex; + + /** + * Returns the number of known errors related to the Index. + * + * @since 15.0.0 + * + * @return int + */ + public function getErrorCount(): int; + + /** + * Reset all error logs related to the Index. + * + * @since 15.0.0 + */ + public function resetErrors(): IIndex; + + + /** + * Set the date of the last index. + * + * @since 15.0.0 + * + * @param int $lastIndex + * + * @return IIndex + */ + public function setLastIndex(int $lastIndex = -1): IIndex; + + /** + * Get the date of the last index. + * + * @since 15.0.0 + * + * @return int + */ + public function getLastIndex(): int; + + +} + diff --git a/lib/public/FullTextSearch/Model/IIndexOptions.php b/lib/public/FullTextSearch/Model/IIndexOptions.php new file mode 100644 index 00000000000..8cc5da13d4d --- /dev/null +++ b/lib/public/FullTextSearch/Model/IIndexOptions.php @@ -0,0 +1,86 @@ +<?php +declare(strict_types=1); + + +/** + * FullTextSearch - Full text search framework for Nextcloud + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2018 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCP\FullTextSearch\Model; + + +/** + * Interface IIndexOptions + * + * IndexOptions are created in FullTextSearch when an admin initiate an index + * from the command line: + * + * ./occ fulltextsearch:index "{\"option1\": \"value\", \"option2\": true}" + * + * @since 15.0.0 + * + * @package OCP\FullTextSearch\Model + */ +interface IIndexOptions { + + + /** + * Get the value (as a string) for an option. + * + * @since 15.0.0 + * + * @param string $option + * @param string $default + * + * @return string + */ + public function getOption(string $option, string $default = ''): string; + + /** + * Get the value (as an array) for an option. + * + * @since 15.0.0 + * + * @param string $option + * @param array $default + * + * @return array + */ + public function getOptionArray(string $option, array $default = []): array; + + /** + * Get the value (as an boolean) for an option. + * + * @since 15.0.0 + * + * @param string $option + * @param bool $default + * + * @return bool + */ + public function getOptionBool(string $option, bool $default): bool; + +} + diff --git a/lib/public/FullTextSearch/Model/IRunner.php b/lib/public/FullTextSearch/Model/IRunner.php new file mode 100644 index 00000000000..0dff82bd5a0 --- /dev/null +++ b/lib/public/FullTextSearch/Model/IRunner.php @@ -0,0 +1,142 @@ +<?php +declare(strict_types=1); + + +/** + * FullTextSearch - Full text search framework for Nextcloud + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2018 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCP\FullTextSearch\Model; + + +/** + * Interface IRunner + * + * The indexing process can be long and heavy, and because errors can + * be encountered the process is wrapped using this interface. + * It allows the any extension of FullTextSearch to communicate with the process. + * + * The IRunner is coming with some methods so the Search Platform can + * returns important information and errors to be displayed to the admin. + * + * @since 15.0.0 + * + * @package OCP\FullTextSearch\Model + */ +interface IRunner { + + + const RESULT_TYPE_SUCCESS = 1; + const RESULT_TYPE_WARNING = 4; + const RESULT_TYPE_FAIL = 9; + + + /** + * Info are displayed in the user interface when an admin execute the + * ./occ fulltextsearch:index command. + * + * quick list of info that can be edited: + * 'documentId', 'info', 'title', 'resultIndex', 'resultStatus', + * 'content', 'documentCurrent', 'documentTotal', 'progressStatus', + * 'errorCurrent', 'errorException', 'errorIndex'. + * + * List of all editable info can be find in the Command\Index.php of the + * FullTextSearch app. + * (look for a comment 'full list of info that can be edited') + * + * @since 15.0.0 + * + * @param string $info + * @param string $value + */ + public function setInfo(string $info, string $value); + + + /** + * This method should be used when editing multiple info to avoid too many + * refresh of the interface. + * + * @since 15.0.0 + * + * @param array $data + */ + public function setInfoArray(array $data); + + + /** + * Method used to update the current Action when an index is running. + * + * This method should be used instead of manually update the 'action' using + * setInfo()/setInfoArray() as it is also used to keep the process alive, + * manage the input, and some statistics of the load of the process. + * + * $action is a string with no space + * $force should be set to true if the action is heavy while being executed + * multiple times + * + * @since 15.0.0 + * + * @param string $action + * @param bool $force + * + * @return string + * @throws \Exception + */ + public function updateAction(string $action = '', bool $force = false): string; + + + /** + * Call this method in a Search Platform or Content Provider if there is an + * issue while generating a document or while indexing the current document. + * This is used to store and display errors in the UI during an index to help + * admin to keep track of errors. + * + * @since 15.0.0 + * + * @param IIndex $index + * @param string $message + * @param string $class + * @param int $sev + */ + public function newIndexError(IIndex $index, string $message, string $class = '', int $sev = 3); + + + /** + * Call this method only in a Search Platform after an index of a document. + * This is used to store and display results (good or bad) in the UI during + * an index to help admin to keep track of fail and successful indexes. + * + * @since 15.0.0 + * + * @param IIndex $index + * @param string $message + * @param string $status + * @param int $type + */ + public function newIndexResult(IIndex $index, string $message, string $status, int $type); + + +} + diff --git a/lib/public/FullTextSearch/Model/ISearchRequest.php b/lib/public/FullTextSearch/Model/ISearchRequest.php new file mode 100644 index 00000000000..073b4805f63 --- /dev/null +++ b/lib/public/FullTextSearch/Model/ISearchRequest.php @@ -0,0 +1,326 @@ +<?php +declare(strict_types=1); + + +/** + * FullTextSearch - Full text search framework for Nextcloud + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2018 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCP\FullTextSearch\Model; + + +/** + * Interface ISearchRequest + * + * When a search request is initiated, from a request from the front-end or using + * the IFullTextSearchManager::search() method, FullTextSearch will create a + * SearchRequest object, based on this interface. + * + * The object will be passed to the targeted Content Provider so it can convert + * search options using available method. + * + * The object is then encapsulated in a SearchResult and send to the + * Search Platform. + * + * @since 15.0.0 + * + * + * @package OCP\FullTextSearch\Model + */ +interface ISearchRequest { + + + /** + * Get the maximum number of results to be returns by the Search Platform. + * + * @since 15.0.0 + * + * @return int + */ + public function getSize(): int; + + + /** + * Get the current page. + * Used by pagination. + * + * @since 15.0.0 + * + * @return int + */ + public function getPage(): int; + + + /** + * Get the author of the request. + * + * @since 15.0.0 + * + * @return string + */ + public function getAuthor(): string; + + /** + * Get the searched string. + * + * @since 15.0.0 + * + * @return string + */ + public function getSearch(): string; + + + /** + * Get the value of an option (as string). + * + * @since 15.0.0 + * + * @param string $option + * @param string $default + * + * @return string + */ + public function getOption(string $option, string $default = ''): string; + + /** + * Get the value of an option (as array). + * + * @since 15.0.0 + * + * @param string $option + * @param array $default + * + * @return array + */ + public function getOptionArray(string $option, array $default = []): array; + + + /** + * Limit the search to a part of the document. + * + * @since 15.0.0 + * + * @param string $part + * + * @return ISearchRequest + */ + public function addPart(string $part): ISearchRequest; + + /** + * Limit the search to an array of parts of the document. + * + * @since 15.0.0 + * + * @param array $parts + * + * @return ISearchRequest + */ + public function setParts(array $parts): ISearchRequest; + + /** + * Get the parts the search is limited to. + * + * @since 15.0.0 + * + * @return array + */ + public function getParts(): array; + + + /** + * Limit the search to a specific meta tag. + * + * @since 15.0.0 + * + * @param string $tag + * + * @return ISearchRequest + */ + public function addMetaTag(string $tag): ISearchRequest; + + /** + * Get the meta tags the search is limited to. + * + * @since 15.0.0 + * + * @return array + */ + public function getMetaTags(): array; + + /** + * Limit the search to an array of meta tags. + * + * @since 15.0.0 + * + * @param array $tags + * + * @return ISearchRequest + */ + public function setMetaTags(array $tags): IsearchRequest; + + + /** + * Limit the search to a specific sub tag. + * + * @since 15.0.0 + * + * @param string $source + * @param string $tag + * + * @return ISearchRequest + */ + public function addSubTag(string $source, string $tag): ISearchRequest; + + /** + * Get the sub tags the search is limited to. + * + * @since 15.0.0 + * + * @param bool $formatted + * + * @return array + */ + public function getSubTags(bool $formatted): array; + + /** + * Limit the search to an array of sub tags. + * + * @since 15.0.0 + * + * @param array $tags + * + * @return ISearchRequest + */ + public function setSubTags(array $tags): ISearchRequest; + + + /** + * Limit the search to a specific field of the mapping, using a full string. + * + * @since 15.0.0 + * + * @param string $field + * + * @return ISearchRequest + */ + public function addLimitField(string $field): ISearchRequest; + + /** + * Get the fields the search is limited to. + * + * @since 15.0.0 + * + * @return array + */ + public function getLimitFields(): array; + + + /** + * Limit the search to a specific field of the mapping, using a wildcard on + * the search string. + * + * @since 15.0.0 + * + * @param string $field + * + * @return ISearchRequest + */ + public function addWildcardField(string $field): ISearchRequest; + + /** + * Get the limit to field of the mapping. + * + * @since 15.0.0 + * + * @return array + */ + public function getWildcardFields(): array; + + + /** + * Filter the results, based on a group of field, using regex + * + * @since 15.0.0 + * + * @param array $filters + * + * @return ISearchRequest + */ + public function addRegexFilters(array $filters): ISearchRequest; + + /** + * Get the regex filters the search is limit to. + * + * @since 15.0.0 + * + * @return array + */ + public function getRegexFilters(): array; + + + /** + * Filter the results, based on a group of field, using wildcard + * + * @since 15.0.0 + * + * @param array $filter + * + * @return ISearchRequest + */ + public function addWildcardFilter(array $filter): ISearchRequest; + + /** + * Get the wildcard filters the search is limit to. + * + * @since 15.0.0 + * + * @return array + */ + public function getWildcardFilters(): array; + + + /** + * Add an extra field to the search. + * + * @since 15.0.0 + * + * @param string $field + * + * @return ISearchRequest + */ + public function addField(string $field): ISearchRequest; + + /** + * Get the list of extra field to search into. + * + * @since 15.0.0 + * + * @return array + */ + public function getFields(): array; + + +} + diff --git a/lib/public/FullTextSearch/Model/ISearchResult.php b/lib/public/FullTextSearch/Model/ISearchResult.php new file mode 100644 index 00000000000..a7dcba82f5c --- /dev/null +++ b/lib/public/FullTextSearch/Model/ISearchResult.php @@ -0,0 +1,198 @@ +<?php +declare(strict_types=1); + + +/** + * FullTextSearch - Full text search framework for Nextcloud + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2018 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCP\FullTextSearch\Model; + + +use OCP\FullTextSearch\IFullTextSearchProvider; + + +/** + * Interface ISearchResult + * + * When a search request is initiated, FullTextSearch will create a SearchResult + * object, based on this interface, containing the SearchRequest and the targeted + * Content Provider. + * + * The object will be passed to the Search Platform, which will proceed to the + * search and fill the SearchResult object with results. + * + * Then, the object will be passed to the targeted Content Provider that will + * improve the Search Results with detailed informations. + * + * Finally, the SearchResult is returned to the original search request. + * + * @since 15.0.0 + * + * @package OCP\FullTextSearch\Model + */ +interface ISearchResult { + + + /** + * Get the original SearchRequest. + * + * @see ISearchRequest + * + * @since 15.0.0 + * + * @return ISearchRequest + */ + public function getRequest(): ISearchRequest; + + /** + * Get the targeted Content Provider. + * + * @since 15.0.0 + * + * @return IFullTextSearchProvider + */ + public function getProvider(): IFullTextSearchProvider; + + + /** + * Add an IndexDocument as one of the result of the search request. + * + * @since 15.0.0 + * + * @param IndexDocument $document + * + * @return ISearchResult + */ + public function addDocument(IndexDocument $document): ISearchResult; + + /** + * Returns all result of the search request, in an array of IndexDocument. + * + * @since 15.0.0 + * + * @return array + */ + public function getDocuments(): array; + + /** + * Set an array of IndexDocument as the result of the search request. + * + * @since 15.0.0 + * + * @param IndexDocument[] $documents + * + * @return ISearchResult + */ + public function setDocuments(array $documents): ISearchResult; + + + /** + * Add an aggregation to the result. + * + * @since 15.0.0 + * + * @param string $category + * @param string $value + * @param int $count + * + * @return ISearchResult + */ + public function addAggregation(string $category, string $value, int $count): ISearchResult; + + /** + * Get all aggregations. + * + * @since 15.0.0 + * + * @param string $category + * + * @return array + */ + public function getAggregations(string $category): array; + + + /** + * Set the raw result of the request. + * + * @since 15.0.0 + * + * @param string $result + * + * @return ISearchResult + */ + public function setRawResult(string $result): ISearchResult; + + + /** + * Set the total number of results for the search request. + * Used by pagination. + * + * @since 15.0.0 + * + * @param int $total + * + * @return ISearchResult + */ + public function setTotal(int $total): ISearchResult; + + + /** + * Set the top score for the search request. + * + * @since 15.0.0 + * + * @param int $score + * + * @return ISearchResult + */ + public function setMaxScore(int $score): ISearchResult; + + + /** + * Set the time spent by the request to perform the search. + * + * @since 15.0.0 + * + * @param int $time + * + * @return ISearchResult + */ + public function setTime(int $time): ISearchResult; + + + /** + * Set to true if the request timed out. + * + * @since 15.0.0 + * + * @param bool $timedOut + * + * @return ISearchResult + */ + public function setTimedOut(bool $timedOut): ISearchResult; + +} + diff --git a/lib/public/FullTextSearch/Model/IndexDocument.php b/lib/public/FullTextSearch/Model/IndexDocument.php new file mode 100644 index 00000000000..a73b702e506 --- /dev/null +++ b/lib/public/FullTextSearch/Model/IndexDocument.php @@ -0,0 +1,898 @@ +<?php +declare(strict_types=1); + + +/** + * FullTextSearch - Full text search framework for Nextcloud + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2018 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCP\FullTextSearch\Model; + + +use JsonSerializable; + +/** + * Class IndexDocument + * + * This is one of the main class of the FullTextSearch, used as a data transfer + * object. An IndexDocument is created to manage documents around FullTextSearch, + * during an index and during a search. + * The uniqueness of an IndexDocument is made by the Id of the Content Provider + * and the Id of the original document within the Content Provider. + * + * We will call original document the source from which the IndexDocument is + * generated. As an example, an original document can be a file, a mail, ... + * + * @since 15.0.0 + * + * @package OC\FullTextSearch\Model + */ +class IndexDocument implements JsonSerializable { + + + const NOT_ENCODED = 0; + const ENCODED_BASE64 = 1; + + + /** @var string */ + protected $id; + + /** @var string */ + protected $providerId; + + /** @var DocumentAccess */ + protected $access; + + /** @var IIndex */ + protected $index; + + /** @var int */ + protected $modifiedTime = 0; + + /** @var string */ + protected $source = ''; + + /** @var array */ + protected $tags = []; + + /** @var array */ + protected $metaTags = []; + + /** @var array */ + protected $subTags = []; + + /** @var string */ + protected $title = ''; + + /** @var string */ + protected $content = ''; + + /** @var string */ + protected $hash = ''; + + /** @var array */ + protected $parts = []; + + /** @var string */ + protected $link = ''; + + /** @var array */ + protected $more = []; + + /** @var array */ + protected $excerpts = []; + + /** @var string */ + protected $score = ''; + + /** @var array */ + protected $info = []; + + /** @var int */ + protected $contentEncoded; + + + /** + * IndexDocument constructor. + * + * On creation, we assure the uniqueness of the object using the providerId + * and the Id of the original document. + * + * @since 15.0.0 + * + * @param string $providerId + * @param string $documentId + */ + public function __construct(string $providerId, string $documentId) { + $this->providerId = $providerId; + $this->id = $documentId; + } + + + /** + * Returns the Id of the original document. + * + * @since 15.0.0 + * + * @return string + */ + final public function getId(): string { + return $this->id; + } + + + /** + * Returns the Id of the provider. + * + * @since 15.0.0 + * + * @return string + */ + final public function getProviderId(): string { + return $this->providerId; + } + + + /** + * Set the Index related to the IndexDocument. + * + * @see IIndex + * + * @since 15.0.0 + * + * @param IIndex $index + * + * @return IndexDocument + */ + final public function setIndex(IIndex $index): IndexDocument { + $this->index = $index; + + return $this; + } + + /** + * Get the Index. + * + * @since 15.0.0 + * + * @return IIndex + */ + final public function getIndex(): IIndex { + return $this->index; + } + + + /** + * Set the modified time of the original document. + * + * @since 15.0.0 + * + * @param int $modifiedTime + * + * @return IndexDocument + */ + final public function setModifiedTime(int $modifiedTime): IndexDocument { + $this->modifiedTime = $modifiedTime; + + return $this; + } + + /** + * Get the modified time of the original document. + * + * @since 15.0.0 + * + * @return int + */ + final public function getModifiedTime(): int { + return $this->modifiedTime; + } + + /** + * Check if the original document of the IndexDocument is older than $time. + * + * @since 15.0.0 + * + * @param int $time + * + * @return bool + */ + final public function isOlderThan(int $time): bool { + return ($this->modifiedTime < $time); + } + + + /** + * Set the read rights of the original document using a DocumentAccess. + * + * @see DocumentAccess + * + * @since 15.0.0 + * + * @param DocumentAccess $access + * + * @return $this + */ + final public function setAccess(DocumentAccess $access) { + $this->access = $access; + + return $this; + } + + /** + * Get the DocumentAccess related to the original document. + * + * @since 15.0.0 + * + * @return DocumentAccess + */ + final public function getAccess(): DocumentAccess { + return $this->access; + } + + + /** + * Add a tag to the list. + * + * @since 15.0.0 + * + * @param string $tag + * + * @return IndexDocument + */ + final public function addTag(string $tag): IndexDocument { + $this->tags[] = $tag; + + return $this; + } + + /** + * Set the list of tags assigned to the original document. + * + * @since 15.0.0 + * + * @param array $tags + * + * @return IndexDocument + */ + final public function setTags(array $tags): IndexDocument { + $this->tags = $tags; + + return $this; + } + + /** + * Get the list of tags assigned to the original document. + * + * @since 15.0.0 + * + * @return array + */ + final public function getTags(): array { + return $this->tags; + } + + + /** + * Add a meta tag to the list. + * + * @since 15.0.0 + * + * @param string $tag + * + * @return IndexDocument + */ + final public function addMetaTag(string $tag): IndexDocument { + $this->metaTags[] = $tag; + + return $this; + } + + /** + * Set the list of meta tags assigned to the original document. + * + * @since 15.0.0 + * + * @param array $tags + * + * @return IndexDocument + */ + final public function setMetaTags(array $tags): IndexDocument { + $this->metaTags = $tags; + + return $this; + } + + /** + * Get the list of meta tags assigned to the original document. + * + * @since 15.0.0 + * + * @return array + */ + final public function getMetaTags(): array { + return $this->metaTags; + } + + + /** + * Add a sub tag to the list. + * + * @since 15.0.0 + * + * @param string $sub + * @param string $tag + * + * @return IndexDocument + */ + final public function addSubTag(string $sub, string $tag): IndexDocument { + $this->subTags[$sub] = $tag; + + return $this; + } + + /** + * Set the list of sub tags assigned to the original document. + * + * @since 15.0.0 + * + * @param array $tags + * + * @return IndexDocument + */ + final public function setSubTags(array $tags): IndexDocument { + $this->subTags = $tags; + + return $this; + } + + /** + * Get the list of sub tags assigned to the original document. + * If $formatted is true, the result will be formatted in a one + * dimensional array. + * + * @since 15.0.0 + * + * @param bool $formatted + * + * @return array + */ + final public function getSubTags(bool $formatted = false): array { + if ($formatted === false) { + return $this->subTags; + } + + $subTags = []; + $ak = array_keys($this->subTags); + foreach ($ak as $source) { + $tags = $this->subTags[$source]; + foreach ($tags as $tag) { + $subTags[] = $source . '_' . $tag; + } + } + + return $subTags; + } + + + /** + * Set the source of the original document. + * + * @since 15.0.0 + * + * @param string $source + * + * @return IndexDocument + */ + final public function setSource(string $source): IndexDocument { + $this->source = $source; + + return $this; + } + + /** + * Get the source of the original document. + * + * @since 15.0.0 + * + * @return string + */ + final public function getSource(): string { + return $this->source; + } + + + /** + * Set the title of the original document. + * + * @since 15.0.0 + * + * @param string $title + * + * @return IndexDocument + */ + final public function setTitle(string $title): IndexDocument { + $this->title = $title; + + return $this; + } + + /** + * Get the title of the original document. + * + * @since 15.0.0 + * + * @return string + */ + final public function getTitle(): string { + return $this->title; + } + + + /** + * Set the content of the document. + * $encoded can be NOT_ENCODED or ENCODED_BASE64 if the content is raw or + * encoded in base64. + * + * @since 15.0.0 + * + * @param string $content + * @param int $encoded + * + * @return IndexDocument + */ + final public function setContent(string $content, int $encoded = 0): IndexDocument { + $this->content = $content; + $this->contentEncoded = $encoded; + + return $this; + } + + /** + * Get the content of the original document. + * + * @since 15.0.0 + * + * @return string + */ + final public function getContent(): string { + return $this->content; + } + + /** + * Returns the type of the encoding on the content. + * + * @since 15.0.0 + * + * @return int + */ + final public function isContentEncoded(): int { + return $this->contentEncoded; + } + + /** + * Return the size of the content. + * + * @since 15.0.0 + * + * @return int + */ + final public function getContentSize(): int { + return strlen($this->getContent()); + } + + + /** + * Generate an hash, based on the content of the original document. + * + * @since 15.0.0 + * + * @return IndexDocument + */ + final public function initHash(): IndexDocument { + if ($this->getContent() === '' || is_null($this->getContent())) { + return $this; + } + + $this->hash = hash("md5", $this->getContent()); + + return $this; + } + + /** + * Set the hash of the original document. + * + * @since 15.0.0 + * + * @param string $hash + * + * @return IndexDocument + */ + final public function setHash(string $hash): IndexDocument { + $this->hash = $hash; + + return $this; + } + + /** + * Get the hash of the original document. + * + * @since 15.0.0 + * + * @return string + */ + final public function getHash(): string { + return $this->hash; + } + + + /** + * Add a part, identified by a string, and its content. + * + * It is strongly advised to use alphanumerical chars with no space in the + * $part string. + * + * @since 15.0.0 + * + * @param string $part + * @param string $content + * + * @return IndexDocument + */ + final public function addPart(string $part, string $content): IndexDocument { + $this->parts[$part] = $content; + + return $this; + } + + /** + * Set all parts and their content. + * + * @since 15.0.0 + * + * @param array $parts + * + * @return IndexDocument + */ + final public function setParts(array $parts): IndexDocument { + $this->parts = $parts; + + return $this; + } + + /** + * Get all parts of the IndexDocument. + * + * @since 15.0.0 + * + * @return array + */ + final public function getParts(): array { + return $this->parts; + } + + + /** + * Add a link, usable by the frontend. + * + * @since 15.0.0 + * + * @param string $link + * + * @return IndexDocument + */ + final public function setLink(string $link): IndexDocument { + $this->link = $link; + + return $this; + } + + /** + * Get the link. + * + * @since 15.0.0 + * + * @return string + */ + final public function getLink(): string { + return $this->link; + } + + + /** + * Set more information that couldn't be set using other method. + * + * @since 15.0.0 + * + * @param array $more + * + * @return IndexDocument + */ + final public function setMore(array $more): IndexDocument { + $this->more = $more; + + return $this; + } + + /** + * Get more information. + * + * @since 15.0.0 + * + * @return array + */ + final public function getMore(): array { + return $this->more; + } + + + /** + * Add some excerpt of the content of the original document, usually based + * on the search request. + * + * @since 15.0.0 + * + * @param string $excerpt + * + * @return IndexDocument + */ + final public function addExcerpt(string $excerpt): IndexDocument { + $excerpt = $this->cleanExcerpt($excerpt); + + $this->excerpts[] = $excerpt; + + return $this; + } + + /** + * Set all excerpts of the content of the original document. + * + * @since 15.0.0 + * + * @param array $excerpts + * + * @return IndexDocument + */ + final public function setExcerpts(array $excerpts): IndexDocument { + $excerpts = array_map([$this, 'cleanExcerpt'], $excerpts); + + $this->excerpts = $excerpts; + + return $this; + } + + /** + * Get all excerpts of the content of the original document. + * + * @since 15.0.0 + * + * @return array + */ + final public function getExcerpts(): array { + return $this->excerpts; + } + + /** + * Clean excerpt. + * + * @since 15.0.0 + * + * @param string $excerpt + * + * @return string + */ + final public function cleanExcerpt(string $excerpt): string { + $excerpt = str_replace("\\n", ' ', $excerpt); + $excerpt = str_replace("\\r", ' ', $excerpt); + $excerpt = str_replace("\\t", ' ', $excerpt); + $excerpt = str_replace("\n", ' ', $excerpt); + $excerpt = str_replace("\r", ' ', $excerpt); + $excerpt = str_replace("\t", ' ', $excerpt); + + return $excerpt; + } + + /** + * Set the score to the result assigned to this document during a search + * request. + * + * @since 15.0.0 + * + * @param string $score + * + * @return IndexDocument + */ + final public function setScore(string $score): IndexDocument { + $this->score = $score; + + return $this; + } + + /** + * Get the score. + * + * @since 15.0.0 + * + * @return string + */ + final public function getScore(): string { + return $this->score; + } + + + /** + * Set some information about the original document that will be available + * to the front-end when displaying search result. (as string) + * Because this information will not be indexed, this method can also be + * used to manage some data while filling the IndexDocument before its + * indexing. + * + * @since 15.0.0 + * + * @param string $info + * @param string $value + * + * @return IndexDocument + */ + final public function setInfo(string $info, string $value): IndexDocument { + $this->info[$info] = $value; + + return $this; + } + + /** + * Get an information about a document. (string) + * + * @since 15.0.0 + * + * @param string $info + * @param string $default + * + * @return string + */ + final public function getInfo(string $info, string $default = ''): string { + if (!key_exists($info, $this->info)) { + return $default; + } + + return $this->info[$info]; + } + + /** + * Set some information about the original document that will be available + * to the front-end when displaying search result. (as array) + * Because this information will not be indexed, this method can also be + * used to manage some data while filling the IndexDocument before its + * indexing. + * + * @since 15.0.0 + * + * @param string $info + * @param array $value + * + * @return IndexDocument + */ + final public function setInfoArray(string $info, array $value): IndexDocument { + $this->info[$info] = $value; + + return $this; + } + + /** + * Get an information about a document. (array) + * + * @since 15.0.0 + * + * @param string $info + * @param array $default + * + * @return array + */ + final public function getInfoArray(string $info, array $default = []): array { + if (!key_exists($info, $this->info)) { + return $default; + } + + return $this->info[$info]; + } + + /** + * Get all info. + * + * @since 15.0.0 + * + * @return array + */ + final public function getInfoAll(): array { + + $info = []; + foreach ($this->info as $k => $v) { + if (substr($k, 0, 1) === '_') { + continue; + } + + $info[$k] = $v; + } + + return $info; + } + + + /** + * @since 15.0.0 + * + * On some version of PHP, it is better to force destruct the object. + * And during the index, the number of generated IndexDocument can be + * _huge_. + */ + public function __destruct() { + unset($this->id); + unset($this->providerId); + unset($this->access); + unset($this->modifiedTime); + unset($this->title); + unset($this->content); + unset($this->hash); + unset($this->link); + unset($this->source); + unset($this->tags); + unset($this->metaTags); + unset($this->subTags); + unset($this->more); + unset($this->excerpts); + unset($this->score); + unset($this->info); + unset($this->contentEncoded); + } + + /** + * @since 15.0.0 + * + * @return array + */ + public function jsonSerialize() { + return [ + 'id' => $this->getId(), + 'providerId' => $this->getProviderId(), + 'access' => $this->access, + 'modifiedTime' => $this->getModifiedTime(), + 'title' => $this->getTitle(), + 'link' => $this->getLink(), + 'index' => $this->index, + 'source' => $this->getSource(), + 'info' => $this->getInfoAll(), + 'hash' => $this->getHash(), + 'contentSize' => $this->getContentSize(), + 'tags' => $this->getTags(), + 'metatags' => $this->getMetaTags(), + 'subtags' => $this->getSubTags(), + 'more' => $this->getMore(), + 'excerpts' => $this->getExcerpts(), + 'score' => $this->getScore() + ]; + } + +} + diff --git a/lib/public/FullTextSearch/Model/SearchOption.php b/lib/public/FullTextSearch/Model/SearchOption.php new file mode 100644 index 00000000000..ae6ad3241b6 --- /dev/null +++ b/lib/public/FullTextSearch/Model/SearchOption.php @@ -0,0 +1,296 @@ +<?php +declare(strict_types=1); + + +/** + * FullTextSearch - Full text search framework for Nextcloud + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2018 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCP\FullTextSearch\Model; + + +use JsonSerializable; + + +/** + * @since 15.0.0 + * + * Class SearchOption + * + * @package OCP\FullTextSearch\Model + */ +final class SearchOption implements JsonSerializable { + + + const CHECKBOX = 'checkbox'; + const INPUT = 'input'; + + const INPUT_SMALL = 'small'; + + + /** @var string */ + private $name = ''; + + /** @var string */ + private $title = ''; + + /** @var string */ + private $type = ''; + + /** @var string */ + private $size = ''; + + /** @var string */ + private $placeholder = ''; + + + /** + * * + * + * The array can be empty in case no search options are available. + * The format of the array must be like this: + * + * [ + * 'panel' => [ + * 'options' => [ + * OPTION1, + * OPTION2, + * OPTION3 + * ] + * ], + * 'navigation' => [ + * 'icon' => 'css-class-of-the-icon', + * 'options' => [ + * OPTION1, + * OPTION2, + * OPTION3 + * ] + * ] + * ] + * + * - PANEL contains entries that will be displayed in the app itself, when + * a search is initiated. + * - NAVIGATION contains entries that will be available when using the + * FullTextSearch navigation page + * - OPTION is an element that define each option available to the user. + * + * The format for the options must be like this: + * + * [ + * 'name' => 'name_of_the_option', + * 'title' => 'Name displayed in the panel', + * 'type' => '', + * 'size' => '' (optional), + * 'placeholder' => '' (optional) + * ] + * + * - NAME is the variable name that is sent to the IFullTextSearchProvider + * when a ISearchRequest is requested. (keys in the array returned by the + * ISearchRequest->getOptions()) + * - TYPE can be 'input' or 'checkbox' + * - SIZE is only used in case TYPE='input', default is 'large' but can be + * 'small' + * - PLACEHOLDER is only used in case TYPE='input', default is empty. + */ + + /** + * SearchOption constructor. + * + * Some value can be setduring the creation of the object. + * + * @since 15.0.0 + * + * @param string $name + * @param string $title + * @param string $type + * @param string $size + * @param string $placeholder + */ + public function __construct(string $name = '', string $title = '', string $type = '', string $size = '', string $placeholder = '') { + $this->name = $name; + $this->title = $title; + $this->type = $type; + $this->size = $size; + $this->placeholder = $placeholder; + } + + + /** + * Set the name/key of the option. + * The string should only contains alphanumerical chars and underscore. + * The key can be retrieve when using ISearchRequest::getOption + * + * @see ISearchRequest::getOption + * + * @since 15.0.0 + * + * @param string $name + * + * @return SearchOption + */ + public function setName(string $name): SearchOption { + $this->name = $name; + + return $this; + } + + /** + * Get the name/key of the option. + * + * @since 15.0.0 + * + * @return string + */ + public function getName(): string { + return $this->name; + } + + + /** + * Set the title/display name of the option. + * + * @since 15.0.0 + * + * @param string $title + * + * @return SearchOption + */ + public function setTitle(string $title): SearchOption { + $this->title = $title; + + return $this; + } + + /** + * Get the title of the option. + * + * @since 15.0.0 + * + * @return string + */ + public function getTitle(): string { + return $this->title; + } + + + /** + * Set the type of the option. + * $type can be SearchOption::CHECKBOX or SearchOption::INPUT + * + * @since 15.0.0 + * + * @param string $type + * + * @return SearchOption + */ + public function setType(string $type): SearchOption { + $this->type = $type; + + return $this; + } + + /** + * Get the type of the option. + * + * @since 15.0.0 + * + * @return string + */ + public function getType(): string { + return $this->type; + } + + + /** + * In case of Type is INPUT, set the size of the input field. + * Value can be SearchOption::INPUT_SMALL or not defined. + * + * @since 15.0.0 + * + * @param string $size + * + * @return SearchOption + */ + public function setSize(string $size): SearchOption { + $this->size = $size; + + return $this; + } + + /** + * Get the size of the INPUT. + * + * @since 15.0.0 + * + * @return string + */ + public function getSize(): string { + return $this->size; + } + + + /** + * In case of Type is , set the placeholder to be displayed in the input + * field. + * + * @since 15.0.0 + * + * @param string $placeholder + * + * @return SearchOption + */ + public function setPlaceholder(string $placeholder): SearchOption { + $this->placeholder = $placeholder; + + return $this; + } + + /** + * Get the placeholder. + * + * @since 15.0.0 + * + * @return string + */ + public function getPlaceholder(): string { + return $this->placeholder; + } + + + /** + * @since 15.0.0 + * + * @return array + */ + public function jsonSerialize(): array { + return [ + 'name' => $this->getName(), + 'title' => $this->getTitle(), + 'type' => $this->getType(), + 'size' => $this->getSize(), + 'placeholder' => $this->getPlaceholder() + ]; + } +} diff --git a/lib/public/FullTextSearch/Model/SearchTemplate.php b/lib/public/FullTextSearch/Model/SearchTemplate.php new file mode 100644 index 00000000000..7d9159190ea --- /dev/null +++ b/lib/public/FullTextSearch/Model/SearchTemplate.php @@ -0,0 +1,258 @@ +<?php +declare(strict_types=1); + + +/** + * FullTextSearch - Full text search framework for Nextcloud + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2018 + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCP\FullTextSearch\Model; + + +use JsonSerializable; +use OCP\FullTextSearch\IFullTextSearchProvider; + + +/** + * Class SearchTemplate + * + * This is a data transfer object that should be created by Content Provider + * when the getSearchTemplate() method is called. + * + * The object will contain templates to be displayed, and the list of the different + * options to be available to the user when he start a new search. + * + * The display of the Options is generated by the FullTextSearch app and Options + * can be displayed in 2 places: + * + * - the navigation page of the app that generate the indexed content. + * (files, bookmarks, deck, mails, ...) + * - the navigation page of the FullTextSearch app. + * + * Both pages will have different Options, and only the first one can integrate + * a specific template. + * + * @see IFullTextSearchProvider::getSearchTemplate + * + * @since 15.0.0 + * + * @package OCP\FullTextSearch\Model + */ +final class SearchTemplate implements JsonSerializable { + + + /** @var string */ + private $icon = ''; + + /** @var string */ + private $css = ''; + + /** @var string */ + private $template = ''; + + /** @var SearchOption[] */ + private $panelOptions = []; + + /** @var SearchOption[] */ + private $navigationOptions = []; + + + /** + * SearchTemplate constructor. + * + * the class of the icon and the css file to be loaded can be set during the + * creation of the object. + * + * @since 15.0.0 + * + * @param string $icon + * @param string $css + */ + public function __construct(string $icon = '', string $css = '') { + $this->icon = $icon; + $this->css = $css; + } + + + /** + * Set the class of the icon to be displayed in the left panel of the + * FullTextSearch navigation page, in front of the related Content Provider. + * + * @since 15.0.0 + * + * @param string $class + * + * @return SearchTemplate + */ + public function setIcon(string $class): SearchTemplate { + $this->icon = $class; + + return $this; + } + + /** + * Get the class of the icon. + * + * @since 15.0.0 + * + * @return string + */ + public function getIcon(): string { + return $this->icon; + } + + + /** + * Set the path of a CSS file that will be loaded when needed. + * + * @since 15.0.0 + * + * @param string $css + * + * @return SearchTemplate + */ + public function setCss(string $css): SearchTemplate { + $this->css = $css; + + return $this; + } + + /** + * Get the path of the CSS file. + * + * @since 15.0.0 + * + * @return string + */ + public function getCss(): string { + return $this->css; + } + + + /** + * Set the path of the file of a template that the HTML will be displayed + * below the Options. + * This should only be used if your Content Provider needs to set options in + * a way not generated by FullTextSearch + * + * @since 15.0.0 + * + * @param string $template + * + * @return SearchTemplate + */ + public function setTemplate(string $template): SearchTemplate { + $this->template = $template; + + return $this; + } + + /** + * Get the path of the template file. + * + * @since 15.0.0 + * + * @return string + */ + public function getTemplate(): string { + return $this->template; + } + + + /** + * Add an option in the Panel that is displayed when the user start a search + * within the app that generate the content. + * + * @see SearchOption + * + * @since 15.0.0 + * + * @param SearchOption $option + * + * @return SearchTemplate + */ + public function addPanelOption(SearchOption $option): SearchTemplate { + $this->panelOptions[] = $option; + + return $this; + } + + /** + * Get all options to be displayed in the Panel. + * + * @since 15.0.0 + * + * @return SearchOption[] + */ + public function getPanelOptions(): array { + return $this->panelOptions; + } + + + /** + * Add an option in the left panel of the FullTextSearch navigation page. + * + * @see SearchOption + * + * @since 15.0.0 + * + * @param SearchOption $option + * + * @return SearchTemplate + */ + public function addNavigationOption(SearchOption $option): SearchTemplate { + $this->navigationOptions[] = $option; + + return $this; + } + + /** + * Get all options to be displayed in the FullTextSearch navigation page. + * + * @since 15.0.0 + * + * @return array + */ + public function getNavigationOptions(): array { + return $this->navigationOptions; + } + + + /** + * @since 15.0.0 + * + * @return array + */ + public function jsonSerialize(): array { + return [ + 'icon' => $this->getIcon(), + 'css' => $this->getCss(), + 'template' => $this->getTemplate(), + 'panel' => $this->getPanelOptions(), + 'navigation' => $this->getNavigationOptions() + ]; + } +} + diff --git a/lib/public/FullTextSearch/Service/IIndexService.php b/lib/public/FullTextSearch/Service/IIndexService.php new file mode 100644 index 00000000000..c5d1b9b3bcf --- /dev/null +++ b/lib/public/FullTextSearch/Service/IIndexService.php @@ -0,0 +1,99 @@ +<?php +declare(strict_types=1); + + +/** + * FullTextSearch - Full text search framework for Nextcloud + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2018, Maxence Lange <maxence@artificial-owl.com> + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCP\FullTextSearch\Service; + + +use OCP\FullTextSearch\Model\IIndex; + + +/** + * Interface IIndexService + * + * @since 15.0.0 + * + * @package OCP\FullTextSearch\Service + */ +interface IIndexService { + + + /** + * Retrieve an Index from the database, based on the Id of the Provider + * and the Id of the Document + * + * @since 15.0.0 + * + * @param string $providerId + * @param string $documentId + * + * @return IIndex + */ + public function getIndex(string $providerId, string $documentId): IIndex; + + + /** + * Update the status of an Index. status is a bit flag, setting $reset to + * true will reset the status to the value defined in the parameter. + * + * @since 15.0.0 + * + * @param string $providerId + * @param string $documentId + * @param int $status + * @param bool $reset + */ + public function updateIndexStatus(string $providerId, string $documentId, int $status, bool $reset = false); + + + /** + * Update the status of an array of Index. status is a bit flag, setting $reset to + * true will reset the status to the value defined in the parameter. + * + * @since 15.0.0 + * + * @param string $providerId + * @param array $documentIds + * @param int $status + * @param bool $reset + */ + public function updateIndexesStatus(string $providerId, array $documentIds, int $status, bool $reset = false); + + + /** + * Update an array of Index. + * + * @since 15.0.0 + * + * @param array $indexes + */ + public function updateIndexes(array $indexes); + +} + diff --git a/lib/public/FullTextSearch/Service/IProviderService.php b/lib/public/FullTextSearch/Service/IProviderService.php new file mode 100644 index 00000000000..64153c13965 --- /dev/null +++ b/lib/public/FullTextSearch/Service/IProviderService.php @@ -0,0 +1,65 @@ +<?php +declare(strict_types=1); + + +/** + * FullTextSearch - Full text search framework for Nextcloud + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2018, Maxence Lange <maxence@artificial-owl.com> + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCP\FullTextSearch\Service; + + +/** + * Interface IProviderService + * + * @since 15.0.0 + * + * @package OCP\FullTextSearch\Service + */ +interface IProviderService { + + + /** + * Check if the provider $providerId is already indexed. + * + * @since 15.0.0 + * + * @param string $providerId + * + * @return bool + */ + public function isProviderIndexed(string $providerId); + + + /** + * Add the Javascript API in the navigation page of an app. + * + * @since 15.0.0 + */ + public function addJavascriptAPI(); + + +} + diff --git a/lib/public/FullTextSearch/Service/ISearchService.php b/lib/public/FullTextSearch/Service/ISearchService.php new file mode 100644 index 00000000000..7da38e44f5c --- /dev/null +++ b/lib/public/FullTextSearch/Service/ISearchService.php @@ -0,0 +1,89 @@ +<?php +declare(strict_types=1); + + +/** + * FullTextSearch - Full text search framework for Nextcloud + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Maxence Lange <maxence@artificial-owl.com> + * @copyright 2018, Maxence Lange <maxence@artificial-owl.com> + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCP\FullTextSearch\Service; + + +use OCP\FullTextSearch\Model\ISearchRequest; +use OCP\FullTextSearch\Model\ISearchResult; + + +/** + * Interface ISearchService + * + * @since 15.0.0 + * + * @package OCP\FullTextSearch\Service + */ +interface ISearchService { + + + /** + * generate a search request, based on an array: + * + * $request = + * [ + * 'providers' => (string/array) 'all' + * 'author' => (string) owner of the document. + * 'search' => (string) search string, + * 'size' => (int) number of items to be return + * 'page' => (int) page + * 'parts' => (array) parts of document to search within, + * 'options' = (array) search options, + * 'tags' => (array) tags, + * 'metatags' => (array) metatags, + * 'subtags' => (array) subtags + * ] + * + * 'providers' can be an array of providerIds + * + * @since 15.0.0 + * + * @param array $request + * + * @return ISearchRequest + */ + public function generateSearchRequest(array $request): ISearchRequest; + + + /** + * Search documents + * + * @since 15.0.0 + * + * @param string $userId + * @param ISearchRequest $searchRequest + * + * @return ISearchResult[] + */ + public function search(string $userId, ISearchRequest $searchRequest): array; + +} + diff --git a/lib/public/IAddressBook.php b/lib/public/IAddressBook.php index 67c34c9e8c9..4739e6f0c5b 100644 --- a/lib/public/IAddressBook.php +++ b/lib/public/IAddressBook.php @@ -55,16 +55,18 @@ namespace OCP { /** * @param string $pattern which should match within the $searchProperties * @param array $searchProperties defines the properties within the query pattern should match - * @param array $options - for future use. One should always have options! + * @param array $options Options to define the output format + * - types boolean (since 15.0.0) If set to true, fields that come with a TYPE property will be an array + * example: ['id' => 5, 'FN' => 'Thomas Tanghus', 'EMAIL' => ['type => 'HOME', 'value' => 'g@h.i']] * @return array an array of contacts which are arrays of key-value-pairs + * example result: + * [ + * ['id' => 0, 'FN' => 'Thomas Müller', 'EMAIL' => 'a@b.c', 'GEO' => '37.386013;-122.082932'], + * ['id' => 5, 'FN' => 'Thomas Tanghus', 'EMAIL' => ['d@e.f', 'g@h.i']] + * ] * @since 5.0.0 */ public function search($pattern, $searchProperties, $options); - // // dummy results - // return array( - // array('id' => 0, 'FN' => 'Thomas Müller', 'EMAIL' => 'a@b.c', 'GEO' => '37.386013;-122.082932'), - // array('id' => 5, 'FN' => 'Thomas Tanghus', 'EMAIL' => array('d@e.f', 'g@h.i')), - // ); /** * @param array $properties this array if key-value-pairs defines a contact diff --git a/lib/public/Share/IShare.php b/lib/public/Share/IShare.php index 43543fdad47..dcd5fdecbea 100644 --- a/lib/public/Share/IShare.php +++ b/lib/public/Share/IShare.php @@ -418,4 +418,25 @@ interface IShare { * @since 11.0.0 */ public function getNodeCacheEntry(); + + /** + * Sets a shares hide download state + * This is mainly for public shares. It will signal that the share page should + * hide download buttons etc. + * + * @param bool $ro + * @return IShare + * @since 15.0.0 + */ + public function setHideDownload(bool $hide): IShare; + + /** + * Gets a shares hide download state + * This is mainly for public shares. It will signal that the share page should + * hide download buttons etc. + * + * @return bool + * @since 15.0.0 + */ + public function getHideDownload(): bool; } diff --git a/settings/BackgroundJobs/VerifyUserData.php b/settings/BackgroundJobs/VerifyUserData.php index b4a60ec8405..56ebadff9c3 100644 --- a/settings/BackgroundJobs/VerifyUserData.php +++ b/settings/BackgroundJobs/VerifyUserData.php @@ -63,6 +63,9 @@ class VerifyUserData extends Job { /** @var string */ private $lookupServerUrl; + /** @var IConfig */ + private $config; + /** * VerifyUserData constructor. * @@ -85,6 +88,7 @@ class VerifyUserData extends Job { $lookupServerUrl = $config->getSystemValue('lookup_server', 'https://lookup.nextcloud.com'); $this->lookupServerUrl = rtrim($lookupServerUrl, '/'); + $this->config = $config; } /** diff --git a/settings/Controller/CheckSetupController.php b/settings/Controller/CheckSetupController.php index 42bb4739870..fa4ed57ab95 100644 --- a/settings/Controller/CheckSetupController.php +++ b/settings/Controller/CheckSetupController.php @@ -287,12 +287,11 @@ class CheckSetupController extends Controller { */ private function forwardedForHeadersWorking() { $trustedProxies = $this->config->getSystemValue('trusted_proxies', []); - $remoteAddress = $this->request->getRemoteAddress(); + $remoteAddress = $this->request->getHeader('REMOTE_ADDR'); - if (is_array($trustedProxies) && in_array($remoteAddress, $trustedProxies)) { - return false; + if (\is_array($trustedProxies) && \in_array($remoteAddress, $trustedProxies)) { + return $remoteAddress !== $this->request->getRemoteAddress(); } - // either not enabled or working correctly return true; } diff --git a/settings/js/admin.js b/settings/js/admin.js index 35f3d949ab6..56bbaead520 100644 --- a/settings/js/admin.js +++ b/settings/js/admin.js @@ -66,11 +66,8 @@ $(document).ready(function(){ }); }); - $('#shareapiExpireAfterNDays').change(function() { - var value = $(this).val(); - if (value <= 0) { - $(this).val("1"); - } + $('#shareapiExpireAfterNDays').on('input', function() { + this.value = this.value.replace(/\D/g, ''); }); $('#shareAPI input:not(.noJSAutoUpdate)').change(function() { diff --git a/settings/l10n/is.js b/settings/l10n/is.js index f88a5d79232..522917d8fbb 100644 --- a/settings/l10n/is.js +++ b/settings/l10n/is.js @@ -110,8 +110,10 @@ OC.L10N.register( "Groups" : "Hópar", "Group list is empty" : "Listi yfir hópa er tómur", "Unable to retrieve the group list" : "Tókst ekki að ná í lista yfir hópinn", + "Two-factor authentication can be enforced for all\tusers and specific groups. If they do not have a two-factor provider configured, they will be unable to log into the system." : "Hægt er að þvinga fram tveggja-þrepa auðkenningu fyrir alla notendur og/eða tiltekna hópa. Ef þeir eru ekki með tveggja-þrepa auðkenningarþjónustu uppsetta, munu þeir ekki geta skráð sig inn á kerfið.", "Enforce two-factor authentication" : "Þvinga fram tveggja-þrepa auðkenningu", "Limit to groups" : "Takmarka við hópa", + "Two-factor authentication is not enforced for\tmembers of the following groups." : "Tveggja-þrepa auðkenning er ekki þvinguð fram\tfyrir meðlimi eftirfarandi hópa.", "Official" : "Opinbert", "No results" : "Engar niðurstöður", "Visit website" : "Heimsækja vefsvæðið", diff --git a/settings/l10n/is.json b/settings/l10n/is.json index a069b428fae..7a79081a289 100644 --- a/settings/l10n/is.json +++ b/settings/l10n/is.json @@ -108,8 +108,10 @@ "Groups" : "Hópar", "Group list is empty" : "Listi yfir hópa er tómur", "Unable to retrieve the group list" : "Tókst ekki að ná í lista yfir hópinn", + "Two-factor authentication can be enforced for all\tusers and specific groups. If they do not have a two-factor provider configured, they will be unable to log into the system." : "Hægt er að þvinga fram tveggja-þrepa auðkenningu fyrir alla notendur og/eða tiltekna hópa. Ef þeir eru ekki með tveggja-þrepa auðkenningarþjónustu uppsetta, munu þeir ekki geta skráð sig inn á kerfið.", "Enforce two-factor authentication" : "Þvinga fram tveggja-þrepa auðkenningu", "Limit to groups" : "Takmarka við hópa", + "Two-factor authentication is not enforced for\tmembers of the following groups." : "Tveggja-þrepa auðkenning er ekki þvinguð fram\tfyrir meðlimi eftirfarandi hópa.", "Official" : "Opinbert", "No results" : "Engar niðurstöður", "Visit website" : "Heimsækja vefsvæðið", diff --git a/tests/Core/Controller/LoginControllerTest.php b/tests/Core/Controller/LoginControllerTest.php index f2e8d112b64..efe85d81e1c 100644 --- a/tests/Core/Controller/LoginControllerTest.php +++ b/tests/Core/Controller/LoginControllerTest.php @@ -199,6 +199,7 @@ class LoginControllerTest extends TestCase { 'alt_login' => [], 'resetPasswordLink' => null, 'throttle_delay' => 1000, + 'login_form_autocomplete' => 'off', ], 'guest' ); @@ -223,6 +224,7 @@ class LoginControllerTest extends TestCase { 'alt_login' => [], 'resetPasswordLink' => null, 'throttle_delay' => 1000, + 'login_form_autocomplete' => 'off', ], 'guest' ); @@ -255,10 +257,12 @@ class LoginControllerTest extends TestCase { ->method('isLoggedIn') ->willReturn(false); $this->config - ->expects($this->once()) + ->expects($this->exactly(2)) ->method('getSystemValue') - ->with('lost_password_link') - ->willReturn(false); + ->will($this->returnValueMap([ + ['login_form_autocomplete', true, true], + ['lost_password_link', '', false], + ])); $user = $this->createMock(IUser::class); $user ->expects($this->once()) @@ -281,6 +285,7 @@ class LoginControllerTest extends TestCase { 'alt_login' => [], 'resetPasswordLink' => false, 'throttle_delay' => 1000, + 'login_form_autocomplete' => 'on', ], 'guest' ); @@ -338,10 +343,12 @@ class LoginControllerTest extends TestCase { ->method('isLoggedIn') ->willReturn(false); $this->config - ->expects($this->once()) + ->expects($this->exactly(2)) ->method('getSystemValue') - ->with('lost_password_link') - ->willReturn(false); + ->will($this->returnValueMap([ + ['login_form_autocomplete', true, true], + ['lost_password_link', '', false], + ])); $user = $this->createMock(IUser::class); $user->expects($this->once()) ->method('canChangePassword') @@ -363,6 +370,7 @@ class LoginControllerTest extends TestCase { 'alt_login' => [], 'resetPasswordLink' => false, 'throttle_delay' => 1000, + 'login_form_autocomplete' => 'on', ], 'guest' ); diff --git a/tests/Settings/Controller/CheckSetupControllerTest.php b/tests/Settings/Controller/CheckSetupControllerTest.php index 6706573a1ad..34c7d19bd8d 100644 --- a/tests/Settings/Controller/CheckSetupControllerTest.php +++ b/tests/Settings/Controller/CheckSetupControllerTest.php @@ -295,38 +295,41 @@ class CheckSetupControllerTest extends TestCase { ); } - public function testForwardedForHeadersWorkingFalse() { + /** + * @dataProvider dataForwardedForHeadersWorking + * + * @param array $trustedProxies + * @param string $remoteAddrNoForwarded + * @param string $remoteAddr + * @param bool $result + */ + public function testForwardedForHeadersWorking(array $trustedProxies, string $remoteAddrNoForwarded, string $remoteAddr, bool $result) { $this->config->expects($this->once()) ->method('getSystemValue') ->with('trusted_proxies', []) - ->willReturn(['1.2.3.4']); + ->willReturn($trustedProxies); $this->request->expects($this->once()) + ->method('getHeader') + ->with('REMOTE_ADDR') + ->willReturn($remoteAddrNoForwarded); + $this->request->expects($this->any()) ->method('getRemoteAddress') - ->willReturn('1.2.3.4'); + ->willReturn($remoteAddr); - $this->assertFalse( - self::invokePrivate( - $this->checkSetupController, - 'forwardedForHeadersWorking' - ) + $this->assertEquals( + $result, + self::invokePrivate($this->checkSetupController, 'forwardedForHeadersWorking') ); } - public function testForwardedForHeadersWorkingTrue() { - $this->config->expects($this->once()) - ->method('getSystemValue') - ->with('trusted_proxies', []) - ->willReturn(['1.2.3.4']); - $this->request->expects($this->once()) - ->method('getRemoteAddress') - ->willReturn('4.3.2.1'); - - $this->assertTrue( - self::invokePrivate( - $this->checkSetupController, - 'forwardedForHeadersWorking' - ) - ); + public function dataForwardedForHeadersWorking() { + return [ + // description => trusted proxies, getHeader('REMOTE_ADDR'), getRemoteAddr, expected result + 'no trusted proxies' => [[], '2.2.2.2', '2.2.2.2', true], + 'trusted proxy, remote addr not trusted proxy' => [['1.1.1.1'], '2.2.2.2', '2.2.2.2', true], + 'trusted proxy, remote addr is trusted proxy, x-forwarded-for working' => [['1.1.1.1'], '1.1.1.1', '2.2.2.2', true], + 'trusted proxy, remote addr is trusted proxy, x-forwarded-for not set' => [['1.1.1.1'], '1.1.1.1', '1.1.1.1', false], + ]; } public function testCheck() { @@ -348,7 +351,8 @@ class CheckSetupControllerTest extends TestCase { ->will($this->returnValue(false)); $this->request->expects($this->once()) - ->method('getRemoteAddress') + ->method('getHeader') + ->with('REMOTE_ADDR') ->willReturn('4.3.2.1'); $client = $this->getMockBuilder('\OCP\Http\Client\IClient') diff --git a/tests/acceptance/features/app-files.feature b/tests/acceptance/features/app-files.feature index 74490180ad3..70e085ca665 100644 --- a/tests/acceptance/features/app-files.feature +++ b/tests/acceptance/features/app-files.feature @@ -121,6 +121,32 @@ Feature: app-files And I open the Share menu Then I see that the Share menu is shown + Scenario: hide download in a public shared link + Given I act as John + And I am logged in + And I share the link for "welcome.txt" + And I set the download of the shared link as hidden + And I write down the shared link + When I act as Jane + And I visit the shared link I wrote down + And I see that the current page is the shared link I wrote down + Then I see that the download button is not shown + And I see that the Share menu button is not shown + + Scenario: show download again in a public shared link + Given I act as John + And I am logged in + And I share the link for "welcome.txt" + And I set the download of the shared link as hidden + And I set the download of the shared link as shown + And I write down the shared link + When I act as Jane + And I visit the shared link I wrote down + And I see that the current page is the shared link I wrote down + Then I see that the download button is shown + And I open the Share menu + And I see that the Share menu is shown + Scenario: creation is not possible by default in a public shared folder Given I act as John And I am logged in diff --git a/tests/acceptance/features/bootstrap/FilesAppContext.php b/tests/acceptance/features/bootstrap/FilesAppContext.php index 408995b9a83..4b648bfc544 100644 --- a/tests/acceptance/features/bootstrap/FilesAppContext.php +++ b/tests/acceptance/features/bootstrap/FilesAppContext.php @@ -235,6 +235,27 @@ class FilesAppContext implements Context, ActorAwareInterface { /** * @return Locator */ + public static function hideDownloadCheckbox() { + // forThe()->checkbox("Hide download") can not be used here; that would + // return the checkbox itself, but the element that the user interacts + // with is the label. + return Locator::forThe()->xpath("//label[normalize-space() = 'Hide download']")-> + descendantOf(self::shareLinkMenu())-> + describedAs("Hide download checkbox in the details view in Files app"); + } + + /** + * @return Locator + */ + public static function hideDownloadCheckboxInput() { + return Locator::forThe()->checkbox("Hide download")-> + descendantOf(self::shareLinkMenu())-> + describedAs("Hide download checkbox input in the details view in Files app"); + } + + /** + * @return Locator + */ public static function allowUploadAndEditingRadioButton() { // forThe()->radio("Allow upload and editing") can not be used here; // that would return the radio button itself, but the element that the @@ -335,6 +356,28 @@ class FilesAppContext implements Context, ActorAwareInterface { } /** + * @When I set the download of the shared link as hidden + */ + public function iSetTheDownloadOfTheSharedLinkAsHidden() { + $this->showShareLinkMenuIfNeeded(); + + $this->iSeeThatTheDownloadOfTheLinkShareIsShown(); + + $this->actor->find(self::hideDownloadCheckbox(), 2)->click(); + } + + /** + * @When I set the download of the shared link as shown + */ + public function iSetTheDownloadOfTheSharedLinkAsShown() { + $this->showShareLinkMenuIfNeeded(); + + $this->iSeeThatTheDownloadOfTheLinkShareIsHidden(); + + $this->actor->find(self::hideDownloadCheckbox(), 2)->click(); + } + + /** * @When I set the shared link as editable */ public function iSetTheSharedLinkAsEditable() { @@ -461,6 +504,24 @@ class FilesAppContext implements Context, ActorAwareInterface { } /** + * @Then I see that the download of the link share is hidden + */ + public function iSeeThatTheDownloadOfTheLinkShareIsHidden() { + $this->showShareLinkMenuIfNeeded(); + + PHPUnit_Framework_Assert::assertTrue($this->actor->find(self::hideDownloadCheckboxInput(), 10)->isChecked()); + } + + /** + * @Then I see that the download of the link share is shown + */ + public function iSeeThatTheDownloadOfTheLinkShareIsShown() { + $this->showShareLinkMenuIfNeeded(); + + PHPUnit_Framework_Assert::assertFalse($this->actor->find(self::hideDownloadCheckboxInput(), 10)->isChecked()); + } + + /** * @Then I see that the working icon for password protect is shown */ public function iSeeThatTheWorkingIconForPasswordProtectIsShown() { diff --git a/tests/acceptance/features/bootstrap/FilesSharingAppContext.php b/tests/acceptance/features/bootstrap/FilesSharingAppContext.php index 1fe12d5f42d..531184442dd 100644 --- a/tests/acceptance/features/bootstrap/FilesSharingAppContext.php +++ b/tests/acceptance/features/bootstrap/FilesSharingAppContext.php @@ -104,6 +104,14 @@ class FilesSharingAppContext implements Context, ActorAwareInterface { } /** + * @return Locator + */ + public static function downloadButton() { + return Locator::forThe()->id("downloadFile")-> + describedAs("Download button in Shared file page"); + } + + /** * @When I visit the shared link I wrote down */ public function iVisitTheSharedLinkIWroteDown() { @@ -199,10 +207,42 @@ class FilesSharingAppContext implements Context, ActorAwareInterface { } /** + * @Then I see that the Share menu button is not shown + */ + public function iSeeThatTheShareMenuButtonIsNotShown() { + try { + PHPUnit_Framework_Assert::assertFalse( + $this->actor->find(self::shareMenuButton())->isVisible()); + } catch (NoSuchElementException $exception) { + } + } + + /** * @Then I see that the shared file preview shows the text :text */ public function iSeeThatTheSharedFilePreviewShowsTheText($text) { PHPUnit_Framework_Assert::assertContains($text, $this->actor->find(self::textPreview(), 10)->getText()); } + /** + * @Then I see that the download button is shown + */ + public function iSeeThatTheDownloadButtonIsShown() { + if (!WaitFor::elementToBeEventuallyShown( + $this->actor, self::downloadButton(), $timeout = 10 * $this->actor->getFindTimeoutMultiplier())) { + PHPUnit_Framework_Assert::fail("The download button is not visible yet after $timeout seconds"); + } + } + + /** + * @Then I see that the download button is not shown + */ + public function iSeeThatTheDownloadButtonIsNotShown() { + try { + PHPUnit_Framework_Assert::assertFalse( + $this->actor->find(self::downloadButton())->isVisible()); + } catch (NoSuchElementException $exception) { + } + } + } diff --git a/tests/lib/AppFramework/Http/RequestTest.php b/tests/lib/AppFramework/Http/RequestTest.php index a715eaa9599..c0e8dc97ef2 100644 --- a/tests/lib/AppFramework/Http/RequestTest.php +++ b/tests/lib/AppFramework/Http/RequestTest.php @@ -486,6 +486,35 @@ class RequestTest extends \Test\TestCase { $this->assertSame('10.4.0.5', $request->getRemoteAddress()); } + public function testGetRemoteAddressIPv6WithSingleTrustedRemote() { + $this->config + ->expects($this->at(0)) + ->method('getSystemValue') + ->with('trusted_proxies') + ->will($this->returnValue(['2001:db8:85a3:8d3:1319:8a2e:370:7348'])); + $this->config + ->expects($this->at(1)) + ->method('getSystemValue') + ->with('forwarded_for_headers') + ->will($this->returnValue(['HTTP_X_FORWARDED'])); + + $request = new Request( + [ + 'server' => [ + 'REMOTE_ADDR' => '2001:db8:85a3:8d3:1319:8a2e:370:7348', + 'HTTP_X_FORWARDED' => '10.4.0.5, 10.4.0.4', + 'HTTP_X_FORWARDED_FOR' => '192.168.0.233' + ], + ], + $this->secureRandom, + $this->config, + $this->csrfTokenManager, + $this->stream + ); + + $this->assertSame('10.4.0.5', $request->getRemoteAddress()); + } + public function testGetRemoteAddressVerifyPriorityHeader() { $this->config ->expects($this->at(0)) @@ -519,6 +548,92 @@ class RequestTest extends \Test\TestCase { $this->assertSame('192.168.0.233', $request->getRemoteAddress()); } + public function testGetRemoteAddressIPv6VerifyPriorityHeader() { + $this->config + ->expects($this->at(0)) + ->method('getSystemValue') + ->with('trusted_proxies') + ->will($this->returnValue(['2001:db8:85a3:8d3:1319:8a2e:370:7348'])); + $this->config + ->expects($this->at(1)) + ->method('getSystemValue') + ->with('forwarded_for_headers') + ->will($this->returnValue([ + 'HTTP_CLIENT_IP', + 'HTTP_X_FORWARDED_FOR', + 'HTTP_X_FORWARDED' + ])); + + $request = new Request( + [ + 'server' => [ + 'REMOTE_ADDR' => '2001:db8:85a3:8d3:1319:8a2e:370:7348', + 'HTTP_X_FORWARDED' => '10.4.0.5, 10.4.0.4', + 'HTTP_X_FORWARDED_FOR' => '192.168.0.233' + ], + ], + $this->secureRandom, + $this->config, + $this->csrfTokenManager, + $this->stream + ); + + $this->assertSame('192.168.0.233', $request->getRemoteAddress()); + } + + public function testGetRemoteAddressWithMatchingCidrTrustedRemote() { + $this->config + ->expects($this->at(0)) + ->method('getSystemValue') + ->with('trusted_proxies') + ->will($this->returnValue(['192.168.2.0/24'])); + $this->config + ->expects($this->at(1)) + ->method('getSystemValue') + ->with('forwarded_for_headers') + ->will($this->returnValue(['HTTP_X_FORWARDED_FOR'])); + + $request = new Request( + [ + 'server' => [ + 'REMOTE_ADDR' => '192.168.2.99', + 'HTTP_X_FORWARDED' => '10.4.0.5, 10.4.0.4', + 'HTTP_X_FORWARDED_FOR' => '192.168.0.233' + ], + ], + $this->secureRandom, + $this->config, + $this->csrfTokenManager, + $this->stream + ); + + $this->assertSame('192.168.0.233', $request->getRemoteAddress()); + } + + public function testGetRemoteAddressWithNotMatchingCidrTrustedRemote() { + $this->config + ->expects($this->once()) + ->method('getSystemValue') + ->with('trusted_proxies') + ->will($this->returnValue(['192.168.2.0/24'])); + + $request = new Request( + [ + 'server' => [ + 'REMOTE_ADDR' => '192.168.3.99', + 'HTTP_X_FORWARDED' => '10.4.0.5, 10.4.0.4', + 'HTTP_X_FORWARDED_FOR' => '192.168.0.233' + ], + ], + $this->secureRandom, + $this->config, + $this->csrfTokenManager, + $this->stream + ); + + $this->assertSame('192.168.3.99', $request->getRemoteAddress()); + } + /** * @return array */ diff --git a/tests/lib/Authentication/Token/DefaultTokenProviderTest.php b/tests/lib/Authentication/Token/DefaultTokenProviderTest.php index 8b005bd8bdb..57144d0f00d 100644 --- a/tests/lib/Authentication/Token/DefaultTokenProviderTest.php +++ b/tests/lib/Authentication/Token/DefaultTokenProviderTest.php @@ -22,18 +22,17 @@ namespace Test\Authentication\Token; +use OC\Authentication\Exceptions\ExpiredTokenException; use OC\Authentication\Exceptions\InvalidTokenException; use OC\Authentication\Token\DefaultToken; use OC\Authentication\Token\DefaultTokenMapper; use OC\Authentication\Token\DefaultTokenProvider; -use OC\Authentication\Token\ExpiredTokenException; use OC\Authentication\Token\IToken; use OC\Authentication\Token\PublicKeyToken; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Utility\ITimeFactory; use OCP\IConfig; use OCP\ILogger; -use OCP\IUser; use OCP\Security\ICrypto; use Test\TestCase; diff --git a/tests/lib/Authentication/Token/PublicKeyTokenProviderTest.php b/tests/lib/Authentication/Token/PublicKeyTokenProviderTest.php index 02ec62d3d77..ce64878bf5e 100644 --- a/tests/lib/Authentication/Token/PublicKeyTokenProviderTest.php +++ b/tests/lib/Authentication/Token/PublicKeyTokenProviderTest.php @@ -23,19 +23,17 @@ namespace Test\Authentication\Token; +use OC\Authentication\Exceptions\ExpiredTokenException; use OC\Authentication\Exceptions\InvalidTokenException; -use OC\Authentication\Exceptions\PasswordlessTokenException; use OC\Authentication\Token\DefaultToken; use OC\Authentication\Token\PublicKeyToken; use OC\Authentication\Token\PublicKeyTokenMapper; use OC\Authentication\Token\PublicKeyTokenProvider; -use OC\Authentication\Token\ExpiredTokenException; use OC\Authentication\Token\IToken; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Utility\ITimeFactory; use OCP\IConfig; use OCP\ILogger; -use OCP\IUser; use OCP\Security\ICrypto; use Test\TestCase; diff --git a/tests/lib/Collaboration/Collaborators/MailPluginTest.php b/tests/lib/Collaboration/Collaborators/MailPluginTest.php index 775941bd440..a9d0244d38c 100644 --- a/tests/lib/Collaboration/Collaborators/MailPluginTest.php +++ b/tests/lib/Collaboration/Collaborators/MailPluginTest.php @@ -120,16 +120,20 @@ class MailPluginTest extends TestCase { public function dataGetEmail() { return [ + // data set 0 ['test', [], true, ['emails' => [], 'exact' => ['emails' => []]], false, false], + // data set 1 ['test', [], false, ['emails' => [], 'exact' => ['emails' => []]], false, false], + // data set 2 [ 'test@remote.com', [], true, - ['emails' => [], 'exact' => ['emails' => [['label' => 'test@remote.com', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'test@remote.com']]]]], + ['emails' => [], 'exact' => ['emails' => [['uuid' => 'test@remote.com', 'label' => 'test@remote.com', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'test@remote.com']]]]], false, false, ], + // data set 3 [ // no valid email address 'test@remote', [], @@ -138,26 +142,31 @@ class MailPluginTest extends TestCase { false, false, ], + // data set 4 [ 'test@remote.com', [], false, - ['emails' => [], 'exact' => ['emails' => [['label' => 'test@remote.com', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'test@remote.com']]]]], + ['emails' => [], 'exact' => ['emails' => [['uuid' => 'test@remote.com', 'label' => 'test@remote.com', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'test@remote.com']]]]], false, false, ], + // data set 5 [ 'test', [ [ + 'UID' => 'uid3', 'FN' => 'User3 @ Localhost', ], [ + 'UID' => 'uid2', 'FN' => 'User2 @ Localhost', 'EMAIL' => [ ], ], [ + 'UID' => 'uid1', 'FN' => 'User @ Localhost', 'EMAIL' => [ 'username@localhost', @@ -165,22 +174,26 @@ class MailPluginTest extends TestCase { ], ], true, - ['emails' => [['label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'username@localhost']]], 'exact' => ['emails' => []]], + ['emails' => [['uuid' => 'uid1', 'name' => 'User @ Localhost', 'type' => '', 'label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'username@localhost']]], 'exact' => ['emails' => []]], false, false, ], + // data set 6 [ 'test', [ [ + 'UID' => 'uid3', 'FN' => 'User3 @ Localhost', ], [ + 'UID' => 'uid2', 'FN' => 'User2 @ Localhost', 'EMAIL' => [ ], ], [ + 'UID' => 'uid1', 'FN' => 'User @ Localhost', 'EMAIL' => [ 'username@localhost', @@ -192,18 +205,22 @@ class MailPluginTest extends TestCase { false, false, ], + // data set 7 [ 'test@remote.com', [ [ + 'UID' => 'uid3', 'FN' => 'User3 @ Localhost', ], [ + 'UID' => 'uid2', 'FN' => 'User2 @ Localhost', 'EMAIL' => [ ], ], [ + 'UID' => 'uid1', 'FN' => 'User @ Localhost', 'EMAIL' => [ 'username@localhost', @@ -211,22 +228,26 @@ class MailPluginTest extends TestCase { ], ], true, - ['emails' => [['label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'username@localhost']]], 'exact' => ['emails' => [['label' => 'test@remote.com', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'test@remote.com']]]]], + ['emails' => [['uuid' => 'uid1', 'name' => 'User @ Localhost', 'type' => '', 'label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'username@localhost']]], 'exact' => ['emails' => [['label' => 'test@remote.com', 'uuid' => 'test@remote.com', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'test@remote.com']]]]], false, false, ], + // data set 8 [ 'test@remote.com', [ [ + 'UID' => 'uid3', 'FN' => 'User3 @ Localhost', ], [ + 'UID' => 'uid2', 'FN' => 'User2 @ Localhost', 'EMAIL' => [ ], ], [ + 'UID' => 'uid1', 'FN' => 'User @ Localhost', 'EMAIL' => [ 'username@localhost', @@ -234,22 +255,26 @@ class MailPluginTest extends TestCase { ], ], false, - ['emails' => [], 'exact' => ['emails' => [['label' => 'test@remote.com', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'test@remote.com']]]]], + ['emails' => [], 'exact' => ['emails' => [['label' => 'test@remote.com', 'uuid' => 'test@remote.com', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'test@remote.com']]]]], false, false, ], + // data set 9 [ 'username@localhost', [ [ + 'UID' => 'uid3', 'FN' => 'User3 @ Localhost', ], [ + 'UID' => 'uid2', 'FN' => 'User2 @ Localhost', 'EMAIL' => [ ], ], [ + 'UID' => 'uid1', 'FN' => 'User @ Localhost', 'EMAIL' => [ 'username@localhost', @@ -257,22 +282,26 @@ class MailPluginTest extends TestCase { ], ], true, - ['emails' => [], 'exact' => ['emails' => [['label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'username@localhost']]]]], + ['emails' => [], 'exact' => ['emails' => [['name' => 'User @ Localhost', 'uuid' => 'uid1', 'type' => '', 'label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'username@localhost']]]]], true, false, ], + // data set 10 [ 'username@localhost', [ [ + 'UID' => 'uid1', 'FN' => 'User3 @ Localhost', ], [ + 'UID' => 'uid2', 'FN' => 'User2 @ Localhost', 'EMAIL' => [ ], ], [ + 'UID' => 'uid1', 'FN' => 'User @ Localhost', 'EMAIL' => [ 'username@localhost', @@ -280,23 +309,27 @@ class MailPluginTest extends TestCase { ], ], false, - ['emails' => [], 'exact' => ['emails' => [['label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'username@localhost']]]]], + ['emails' => [], 'exact' => ['emails' => [['name' => 'User @ Localhost', 'uuid' => 'uid1', 'type' => '', 'label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'username@localhost']]]]], true, false, ], + // data set 11 // contact with space [ 'user name@localhost', [ [ + 'UID' => 'uid3', 'FN' => 'User3 @ Localhost', ], [ + 'UID' => 'uid2', 'FN' => 'User2 @ Localhost', 'EMAIL' => [ ], ], [ + 'UID' => 'uid1', 'FN' => 'User Name @ Localhost', 'EMAIL' => [ 'user name@localhost', @@ -304,23 +337,27 @@ class MailPluginTest extends TestCase { ], ], false, - ['emails' => [], 'exact' => ['emails' => [['label' => 'User Name @ Localhost (user name@localhost)', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'user name@localhost']]]]], + ['emails' => [], 'exact' => ['emails' => [['name' => 'User Name @ Localhost', 'uuid' => 'uid1', 'type' => '', 'label' => 'User Name @ Localhost (user name@localhost)', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'user name@localhost']]]]], true, false, ], + // data set 12 // remote with space, no contact [ 'user space@remote.com', [ [ + 'UID' => 'uid3', 'FN' => 'User3 @ Localhost', ], [ + 'UID' => 'uid2', 'FN' => 'User2 @ Localhost', 'EMAIL' => [ ], ], [ + 'UID' => 'uid1', 'FN' => 'User @ Localhost', 'EMAIL' => [ 'username@localhost', @@ -332,11 +369,13 @@ class MailPluginTest extends TestCase { false, false, ], + // data set 13 // Local user found by email [ 'test@example.com', [ [ + 'UID' => 'uid1', 'FN' => 'User', 'EMAIL' => ['test@example.com'], 'CLOUD' => ['test@localhost'], @@ -344,15 +383,17 @@ class MailPluginTest extends TestCase { ] ], false, - ['users' => [], 'exact' => ['users' => [['label' => 'User (test@example.com)','value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test'],]]]], + ['users' => [], 'exact' => ['users' => [['uuid' => 'uid1', 'name' => 'User', 'label' => 'User (test@example.com)','value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test'],]]]], true, false, ], + // data set 14 // Current local user found by email => no result [ 'test@example.com', [ [ + 'UID' => 'uid1', 'FN' => 'User', 'EMAIL' => ['test@example.com'], 'CLOUD' => ['current@localhost'], @@ -364,29 +405,34 @@ class MailPluginTest extends TestCase { false, false, ], + // data set 15 // Pagination and "more results" for user matches byyyyyyy emails [ 'test@example', [ [ + 'UID' => 'uid1', 'FN' => 'User1', 'EMAIL' => ['test@example.com'], 'CLOUD' => ['test1@localhost'], 'isLocalSystemBook' => true, ], [ + 'UID' => 'uid2', 'FN' => 'User2', 'EMAIL' => ['test@example.de'], 'CLOUD' => ['test2@localhost'], 'isLocalSystemBook' => true, ], [ + 'UID' => 'uid3', 'FN' => 'User3', 'EMAIL' => ['test@example.org'], 'CLOUD' => ['test3@localhost'], 'isLocalSystemBook' => true, ], [ + 'UID' => 'uid4', 'FN' => 'User4', 'EMAIL' => ['test@example.net'], 'CLOUD' => ['test4@localhost'], @@ -395,32 +441,37 @@ class MailPluginTest extends TestCase { ], true, ['users' => [ - ['label' => 'User1 (test@example.com)', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']], - ['label' => 'User2 (test@example.de)', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test2']], + ['uuid' => 'uid1', 'name' => 'User1', 'label' => 'User1 (test@example.com)', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']], + ['uuid' => 'uid2', 'name' => 'User2', 'label' => 'User2 (test@example.de)', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test2']], ], 'emails' => [], 'exact' => ['users' => [], 'emails' => []]], false, true, ], + // data set 16 // Pagination and "more results" for normal emails [ 'test@example', [ [ + 'UID' => 'uid1', 'FN' => 'User1', 'EMAIL' => ['test@example.com'], 'CLOUD' => ['test1@localhost'], ], [ + 'UID' => 'uid2', 'FN' => 'User2', 'EMAIL' => ['test@example.de'], 'CLOUD' => ['test2@localhost'], ], [ + 'UID' => 'uid3', 'FN' => 'User3', 'EMAIL' => ['test@example.org'], 'CLOUD' => ['test3@localhost'], ], [ + 'UID' => 'uid4', 'FN' => 'User4', 'EMAIL' => ['test@example.net'], 'CLOUD' => ['test4@localhost'], @@ -428,12 +479,45 @@ class MailPluginTest extends TestCase { ], true, ['emails' => [ - ['label' => 'User1 (test@example.com)', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'test@example.com']], - ['label' => 'User2 (test@example.de)', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'test@example.de']], + ['uuid' => 'uid1', 'name' => 'User1', 'type' => '', 'label' => 'User1 (test@example.com)', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'test@example.com']], + ['uuid' => 'uid2', 'name' => 'User2', 'type' => '', 'label' => 'User2 (test@example.de)', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'test@example.de']], ], 'exact' => ['emails' => []]], false, true, ], + // data set 17 + // multiple email addresses with type + [ + 'User Name', + [ + [ + 'UID' => 'uid3', + 'FN' => 'User3', + ], + [ + 'UID' => 'uid2', + 'FN' => 'User2', + 'EMAIL' => [ + ], + ], + [ + 'UID' => 'uid1', + 'FN' => 'User Name', + 'EMAIL' => [ + ['type' => 'HOME', 'value' => 'username@localhost'], + ['type' => 'WORK', 'value' => 'username@other'], + ], + ], + ], + false, + ['emails' => [ + ], 'exact' => ['emails' => [ + ['name' => 'User Name', 'uuid' => 'uid1', 'type' => 'HOME', 'label' => 'User Name (username@localhost)', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'username@localhost']], + ['name' => 'User Name', 'uuid' => 'uid1', 'type' => 'WORK', 'label' => 'User Name (username@other)', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'username@other']] + ]]], + false, + false, + ], ]; } @@ -513,7 +597,7 @@ class MailPluginTest extends TestCase { 'UID' => 'User' ] ], - ['users' => [['label' => 'User (test@example.com)','value' => ['shareType' => 0, 'shareWith' => 'test'],]], 'emails' => [], 'exact' => ['emails' => [], 'users' => []]], + ['users' => [['label' => 'User (test@example.com)', 'uuid' => 'User', 'name' => 'User', 'value' => ['shareType' => 0, 'shareWith' => 'test'],]], 'emails' => [], 'exact' => ['emails' => [], 'users' => []]], false, false, [ @@ -553,7 +637,7 @@ class MailPluginTest extends TestCase { 'UID' => 'User' ] ], - ['emails' => [], 'exact' => ['emails' => [['label' => 'test@example.com', 'value' => ['shareType' => 4,'shareWith' => 'test@example.com']]]]], + ['emails' => [], 'exact' => ['emails' => [['label' => 'test@example.com', 'uuid' => 'test@example.com', 'value' => ['shareType' => 4,'shareWith' => 'test@example.com']]]]], false, false, [ diff --git a/tests/lib/Collaboration/Collaborators/RemotePluginTest.php b/tests/lib/Collaboration/Collaborators/RemotePluginTest.php index aa009a7134b..aff68185767 100644 --- a/tests/lib/Collaboration/Collaborators/RemotePluginTest.php +++ b/tests/lib/Collaboration/Collaborators/RemotePluginTest.php @@ -31,10 +31,17 @@ use OCP\Collaboration\Collaborators\SearchResultType; use OCP\Contacts\IManager; use OCP\Federation\ICloudIdManager; use OCP\IConfig; +use OCP\IUser; +use OCP\IUserManager; +use OCP\IUserSession; use OCP\Share; use Test\TestCase; class RemotePluginTest extends TestCase { + + /** @var IUserManager|\PHPUnit_Framework_MockObject_MockObject */ + protected $userManager; + /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */ protected $config; @@ -53,6 +60,7 @@ class RemotePluginTest extends TestCase { public function setUp() { parent::setUp(); + $this->userManager = $this->createMock(IUserManager::class); $this->config = $this->createMock(IConfig::class); $this->contactsManager = $this->createMock(IManager::class); $this->cloudIdManager = new CloudIdManager(); @@ -60,7 +68,15 @@ class RemotePluginTest extends TestCase { } public function instantiatePlugin() { - $this->plugin = new RemotePlugin($this->contactsManager, $this->cloudIdManager, $this->config); + $user = $this->createMock(IUser::class); + $user->expects($this->any()) + ->method('getUID') + ->willReturn('admin'); + $userSession = $this->createMock(IUserSession::class); + $userSession->expects($this->any()) + ->method('getUser') + ->willReturn($user); + $this->plugin = new RemotePlugin($this->contactsManager, $this->cloudIdManager, $this->config, $this->userManager, $userSession); } /** @@ -152,14 +168,17 @@ class RemotePluginTest extends TestCase { 'test', [ [ + 'UID' => 'uid', 'FN' => 'User3 @ Localhost', ], [ + 'UID' => 'uid', 'FN' => 'User2 @ Localhost', 'CLOUD' => [ ], ], [ + 'UID' => 'uid1', 'FN' => 'User @ Localhost', 'CLOUD' => [ 'username@localhost', @@ -167,7 +186,7 @@ class RemotePluginTest extends TestCase { ], ], true, - ['remotes' => [['label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'username@localhost', 'server' => 'localhost']]], 'exact' => ['remotes' => []]], + ['remotes' => [['name' => 'User @ Localhost', 'label' => 'User @ Localhost (username@localhost)', 'uuid' => 'uid1', 'type' => '', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'username@localhost', 'server' => 'localhost']]], 'exact' => ['remotes' => []]], false, true, ], @@ -175,14 +194,17 @@ class RemotePluginTest extends TestCase { 'test', [ [ + 'UID' => 'uid', 'FN' => 'User3 @ Localhost', ], [ + 'UID' => 'uid', 'FN' => 'User2 @ Localhost', 'CLOUD' => [ ], ], [ + 'UID' => 'uid', 'FN' => 'User @ Localhost', 'CLOUD' => [ 'username@localhost', @@ -198,14 +220,17 @@ class RemotePluginTest extends TestCase { 'test@remote', [ [ + 'UID' => 'uid', 'FN' => 'User3 @ Localhost', ], [ + 'UID' => 'uid', 'FN' => 'User2 @ Localhost', 'CLOUD' => [ ], ], [ + 'UID' => 'uid', 'FN' => 'User @ Localhost', 'CLOUD' => [ 'username@localhost', @@ -213,7 +238,7 @@ class RemotePluginTest extends TestCase { ], ], true, - ['remotes' => [['label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'username@localhost', 'server' => 'localhost']]], 'exact' => ['remotes' => [['label' => 'test@remote', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'test@remote']]]]], + ['remotes' => [['name' => 'User @ Localhost', 'label' => 'User @ Localhost (username@localhost)', 'uuid' => 'uid', 'type' => '', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'username@localhost', 'server' => 'localhost']]], 'exact' => ['remotes' => [['label' => 'test@remote', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'test@remote']]]]], false, true, ], @@ -221,14 +246,17 @@ class RemotePluginTest extends TestCase { 'test@remote', [ [ + 'UID' => 'uid', 'FN' => 'User3 @ Localhost', ], [ + 'UID' => 'uid', 'FN' => 'User2 @ Localhost', 'CLOUD' => [ ], ], [ + 'UID' => 'uid', 'FN' => 'User @ Localhost', 'CLOUD' => [ 'username@localhost', @@ -244,14 +272,17 @@ class RemotePluginTest extends TestCase { 'username@localhost', [ [ + 'UID' => 'uid3', 'FN' => 'User3 @ Localhost', ], [ + 'UID' => '2', 'FN' => 'User2 @ Localhost', 'CLOUD' => [ ], ], [ + 'UID' => 'uid1', 'FN' => 'User @ Localhost', 'CLOUD' => [ 'username@localhost', @@ -259,7 +290,7 @@ class RemotePluginTest extends TestCase { ], ], true, - ['remotes' => [], 'exact' => ['remotes' => [['label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'username@localhost', 'server' => 'localhost']]]]], + ['remotes' => [], 'exact' => ['remotes' => [['name' => 'User @ Localhost', 'label' => 'User @ Localhost (username@localhost)', 'uuid' => 'uid1', 'type' => '', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'username@localhost', 'server' => 'localhost']]]]], true, true, ], @@ -267,14 +298,17 @@ class RemotePluginTest extends TestCase { 'username@localhost', [ [ + 'UID' => 'uid3', 'FN' => 'User3 @ Localhost', ], [ + 'UID' => 'uid2', 'FN' => 'User2 @ Localhost', 'CLOUD' => [ ], ], [ + 'UID' => 'uid1', 'FN' => 'User @ Localhost', 'CLOUD' => [ 'username@localhost', @@ -282,7 +316,7 @@ class RemotePluginTest extends TestCase { ], ], false, - ['remotes' => [], 'exact' => ['remotes' => [['label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'username@localhost', 'server' => 'localhost']]]]], + ['remotes' => [], 'exact' => ['remotes' => [['name' => 'User @ Localhost', 'label' => 'User @ Localhost (username@localhost)', 'uuid' => 'uid1', 'type' => '', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'username@localhost', 'server' => 'localhost']]]]], true, true, ], @@ -291,14 +325,17 @@ class RemotePluginTest extends TestCase { 'user name@localhost', [ [ + 'UID' => 'uid1', 'FN' => 'User3 @ Localhost', ], [ + 'UID' => 'uid2', 'FN' => 'User2 @ Localhost', 'CLOUD' => [ ], ], [ + 'UID' => 'uid3', 'FN' => 'User Name @ Localhost', 'CLOUD' => [ 'user name@localhost', @@ -306,7 +343,7 @@ class RemotePluginTest extends TestCase { ], ], false, - ['remotes' => [], 'exact' => ['remotes' => [['label' => 'User Name @ Localhost (user name@localhost)', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'user name@localhost', 'server' => 'localhost']]]]], + ['remotes' => [], 'exact' => ['remotes' => [['name' => 'User Name @ Localhost', 'label' => 'User Name @ Localhost (user name@localhost)', 'uuid' => 'uid3', 'type' => '', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'user name@localhost', 'server' => 'localhost']]]]], true, true, ], @@ -315,14 +352,17 @@ class RemotePluginTest extends TestCase { 'user space@remote', [ [ + 'UID' => 'uid3', 'FN' => 'User3 @ Localhost', ], [ + 'UID' => 'uid2', 'FN' => 'User2 @ Localhost', 'CLOUD' => [ ], ], [ + 'UID' => 'uid1', 'FN' => 'User @ Localhost', 'CLOUD' => [ 'username@localhost', diff --git a/tests/lib/Files/Storage/Storage.php b/tests/lib/Files/Storage/Storage.php index 04aafece2e3..a25a3f74f9e 100644 --- a/tests/lib/Files/Storage/Storage.php +++ b/tests/lib/Files/Storage/Storage.php @@ -23,6 +23,7 @@ namespace Test\Files\Storage; use OC\Files\Cache\Watcher; +use OCP\Files\Storage\IWriteStreamStorage; abstract class Storage extends \Test\TestCase { /** @@ -628,4 +629,20 @@ abstract class Storage extends \Test\TestCase { $this->instance->rename('bar.txt.part', 'bar.txt'); $this->assertEquals('bar', $this->instance->file_get_contents('bar.txt')); } + + public function testWriteStream() { + $textFile = \OC::$SERVERROOT . '/tests/data/lorem.txt'; + + if (!$this->instance->instanceOfStorage(IWriteStreamStorage::class)) { + $this->markTestSkipped('Not a WriteSteamStorage'); + } + /** @var IWriteStreamStorage $storage */ + $storage = $this->instance; + + $source = fopen($textFile, 'r'); + + $storage->writeStream('test.txt', $source); + $this->assertTrue($storage->file_exists('test.txt')); + $this->assertEquals(file_get_contents($textFile), $storage->file_get_contents('test.txt')); + } } diff --git a/tests/lib/Files/Stream/CountReadStreamTest.php b/tests/lib/Files/Stream/CountReadStreamTest.php new file mode 100644 index 00000000000..99291d1644f --- /dev/null +++ b/tests/lib/Files/Stream/CountReadStreamTest.php @@ -0,0 +1,49 @@ +<?php declare(strict_types=1); +/** + * @copyright Copyright (c) 2018 Robin Appelman <robin@icewind.nl> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace Test\Files\Stream; + +use OC\Files\Stream\CountReadStream; +use Test\TestCase; + +class CountReadStreamTest extends TestCase { + private function getStream($data) { + $handle = fopen('php://temp', 'w+'); + fwrite($handle, $data); + rewind($handle); + return $handle; + } + + public function testBasicCount() { + $source = $this->getStream('foo'); + $stream = CountReadStream::wrap($source, function ($size) { + $this->assertEquals(3, $size); + }); + stream_get_contents($stream); + } + + public function testLarger() { + $stream = CountReadStream::wrap(fopen(__DIR__ . '/../../../data/testimage.mp4', 'r'), function ($size) { + $this->assertEquals(383631, $size); + }); + stream_get_contents($stream); + } +} diff --git a/tests/lib/Preview/GeneratorTest.php b/tests/lib/Preview/GeneratorTest.php index 64786fa9fe8..565b526b659 100644 --- a/tests/lib/Preview/GeneratorTest.php +++ b/tests/lib/Preview/GeneratorTest.php @@ -104,7 +104,7 @@ class GeneratorTest extends \Test\TestCase { $previewFile = $this->createMock(ISimpleFile::class); $previewFolder->method('getFile') - ->with($this->equalTo('128-128.png')) + ->with($this->equalTo('256-256.png')) ->willReturn($previewFile); $this->eventDispatcher->expects($this->once()) @@ -212,7 +212,7 @@ class GeneratorTest extends \Test\TestCase { ->will($this->returnCallback(function($filename) use ($maxPreview, $previewFile) { if ($filename === '2048-2048-max.png') { return $maxPreview; - } else if ($filename === '128-128.png') { + } else if ($filename === '256-256.png') { return $previewFile; } $this->fail('Unexpected file'); @@ -223,7 +223,7 @@ class GeneratorTest extends \Test\TestCase { ->with($this->equalTo('my data')); $previewFolder->method('getFile') - ->with($this->equalTo('128-128.png')) + ->with($this->equalTo('256-256.png')) ->willThrowException(new NotFoundException()); $image = $this->createMock(IImage::class); @@ -233,7 +233,7 @@ class GeneratorTest extends \Test\TestCase { $image->expects($this->once()) ->method('resize') - ->with(128); + ->with(256); $image->method('data') ->willReturn('my resized data'); $image->method('valid')->willReturn(true); @@ -328,8 +328,8 @@ class GeneratorTest extends \Test\TestCase { return [ [1024, 2048, 512, 512, false, IPreview::MODE_FILL, 256, 512], [1024, 2048, 512, 512, false, IPreview::MODE_COVER, 512, 1024], - [1024, 2048, 512, 512, true, IPreview::MODE_FILL, 512, 512], - [1024, 2048, 512, 512, true, IPreview::MODE_COVER, 512, 512], + [1024, 2048, 512, 512, true, IPreview::MODE_FILL, 1024, 1024], + [1024, 2048, 512, 512, true, IPreview::MODE_COVER, 1024, 1024], [1024, 2048, -1, 512, false, IPreview::MODE_COVER, 256, 512], [1024, 2048, 512, -1, false, IPreview::MODE_FILL, 512, 1024], @@ -343,14 +343,20 @@ class GeneratorTest extends \Test\TestCase { [2048, 1024, 512, 512, false, IPreview::MODE_FILL, 512, 256], [2048, 1024, 512, 512, false, IPreview::MODE_COVER, 1024, 512], - [2048, 1024, 512, 512, true, IPreview::MODE_FILL, 512, 512], - [2048, 1024, 512, 512, true, IPreview::MODE_COVER, 512, 512], + [2048, 1024, 512, 512, true, IPreview::MODE_FILL, 1024, 1024], + [2048, 1024, 512, 512, true, IPreview::MODE_COVER, 1024, 1024], [2048, 1024, -1, 512, false, IPreview::MODE_FILL, 1024, 512], [2048, 1024, 512, -1, false, IPreview::MODE_COVER, 512, 256], [2048, 1024, 4096, 1024, true, IPreview::MODE_FILL, 2048, 512], [2048, 1024, 4096, 1024, true, IPreview::MODE_COVER, 2048, 512], + + //Test minimum size + [2048, 1024, 32, 32, false, IPreview::MODE_FILL, 64, 32], + [2048, 1024, 32, 32, false, IPreview::MODE_COVER, 64, 32], + [2048, 1024, 32, 32, true, IPreview::MODE_FILL, 64, 64], + [2048, 1024, 32, 32, true, IPreview::MODE_COVER, 64, 64], ]; } diff --git a/tests/lib/Template/IconsCacherTest.php b/tests/lib/Template/IconsCacherTest.php index 33735e3a45e..c537323e0eb 100644 --- a/tests/lib/Template/IconsCacherTest.php +++ b/tests/lib/Template/IconsCacherTest.php @@ -104,7 +104,7 @@ class IconsCacherTest extends \Test\TestCase { public function testSetIconsFromValidCss() { $css = " icon.test { - --icon-test: url('/index.php/svg/core/actions/add/000?v=1'); + --icon-test: url('/index.php/svg/core/actions/add?color=000&v=1'); background-image: var(--icon-test); } "; @@ -127,7 +127,7 @@ class IconsCacherTest extends \Test\TestCase { public function testSetIconsFromValidCssMultipleTimes() { $css = " icon.test { - --icon-test: url('/index.php/svg/core/actions/add/000?v=1'); + --icon-test: url('/index.php/svg/core/actions/add?color=000&v=1'); background-image: var(--icon-test); } "; diff --git a/version.php b/version.php index c3740f01fa3..93a8b5fd53e 100644 --- a/version.php +++ b/version.php @@ -29,7 +29,7 @@ // between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel // when updating major/minor version number. -$OC_Version = array(15, 0, 0, 1); +$OC_Version = array(15, 0, 0, 2); // The human readable string $OC_VersionString = '15.0.0 alpha'; |