Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>2018-11-01 19:33:50 +0300
committerJohn Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>2018-11-01 19:33:58 +0300
commit98f30c2dab24f0ab80015ef7849a7d8875651f6f (patch)
tree9de386977ed99c6627410de53d0cfdfaccf4616c
parentabed75e5cbd200169a236f3b586553e5d9ed0452 (diff)
parent7246f2ace50e41f68433cd89755413b512fa7909 (diff)
Merge branch 'addressbook-uid-check-migration' of https://github.com/nextcloud/server into addressbook-uid-check-migration
Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
-rw-r--r--apps/dav/lib/CalDAV/Schedule/IMipPlugin.php2
-rw-r--r--apps/dav/lib/CardDAV/AddressBookImpl.php35
-rw-r--r--apps/dav/lib/CardDAV/CardDavBackend.php4
-rw-r--r--apps/dav/lib/Connector/Sabre/File.php27
-rw-r--r--apps/dav/tests/unit/Connector/Sabre/FileTest.php6
-rw-r--r--apps/files/css/detailsView.scss10
-rw-r--r--apps/files/css/files.scss16
-rw-r--r--apps/files/js/detailsview.js3
-rw-r--r--apps/files/js/detailtabview.js15
-rw-r--r--apps/files/l10n/cs.js1
-rw-r--r--apps/files/l10n/cs.json1
-rw-r--r--apps/files_external/js/app.js28
-rw-r--r--apps/files_external/js/mountsfilelist.js10
-rw-r--r--apps/files_external/js/oauth1.js6
-rw-r--r--apps/files_external/js/oauth2.js6
-rw-r--r--apps/files_external/js/public_key.js4
-rw-r--r--apps/files_external/js/rollingqueue.js10
-rw-r--r--apps/files_external/js/settings.js54
-rw-r--r--apps/files_external/js/statusmanager.js56
-rw-r--r--apps/files_external/js/templates.js2
-rw-r--r--apps/files_external/tests/appSpec.js4
-rw-r--r--apps/files_external/tests/js/mountsfilelistSpec.js4
-rw-r--r--apps/files_external/tests/js/settingsSpec.js4
-rw-r--r--apps/files_sharing/css/sharetabview.scss29
-rw-r--r--apps/files_sharing/lib/Controller/ShareAPIController.php14
-rw-r--r--apps/files_sharing/lib/Controller/ShareController.php15
-rw-r--r--apps/files_sharing/templates/public.php9
-rw-r--r--apps/files_sharing/tests/Controller/ShareAPIControllerTest.php21
-rw-r--r--apps/files_sharing/tests/Controller/ShareControllerTest.php117
-rw-r--r--apps/files_versions/appinfo/info.xml4
-rw-r--r--apps/files_versions/composer/composer/autoload_classmap.php7
-rw-r--r--apps/files_versions/composer/composer/autoload_static.php7
-rw-r--r--apps/files_versions/js/versionstabview.js4
-rw-r--r--apps/files_versions/lib/AppInfo/Application.php48
-rw-r--r--apps/files_versions/lib/Controller/PreviewController.php47
-rw-r--r--apps/files_versions/lib/Sabre/RestoreFolder.php12
-rw-r--r--apps/files_versions/lib/Sabre/RootCollection.php25
-rw-r--r--apps/files_versions/lib/Sabre/VersionCollection.php22
-rw-r--r--apps/files_versions/lib/Sabre/VersionFile.php41
-rw-r--r--apps/files_versions/lib/Sabre/VersionHome.php37
-rw-r--r--apps/files_versions/lib/Sabre/VersionRoot.php18
-rw-r--r--apps/files_versions/lib/Storage.php25
-rw-r--r--apps/files_versions/lib/Versions/BackendNotFoundException.php26
-rw-r--r--apps/files_versions/lib/Versions/IVersion.php99
-rw-r--r--apps/files_versions/lib/Versions/IVersionBackend.php81
-rw-r--r--apps/files_versions/lib/Versions/IVersionManager.php36
-rw-r--r--apps/files_versions/lib/Versions/LegacyVersionsBackend.php105
-rw-r--r--apps/files_versions/lib/Versions/Version.php113
-rw-r--r--apps/files_versions/lib/Versions/VersionManager.php93
-rw-r--r--apps/files_versions/tests/Controller/PreviewControllerTest.php55
-rw-r--r--apps/oauth2/lib/Controller/OauthApiController.php12
-rw-r--r--apps/oauth2/tests/Controller/OauthApiControllerTest.php44
-rw-r--r--apps/sharebymail/tests/CapabilitiesTest.php51
-rw-r--r--apps/systemtags/tests/Activity/SettingTest.php72
-rw-r--r--apps/user_ldap/composer/composer/autoload_classmap.php1
-rw-r--r--apps/user_ldap/composer/composer/autoload_static.php1
-rw-r--r--apps/user_ldap/lib/Access.php3
-rw-r--r--apps/user_ldap/lib/User/IUserTools.php42
-rw-r--r--apps/user_ldap/lib/User/Manager.php10
-rw-r--r--apps/user_ldap/lib/User/User.php21
-rw-r--r--apps/user_ldap/tests/User/ManagerTest.php224
-rw-r--r--apps/user_ldap/tests/User/UserTest.php43
-rwxr-xr-xbuild/compile-handlebars-templates.sh2
-rw-r--r--config/config.sample.php31
-rw-r--r--core/Controller/LoginController.php8
-rw-r--r--core/Migrations/Version15000Date20181015062942.php54
-rw-r--r--core/css/apps.scss30
-rw-r--r--core/css/css-variables.scss2
-rw-r--r--core/css/global.scss6
-rw-r--r--core/css/header.scss101
-rw-r--r--core/css/icons.scss4
-rw-r--r--core/css/inputs.scss1
-rw-r--r--core/css/jquery-ui-fixes.scss8
-rw-r--r--core/css/styles.scss10
-rw-r--r--core/css/variables.scss1
-rw-r--r--core/js/share/sharedialoglinkshareview_popover_menu.handlebars10
-rw-r--r--core/js/sharedialoglinkshareview.js22
-rw-r--r--core/js/sharedialogshareelistview.js4
-rw-r--r--core/js/sharedialogview.js110
-rw-r--r--core/js/shareitemmodel.js11
-rw-r--r--core/js/sharetemplates.js53
-rw-r--r--core/js/tests/specs/sharedialoglinkshareview.js94
-rw-r--r--core/js/tests/specs/sharedialogshareelistview.js31
-rw-r--r--core/js/tests/specs/shareitemmodelSpec.js13
-rw-r--r--core/l10n/af.js6
-rw-r--r--core/l10n/af.json6
-rw-r--r--core/l10n/ast.js4
-rw-r--r--core/l10n/ast.json4
-rw-r--r--core/l10n/bg.js8
-rw-r--r--core/l10n/bg.json8
-rw-r--r--core/l10n/ca.js8
-rw-r--r--core/l10n/ca.json8
-rw-r--r--core/l10n/cs.js9
-rw-r--r--core/l10n/cs.json9
-rw-r--r--core/l10n/da.js6
-rw-r--r--core/l10n/da.json6
-rw-r--r--core/l10n/de.js11
-rw-r--r--core/l10n/de.json11
-rw-r--r--core/l10n/de_DE.js11
-rw-r--r--core/l10n/de_DE.json11
-rw-r--r--core/l10n/el.js6
-rw-r--r--core/l10n/el.json6
-rw-r--r--core/l10n/en_GB.js6
-rw-r--r--core/l10n/en_GB.json6
-rw-r--r--core/l10n/eo.js6
-rw-r--r--core/l10n/eo.json6
-rw-r--r--core/l10n/es.js8
-rw-r--r--core/l10n/es.json8
-rw-r--r--core/l10n/es_419.js6
-rw-r--r--core/l10n/es_419.json6
-rw-r--r--core/l10n/es_AR.js6
-rw-r--r--core/l10n/es_AR.json6
-rw-r--r--core/l10n/es_CL.js6
-rw-r--r--core/l10n/es_CL.json6
-rw-r--r--core/l10n/es_CO.js6
-rw-r--r--core/l10n/es_CO.json6
-rw-r--r--core/l10n/es_CR.js6
-rw-r--r--core/l10n/es_CR.json6
-rw-r--r--core/l10n/es_DO.js6
-rw-r--r--core/l10n/es_DO.json6
-rw-r--r--core/l10n/es_EC.js6
-rw-r--r--core/l10n/es_EC.json6
-rw-r--r--core/l10n/es_GT.js6
-rw-r--r--core/l10n/es_GT.json6
-rw-r--r--core/l10n/es_HN.js6
-rw-r--r--core/l10n/es_HN.json6
-rw-r--r--core/l10n/es_MX.js6
-rw-r--r--core/l10n/es_MX.json6
-rw-r--r--core/l10n/es_NI.js6
-rw-r--r--core/l10n/es_NI.json6
-rw-r--r--core/l10n/es_PA.js6
-rw-r--r--core/l10n/es_PA.json6
-rw-r--r--core/l10n/es_PE.js6
-rw-r--r--core/l10n/es_PE.json6
-rw-r--r--core/l10n/es_PR.js6
-rw-r--r--core/l10n/es_PR.json6
-rw-r--r--core/l10n/es_PY.js6
-rw-r--r--core/l10n/es_PY.json6
-rw-r--r--core/l10n/es_SV.js6
-rw-r--r--core/l10n/es_SV.json6
-rw-r--r--core/l10n/es_UY.js6
-rw-r--r--core/l10n/es_UY.json6
-rw-r--r--core/l10n/et_EE.js6
-rw-r--r--core/l10n/et_EE.json6
-rw-r--r--core/l10n/eu.js6
-rw-r--r--core/l10n/eu.json6
-rw-r--r--core/l10n/fa.js6
-rw-r--r--core/l10n/fa.json6
-rw-r--r--core/l10n/fi.js6
-rw-r--r--core/l10n/fi.json6
-rw-r--r--core/l10n/fr.js8
-rw-r--r--core/l10n/fr.json8
-rw-r--r--core/l10n/he.js8
-rw-r--r--core/l10n/he.json8
-rw-r--r--core/l10n/hu.js6
-rw-r--r--core/l10n/hu.json6
-rw-r--r--core/l10n/id.js6
-rw-r--r--core/l10n/id.json6
-rw-r--r--core/l10n/is.js8
-rw-r--r--core/l10n/is.json8
-rw-r--r--core/l10n/it.js11
-rw-r--r--core/l10n/it.json11
-rw-r--r--core/l10n/ja.js6
-rw-r--r--core/l10n/ja.json6
-rw-r--r--core/l10n/ka_GE.js6
-rw-r--r--core/l10n/ka_GE.json6
-rw-r--r--core/l10n/ko.js6
-rw-r--r--core/l10n/ko.json6
-rw-r--r--core/l10n/lt_LT.js6
-rw-r--r--core/l10n/lt_LT.json6
-rw-r--r--core/l10n/lv.js6
-rw-r--r--core/l10n/lv.json6
-rw-r--r--core/l10n/nb.js8
-rw-r--r--core/l10n/nb.json8
-rw-r--r--core/l10n/nl.js8
-rw-r--r--core/l10n/nl.json8
-rw-r--r--core/l10n/pl.js8
-rw-r--r--core/l10n/pl.json8
-rw-r--r--core/l10n/pt_BR.js11
-rw-r--r--core/l10n/pt_BR.json11
-rw-r--r--core/l10n/pt_PT.js6
-rw-r--r--core/l10n/pt_PT.json6
-rw-r--r--core/l10n/ro.js6
-rw-r--r--core/l10n/ro.json6
-rw-r--r--core/l10n/ru.js8
-rw-r--r--core/l10n/ru.json8
-rw-r--r--core/l10n/sk.js8
-rw-r--r--core/l10n/sk.json8
-rw-r--r--core/l10n/sl.js6
-rw-r--r--core/l10n/sl.json6
-rw-r--r--core/l10n/sq.js6
-rw-r--r--core/l10n/sq.json6
-rw-r--r--core/l10n/sr.js8
-rw-r--r--core/l10n/sr.json8
-rw-r--r--core/l10n/sv.js6
-rw-r--r--core/l10n/sv.json6
-rw-r--r--core/l10n/tr.js11
-rw-r--r--core/l10n/tr.json11
-rw-r--r--core/l10n/uk.js6
-rw-r--r--core/l10n/uk.json6
-rw-r--r--core/l10n/vi.js6
-rw-r--r--core/l10n/vi.json6
-rw-r--r--core/l10n/zh_CN.js8
-rw-r--r--core/l10n/zh_CN.json8
-rw-r--r--core/l10n/zh_TW.js8
-rw-r--r--core/l10n/zh_TW.json8
-rw-r--r--core/templates/layout.user.php4
-rw-r--r--core/templates/login.php4
-rw-r--r--lib/composer/composer/autoload_classmap.php23
-rw-r--r--lib/composer/composer/autoload_static.php23
-rw-r--r--lib/private/Authentication/Exceptions/ExpiredTokenException.php4
-rw-r--r--lib/private/Authentication/Token/DefaultTokenProvider.php1
-rw-r--r--lib/private/Authentication/Token/IProvider.php1
-rw-r--r--lib/private/Authentication/Token/Manager.php1
-rw-r--r--lib/private/Authentication/Token/PublicKeyTokenProvider.php1
-rw-r--r--lib/private/Collaboration/Collaborators/MailPlugin.php21
-rw-r--r--lib/private/Collaboration/Collaborators/RemotePlugin.php69
-rw-r--r--lib/private/Files/ObjectStore/ObjectStoreStorage.php68
-rw-r--r--lib/private/Files/Storage/Common.php22
-rw-r--r--lib/private/Files/Storage/Local.php4
-rw-r--r--lib/private/Files/Storage/Wrapper/Encryption.php9
-rw-r--r--lib/private/Files/Storage/Wrapper/Jail.php15
-rw-r--r--lib/private/Files/Storage/Wrapper/Wrapper.php17
-rw-r--r--lib/private/Files/Stream/CountReadStream.php65
-rw-r--r--lib/private/FullTextSearch/FullTextSearchManager.php227
-rw-r--r--lib/private/Preview/Generator.php18
-rw-r--r--lib/private/Server.php6
-rw-r--r--lib/private/Share20/DefaultShareProvider.php2
-rw-r--r--lib/private/Share20/Share.php13
-rw-r--r--lib/private/User/Session.php12
-rw-r--r--lib/public/Files/Storage/IWriteStreamStorage.php40
-rw-r--r--lib/public/Files_FullTextSearch/Model/AFilesDocument.php112
-rw-r--r--lib/public/FullTextSearch/Exceptions/FullTextSearchAppNotAvailableException.php42
-rw-r--r--lib/public/FullTextSearch/IFullTextSearchManager.php186
-rw-r--r--lib/public/FullTextSearch/IFullTextSearchPlatform.php227
-rw-r--r--lib/public/FullTextSearch/IFullTextSearchProvider.php304
-rw-r--r--lib/public/FullTextSearch/Model/DocumentAccess.php363
-rw-r--r--lib/public/FullTextSearch/Model/IIndex.php292
-rw-r--r--lib/public/FullTextSearch/Model/IIndexOptions.php86
-rw-r--r--lib/public/FullTextSearch/Model/IRunner.php142
-rw-r--r--lib/public/FullTextSearch/Model/ISearchRequest.php326
-rw-r--r--lib/public/FullTextSearch/Model/ISearchResult.php198
-rw-r--r--lib/public/FullTextSearch/Model/IndexDocument.php898
-rw-r--r--lib/public/FullTextSearch/Model/SearchOption.php296
-rw-r--r--lib/public/FullTextSearch/Model/SearchTemplate.php258
-rw-r--r--lib/public/FullTextSearch/Service/IIndexService.php99
-rw-r--r--lib/public/FullTextSearch/Service/IProviderService.php65
-rw-r--r--lib/public/FullTextSearch/Service/ISearchService.php89
-rw-r--r--lib/public/IAddressBook.php14
-rw-r--r--lib/public/Share/IShare.php21
-rw-r--r--resources/app-info.xsd17
-rw-r--r--settings/BackgroundJobs/VerifyUserData.php4
-rw-r--r--settings/js/admin.js7
-rw-r--r--tests/Core/Controller/LoginControllerTest.php20
-rw-r--r--tests/acceptance/features/app-files.feature26
-rw-r--r--tests/acceptance/features/bootstrap/FilesAppContext.php61
-rw-r--r--tests/acceptance/features/bootstrap/FilesSharingAppContext.php40
-rw-r--r--tests/lib/Authentication/Token/DefaultTokenProviderTest.php3
-rw-r--r--tests/lib/Authentication/Token/PublicKeyTokenProviderTest.php4
-rw-r--r--tests/lib/Collaboration/Collaborators/MailPluginTest.php114
-rw-r--r--tests/lib/Collaboration/Collaborators/RemotePluginTest.php52
-rw-r--r--tests/lib/Files/Storage/Storage.php17
-rw-r--r--tests/lib/Files/Stream/CountReadStreamTest.php49
-rw-r--r--tests/lib/Preview/GeneratorTest.php22
-rw-r--r--tests/lib/Repair/SetVcardDatabaseUIDTest.php2
265 files changed, 7485 insertions, 1029 deletions
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/CardDAV/CardDavBackend.php b/apps/dav/lib/CardDAV/CardDavBackend.php
index 8ef0e0baf56..80a3fe2f11f 100644
--- a/apps/dav/lib/CardDAV/CardDavBackend.php
+++ b/apps/dav/lib/CardDAV/CardDavBackend.php
@@ -1134,8 +1134,8 @@ class CardDavBackend implements BackendInterface, SyncSupport {
* Extract UID from vcard
*
* @param string $cardData the vcard raw data
- * @return string the uid or empty if none
- * @throws BadRequest
+ * @return string the uid
+ * @throws BadRequest if no UID is available
*/
private function getUID($cardData) {
$vCard = Reader::read($cardData);
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/detailsView.scss b/apps/files/css/detailsView.scss
index f64a3702850..71062648c97 100644
--- a/apps/files/css/detailsView.scss
+++ b/apps/files/css/detailsView.scss
@@ -15,7 +15,13 @@
#app-sidebar .mainFileInfoView .permalink {
padding: 6px 10px;
- vertical-align: text-top;
+ vertical-align: top;
+ opacity: .6;
+
+ &:hover,
+ &:focus {
+ opacity: 1;
+ }
}
#app-sidebar .mainFileInfoView .permalink-field>input {
clear: both;
@@ -87,7 +93,7 @@
}
#app-sidebar .fileName h3 {
- width: calc(100% - 36px); /* 36px is the with of the copy link icon */
+ width: calc(100% - 42px); /* 36px is the with of the copy link icon, but this breaks so we add some more to be sure */
display: inline-block;
padding: 5px 0;
margin: -5px 0;
diff --git a/apps/files/css/files.scss b/apps/files/css/files.scss
index 4e0bc9c0160..d6f9bd6131e 100644
--- a/apps/files/css/files.scss
+++ b/apps/files/css/files.scss
@@ -8,7 +8,12 @@
}
/* FILE MENU */
-.actions { padding:5px; height:32px; display: inline-block; float: left; }
+.actions {
+ padding: 5px;
+ height: 100%;
+ display: inline-block;
+ float: left;
+}
.actions input, .actions button, .actions .button { margin:0; float:left; }
.actions .button a { color: #555; }
.actions .button a:hover,
@@ -316,6 +321,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;
@@ -658,8 +664,14 @@ table.dragshadow td.size {
top: 100%;
margin-top: 4px;
min-width: 100px;
- margin-left: 7px;
+ margin-left: 22px; /* Align left edge below center of + button … */
+ transform: translateX(-50%); /* … then center it below button */
z-index: 1001;
+
+ /* Center triangle */
+ &::after {
+ left: calc(50% - 8px) !important;
+ }
}
#filestable .filename .action .icon,
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/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_versions/appinfo/info.xml b/apps/files_versions/appinfo/info.xml
index d2f873edb07..6d1b3085f80 100644
--- a/apps/files_versions/appinfo/info.xml
+++ b/apps/files_versions/appinfo/info.xml
@@ -41,4 +41,8 @@
<collection>OCA\Files_Versions\Sabre\RootCollection</collection>
</collections>
</sabre>
+
+ <versions>
+ <backend for="OCP\Files\Storage\IStorage">OCA\Files_Versions\Versions\LegacyVersionsBackend</backend>
+ </versions>
</info>
diff --git a/apps/files_versions/composer/composer/autoload_classmap.php b/apps/files_versions/composer/composer/autoload_classmap.php
index 4bb112b4f11..1283e533914 100644
--- a/apps/files_versions/composer/composer/autoload_classmap.php
+++ b/apps/files_versions/composer/composer/autoload_classmap.php
@@ -23,4 +23,11 @@ return array(
'OCA\\Files_Versions\\Sabre\\VersionHome' => $baseDir . '/../lib/Sabre/VersionHome.php',
'OCA\\Files_Versions\\Sabre\\VersionRoot' => $baseDir . '/../lib/Sabre/VersionRoot.php',
'OCA\\Files_Versions\\Storage' => $baseDir . '/../lib/Storage.php',
+ 'OCA\\Files_Versions\\Versions\\BackendNotFoundException' => $baseDir . '/../lib/Versions/BackendNotFoundException.php',
+ 'OCA\\Files_Versions\\Versions\\IVersion' => $baseDir . '/../lib/Versions/IVersion.php',
+ 'OCA\\Files_Versions\\Versions\\IVersionBackend' => $baseDir . '/../lib/Versions/IVersionBackend.php',
+ 'OCA\\Files_Versions\\Versions\\IVersionManager' => $baseDir . '/../lib/Versions/IVersionManager.php',
+ 'OCA\\Files_Versions\\Versions\\LegacyVersionsBackend' => $baseDir . '/../lib/Versions/LegacyVersionsBackend.php',
+ 'OCA\\Files_Versions\\Versions\\Version' => $baseDir . '/../lib/Versions/Version.php',
+ 'OCA\\Files_Versions\\Versions\\VersionManager' => $baseDir . '/../lib/Versions/VersionManager.php',
);
diff --git a/apps/files_versions/composer/composer/autoload_static.php b/apps/files_versions/composer/composer/autoload_static.php
index 29bc592b41c..6a6b753c2e5 100644
--- a/apps/files_versions/composer/composer/autoload_static.php
+++ b/apps/files_versions/composer/composer/autoload_static.php
@@ -38,6 +38,13 @@ class ComposerStaticInitFiles_Versions
'OCA\\Files_Versions\\Sabre\\VersionHome' => __DIR__ . '/..' . '/../lib/Sabre/VersionHome.php',
'OCA\\Files_Versions\\Sabre\\VersionRoot' => __DIR__ . '/..' . '/../lib/Sabre/VersionRoot.php',
'OCA\\Files_Versions\\Storage' => __DIR__ . '/..' . '/../lib/Storage.php',
+ 'OCA\\Files_Versions\\Versions\\BackendNotFoundException' => __DIR__ . '/..' . '/../lib/Versions/BackendNotFoundException.php',
+ 'OCA\\Files_Versions\\Versions\\IVersion' => __DIR__ . '/..' . '/../lib/Versions/IVersion.php',
+ 'OCA\\Files_Versions\\Versions\\IVersionBackend' => __DIR__ . '/..' . '/../lib/Versions/IVersionBackend.php',
+ 'OCA\\Files_Versions\\Versions\\IVersionManager' => __DIR__ . '/..' . '/../lib/Versions/IVersionManager.php',
+ 'OCA\\Files_Versions\\Versions\\LegacyVersionsBackend' => __DIR__ . '/..' . '/../lib/Versions/LegacyVersionsBackend.php',
+ 'OCA\\Files_Versions\\Versions\\Version' => __DIR__ . '/..' . '/../lib/Versions/Version.php',
+ 'OCA\\Files_Versions\\Versions\\VersionManager' => __DIR__ . '/..' . '/../lib/Versions/VersionManager.php',
);
public static function getInitializer(ClassLoader $loader)
diff --git a/apps/files_versions/js/versionstabview.js b/apps/files_versions/js/versionstabview.js
index 61309a30d50..213ee1ae83c 100644
--- a/apps/files_versions/js/versionstabview.js
+++ b/apps/files_versions/js/versionstabview.js
@@ -38,6 +38,10 @@
return t('files_versions', 'Versions');
},
+ getIcon: function() {
+ return 'icon-history';
+ },
+
nextPage: function() {
if (this._loading) {
return;
diff --git a/apps/files_versions/lib/AppInfo/Application.php b/apps/files_versions/lib/AppInfo/Application.php
index 340b5ab5cbd..935556221fa 100644
--- a/apps/files_versions/lib/AppInfo/Application.php
+++ b/apps/files_versions/lib/AppInfo/Application.php
@@ -24,9 +24,10 @@
namespace OCA\Files_Versions\AppInfo;
use OCA\DAV\Connector\Sabre\Principal;
+use OCA\Files_Versions\Versions\IVersionManager;
+use OCA\Files_Versions\Versions\VersionManager;
use OCP\AppFramework\App;
-use OCA\Files_Versions\Expiration;
-use OCP\AppFramework\Utility\ITimeFactory;
+use OCP\AppFramework\IAppContainer;
use OCA\Files_Versions\Capabilities;
class Application extends App {
@@ -43,14 +44,45 @@ class Application extends App {
/*
* Register $principalBackend for the DAV collection
*/
- $container->registerService('principalBackend', function () {
+ $container->registerService('principalBackend', function (IAppContainer $c) {
+ $server = $c->getServer();
return new Principal(
- \OC::$server->getUserManager(),
- \OC::$server->getGroupManager(),
- \OC::$server->getShareManager(),
- \OC::$server->getUserSession(),
- \OC::$server->getConfig()
+ $server->getUserManager(),
+ $server->getGroupManager(),
+ $server->getShareManager(),
+ $server->getUserSession(),
+ $server->getConfig()
);
});
+
+ $container->registerService(IVersionManager::class, function(IAppContainer $c) {
+ return new VersionManager();
+ });
+
+ $this->registerVersionBackends();
+ }
+
+ public function registerVersionBackends() {
+ $server = $this->getContainer()->getServer();
+ $logger = $server->getLogger();
+ $appManager = $server->getAppManager();
+ /** @var IVersionManager $versionManager */
+ $versionManager = $this->getContainer()->getServer()->query(IVersionManager::class);
+ foreach($appManager->getInstalledApps() as $app) {
+ $appInfo = $appManager->getAppInfo($app);
+ if (isset($appInfo['versions'])) {
+ $backends = $appInfo['versions'];
+ foreach($backends as $backend) {
+ $class = $backend['@value'];
+ $for = $backend['@attributes']['for'];
+ try {
+ $backendObject = $server->query($class);
+ $versionManager->registerBackend($for, $backendObject);
+ } catch (\Exception $e) {
+ $logger->logException($e);
+ }
+ }
+ }
+ }
}
}
diff --git a/apps/files_versions/lib/Controller/PreviewController.php b/apps/files_versions/lib/Controller/PreviewController.php
index b8bf464fb3f..f41250a8971 100644
--- a/apps/files_versions/lib/Controller/PreviewController.php
+++ b/apps/files_versions/lib/Controller/PreviewController.php
@@ -21,45 +21,53 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
namespace OCA\Files_Versions\Controller;
+use OCA\Files_Versions\Versions\IVersionManager;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\Http\FileDisplayResponse;
-use OCP\Files\File;
-use OCP\Files\Folder;
use OCP\Files\IMimeTypeDetector;
use OCP\Files\IRootFolder;
use OCP\Files\NotFoundException;
use OCP\IPreview;
use OCP\IRequest;
+use OCP\IUserSession;
class PreviewController extends Controller {
/** @var IRootFolder */
private $rootFolder;
- /** @var string */
- private $userId;
+ /** @var IUserSession */
+ private $userSession;
/** @var IMimeTypeDetector */
private $mimeTypeDetector;
+ /** @var IVersionManager */
+ private $versionManager;
+
/** @var IPreview */
private $previewManager;
- public function __construct($appName,
- IRequest $request,
- IRootFolder $rootFolder,
- $userId,
- IMimeTypeDetector $mimeTypeDetector,
- IPreview $previewManager) {
+ public function __construct(
+ $appName,
+ IRequest $request,
+ IRootFolder $rootFolder,
+ IUserSession $userSession,
+ IMimeTypeDetector $mimeTypeDetector,
+ IVersionManager $versionManager,
+ IPreview $previewManager
+ ) {
parent::__construct($appName, $request);
$this->rootFolder = $rootFolder;
- $this->userId = $userId;
+ $this->userSession = $userSession;
$this->mimeTypeDetector = $mimeTypeDetector;
+ $this->versionManager = $versionManager;
$this->previewManager = $previewManager;
}
@@ -79,20 +87,17 @@ class PreviewController extends Controller {
$y = 44,
$version = ''
) {
- if($file === '' || $version === '' || $x === 0 || $y === 0) {
+ if ($file === '' || $version === '' || $x === 0 || $y === 0) {
return new DataResponse([], Http::STATUS_BAD_REQUEST);
}
try {
- $userFolder = $this->rootFolder->getUserFolder($this->userId);
- /** @var Folder $versionFolder */
- $versionFolder = $userFolder->getParent()->get('files_versions');
- $mimeType = $this->mimeTypeDetector->detectPath($file);
- $file = $versionFolder->get($file.'.v'.$version);
-
- /** @var File $file */
- $f = $this->previewManager->getPreview($file, $x, $y, true, IPreview::MODE_FILL, $mimeType);
- return new FileDisplayResponse($f, Http::STATUS_OK, ['Content-Type' => $f->getMimeType()]);
+ $user = $this->userSession->getUser();
+ $userFolder = $this->rootFolder->getUserFolder($user->getUID());
+ $file = $userFolder->get($file);
+ $versionFile = $this->versionManager->getVersionFile($user, $file, (int)$version);
+ $preview = $this->previewManager->getPreview($versionFile, $x, $y, true, IPreview::MODE_FILL, $versionFile->getMimetype());
+ return new FileDisplayResponse($preview, Http::STATUS_OK, ['Content-Type' => $preview->getMimeType()]);
} catch (NotFoundException $e) {
return new DataResponse([], Http::STATUS_NOT_FOUND);
} catch (\InvalidArgumentException $e) {
diff --git a/apps/files_versions/lib/Sabre/RestoreFolder.php b/apps/files_versions/lib/Sabre/RestoreFolder.php
index c398d02692b..c8504646bad 100644
--- a/apps/files_versions/lib/Sabre/RestoreFolder.php
+++ b/apps/files_versions/lib/Sabre/RestoreFolder.php
@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace OCA\Files_Versions\Sabre;
+use OCP\IUser;
use Sabre\DAV\Exception\Forbidden;
use Sabre\DAV\ICollection;
use Sabre\DAV\IMoveTarget;
@@ -31,14 +32,6 @@ use Sabre\DAV\INode;
class RestoreFolder implements ICollection, IMoveTarget {
-
- /** @var string */
- protected $userId;
-
- public function __construct(string $userId) {
- $this->userId = $userId;
- }
-
public function createFile($name, $data = null) {
throw new Forbidden();
}
@@ -80,7 +73,8 @@ class RestoreFolder implements ICollection, IMoveTarget {
return false;
}
- return $sourceNode->rollBack();
+ $sourceNode->rollBack();
+ return true;
}
}
diff --git a/apps/files_versions/lib/Sabre/RootCollection.php b/apps/files_versions/lib/Sabre/RootCollection.php
index ca5979573b5..504c3362505 100644
--- a/apps/files_versions/lib/Sabre/RootCollection.php
+++ b/apps/files_versions/lib/Sabre/RootCollection.php
@@ -20,10 +20,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
namespace OCA\Files_Versions\Sabre;
+use OCA\Files_Versions\Versions\IVersionManager;
use OCP\Files\IRootFolder;
use OCP\IConfig;
+use OCP\IUserManager;
use Sabre\DAV\INode;
use Sabre\DAVACL\AbstractPrincipalCollection;
use Sabre\DAVACL\PrincipalBackend;
@@ -33,12 +36,24 @@ class RootCollection extends AbstractPrincipalCollection {
/** @var IRootFolder */
private $rootFolder;
- public function __construct(PrincipalBackend\BackendInterface $principalBackend,
- IRootFolder $rootFolder,
- IConfig $config) {
+ /** @var IUserManager */
+ private $userManager;
+
+ /** @var IVersionManager */
+ private $versionManager;
+
+ public function __construct(
+ PrincipalBackend\BackendInterface $principalBackend,
+ IRootFolder $rootFolder,
+ IConfig $config,
+ IUserManager $userManager,
+ IVersionManager $versionManager
+ ) {
parent::__construct($principalBackend, 'principals/users');
$this->rootFolder = $rootFolder;
+ $this->userManager = $userManager;
+ $this->versionManager = $versionManager;
$this->disableListing = !$config->getSystemValue('debug', false);
}
@@ -54,12 +69,12 @@ class RootCollection extends AbstractPrincipalCollection {
* @return INode
*/
public function getChildForPrincipal(array $principalInfo) {
- list(,$name) = \Sabre\Uri\split($principalInfo['uri']);
+ list(, $name) = \Sabre\Uri\split($principalInfo['uri']);
$user = \OC::$server->getUserSession()->getUser();
if (is_null($user) || $name !== $user->getUID()) {
throw new \Sabre\DAV\Exception\Forbidden();
}
- return new VersionHome($principalInfo, $this->rootFolder);
+ return new VersionHome($principalInfo, $this->rootFolder, $this->userManager, $this->versionManager);
}
public function getName() {
diff --git a/apps/files_versions/lib/Sabre/VersionCollection.php b/apps/files_versions/lib/Sabre/VersionCollection.php
index 481a5f491c3..9a3a6a365f0 100644
--- a/apps/files_versions/lib/Sabre/VersionCollection.php
+++ b/apps/files_versions/lib/Sabre/VersionCollection.php
@@ -21,11 +21,15 @@ declare(strict_types=1);
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
namespace OCA\Files_Versions\Sabre;
use OCA\Files_Versions\Storage;
+use OCA\Files_Versions\Versions\IVersion;
+use OCA\Files_Versions\Versions\IVersionManager;
use OCP\Files\File;
use OCP\Files\Folder;
+use OCP\IUser;
use Sabre\DAV\Exception\Forbidden;
use Sabre\DAV\Exception\NotFound;
use Sabre\DAV\ICollection;
@@ -37,13 +41,17 @@ class VersionCollection implements ICollection {
/** @var File */
private $file;
- /** @var string */
- private $userId;
+ /** @var IUser */
+ private $user;
+
+ /** @var IVersionManager */
+ private $versionManager;
- public function __construct(Folder $userFolder, File $file, string $userId) {
+ public function __construct(Folder $userFolder, File $file, IUser $user, IVersionManager $versionManager) {
$this->userFolder = $userFolder;
$this->file = $file;
- $this->userId = $userId;
+ $this->user = $user;
+ $this->versionManager = $versionManager;
}
public function createFile($name, $data = null) {
@@ -68,10 +76,10 @@ class VersionCollection implements ICollection {
}
public function getChildren(): array {
- $versions = Storage::getVersions($this->userId, $this->userFolder->getRelativePath($this->file->getPath()));
+ $versions = $this->versionManager->getVersionsForFile($this->user, $this->file);
- return array_map(function (array $data) {
- return new VersionFile($data, $this->userFolder->getParent());
+ return array_map(function (IVersion $version) {
+ return new VersionFile($version, $this->versionManager);
}, $versions);
}
diff --git a/apps/files_versions/lib/Sabre/VersionFile.php b/apps/files_versions/lib/Sabre/VersionFile.php
index 347058448fc..2d630008d2a 100644
--- a/apps/files_versions/lib/Sabre/VersionFile.php
+++ b/apps/files_versions/lib/Sabre/VersionFile.php
@@ -21,26 +21,26 @@ declare(strict_types=1);
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
namespace OCA\Files_Versions\Sabre;
-use OCA\Files_Versions\Storage;
-use OCP\Files\File;
-use OCP\Files\Folder;
+use OCA\Files_Versions\Versions\IVersion;
+use OCA\Files_Versions\Versions\IVersionManager;
use OCP\Files\NotFoundException;
use Sabre\DAV\Exception\Forbidden;
use Sabre\DAV\Exception\NotFound;
use Sabre\DAV\IFile;
class VersionFile implements IFile {
- /** @var array */
- private $data;
+ /** @var IVersion */
+ private $version;
- /** @var Folder */
- private $userRoot;
+ /** @var IVersionManager */
+ private $versionManager;
- public function __construct(array $data, Folder $userRoot) {
- $this->data = $data;
- $this->userRoot = $userRoot;
+ public function __construct(IVersion $version, IVersionManager $versionManager) {
+ $this->version = $version;
+ $this->versionManager = $versionManager;
}
public function put($data) {
@@ -49,27 +49,22 @@ class VersionFile implements IFile {
public function get() {
try {
- /** @var Folder $versions */
- $versions = $this->userRoot->get('files_versions');
- /** @var File $version */
- $version = $versions->get($this->data['path'].'.v'.$this->data['version']);
+ return $this->versionManager->read($this->version);
} catch (NotFoundException $e) {
throw new NotFound();
}
-
- return $version->fopen('rb');
}
public function getContentType(): string {
- return $this->data['mimetype'];
+ return $this->version->getMimeType();
}
public function getETag(): string {
- return $this->data['version'];
+ return (string)$this->version->getRevisionId();
}
public function getSize(): int {
- return $this->data['size'];
+ return $this->version->getSize();
}
public function delete() {
@@ -77,7 +72,7 @@ class VersionFile implements IFile {
}
public function getName(): string {
- return $this->data['version'];
+ return (string)$this->version->getRevisionId();
}
public function setName($name) {
@@ -85,10 +80,10 @@ class VersionFile implements IFile {
}
public function getLastModified(): int {
- return (int)$this->data['version'];
+ return $this->version->getTimestamp();
}
- public function rollBack(): bool {
- return Storage::rollback($this->data['path'], $this->data['version']);
+ public function rollBack() {
+ $this->versionManager->rollback($this->version);
}
}
diff --git a/apps/files_versions/lib/Sabre/VersionHome.php b/apps/files_versions/lib/Sabre/VersionHome.php
index 7a99d2376d4..7be5974bbbe 100644
--- a/apps/files_versions/lib/Sabre/VersionHome.php
+++ b/apps/files_versions/lib/Sabre/VersionHome.php
@@ -20,9 +20,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
namespace OCA\Files_Versions\Sabre;
+use OC\User\NoUserException;
+use OCA\Files_Versions\Versions\IVersionManager;
use OCP\Files\IRootFolder;
+use OCP\IUserManager;
use Sabre\DAV\Exception\Forbidden;
use Sabre\DAV\ICollection;
@@ -34,9 +38,25 @@ class VersionHome implements ICollection {
/** @var IRootFolder */
private $rootFolder;
- public function __construct(array $principalInfo, IRootFolder $rootFolder) {
+ /** @var IUserManager */
+ private $userManager;
+
+ /** @var IVersionManager */
+ private $versionManager;
+
+ public function __construct(array $principalInfo, IRootFolder $rootFolder, IUserManager $userManager, IVersionManager $versionManager) {
$this->principalInfo = $principalInfo;
$this->rootFolder = $rootFolder;
+ $this->userManager = $userManager;
+ $this->versionManager = $versionManager;
+ }
+
+ private function getUser() {
+ list(, $name) = \Sabre\Uri\split($this->principalInfo['uri']);
+ $user = $this->userManager->get($name);
+ if (!$user) {
+ throw new NoUserException();
+ }
}
public function delete() {
@@ -44,8 +64,7 @@ class VersionHome implements ICollection {
}
public function getName(): string {
- list(,$name) = \Sabre\Uri\split($this->principalInfo['uri']);
- return $name;
+ return $this->getUser()->getUID();
}
public function setName($name) {
@@ -61,22 +80,22 @@ class VersionHome implements ICollection {
}
public function getChild($name) {
- list(,$userId) = \Sabre\Uri\split($this->principalInfo['uri']);
+ $user = $this->getUser();
if ($name === 'versions') {
- return new VersionRoot($userId, $this->rootFolder);
+ return new VersionRoot($user, $this->rootFolder, $this->versionManager);
}
if ($name === 'restore') {
- return new RestoreFolder($userId);
+ return new RestoreFolder();
}
}
public function getChildren() {
- list(,$userId) = \Sabre\Uri\split($this->principalInfo['uri']);
+ $user = $this->getUser();
return [
- new VersionRoot($userId, $this->rootFolder),
- new RestoreFolder($userId),
+ new VersionRoot($user, $this->rootFolder, $this->versionManager),
+ new RestoreFolder(),
];
}
diff --git a/apps/files_versions/lib/Sabre/VersionRoot.php b/apps/files_versions/lib/Sabre/VersionRoot.php
index 743b1c6ef1b..1c689a4d87b 100644
--- a/apps/files_versions/lib/Sabre/VersionRoot.php
+++ b/apps/files_versions/lib/Sabre/VersionRoot.php
@@ -23,23 +23,29 @@ declare(strict_types=1);
*/
namespace OCA\Files_Versions\Sabre;
+use OCA\Files_Versions\Versions\IVersionManager;
use OCP\Files\File;
use OCP\Files\IRootFolder;
+use OCP\IUser;
use Sabre\DAV\Exception\Forbidden;
use Sabre\DAV\Exception\NotFound;
use Sabre\DAV\ICollection;
class VersionRoot implements ICollection {
- /** @var string */
- private $userId;
+ /** @var IUser */
+ private $user;
/** @var IRootFolder */
private $rootFolder;
- public function __construct(string $userId, IRootFolder $rootFolder) {
- $this->userId = $userId;
+ /** @var IVersionManager */
+ private $versionManager;
+
+ public function __construct(IUser $user, IRootFolder $rootFolder, IVersionManager $versionManager) {
+ $this->user = $user;
$this->rootFolder = $rootFolder;
+ $this->versionManager = $versionManager;
}
public function delete() {
@@ -63,7 +69,7 @@ class VersionRoot implements ICollection {
}
public function getChild($name) {
- $userFolder = $this->rootFolder->getUserFolder($this->userId);
+ $userFolder = $this->rootFolder->getUserFolder($this->user->getUID());
$fileId = (int)$name;
$nodes = $userFolder->getById($fileId);
@@ -78,7 +84,7 @@ class VersionRoot implements ICollection {
throw new NotFound();
}
- return new VersionCollection($userFolder, $node, $this->userId);
+ return new VersionCollection($userFolder, $node, $this->user, $this->versionManager);
}
public function getChildren(): array {
diff --git a/apps/files_versions/lib/Storage.php b/apps/files_versions/lib/Storage.php
index 401544cc5d7..e2e4888cbce 100644
--- a/apps/files_versions/lib/Storage.php
+++ b/apps/files_versions/lib/Storage.php
@@ -48,6 +48,7 @@ use OC\Files\View;
use OCA\Files_Versions\AppInfo\Application;
use OCA\Files_Versions\Command\Expire;
use OCA\Files_Versions\Events\CreateVersionEvent;
+use OCA\Files_Versions\Versions\IVersionManager;
use OCP\Files\NotFoundException;
use OCP\Lock\ILockingProvider;
use OCP\User;
@@ -178,10 +179,10 @@ class Storage {
list($uid, $filename) = self::getUidAndFilename($filename);
$files_view = new View('/'.$uid .'/files');
- $users_view = new View('/'.$uid);
$eventDispatcher = \OC::$server->getEventDispatcher();
- $id = $files_view->getFileInfo($filename)->getId();
+ $fileInfo = $files_view->getFileInfo($filename);
+ $id = $fileInfo->getId();
$nodes = \OC::$server->getRootFolder()->getById($id);
foreach ($nodes as $node) {
$event = new CreateVersionEvent($node);
@@ -192,20 +193,16 @@ class Storage {
}
// no use making versions for empty files
- if ($files_view->filesize($filename) === 0) {
+ if ($fileInfo->getSize() === 0) {
return false;
}
- // create all parent folders
- self::createMissingDirectories($filename, $users_view);
-
- self::scheduleExpire($uid, $filename);
+ /** @var IVersionManager $versionManager */
+ $versionManager = \OC::$server->query(IVersionManager::class);
+ $userManager = \OC::$server->getUserManager();
+ $user = $userManager->get($uid);
- // store a new version of a file
- $mtime = $users_view->filemtime('files/' . $filename);
- $users_view->copy('files/' . $filename, 'files_versions/' . $filename . '.v' . $mtime);
- // call getFileInfo to enforce a file cache entry for the new version
- $users_view->getFileInfo('files_versions/' . $filename . '.v' . $mtime);
+ $versionManager->createVersion($user, $fileInfo);
}
@@ -695,7 +692,7 @@ class Storage {
* @param string $uid owner of the file
* @param string $fileName file/folder for which to schedule expiration
*/
- private static function scheduleExpire($uid, $fileName) {
+ public static function scheduleExpire($uid, $fileName) {
// let the admin disable auto expire
$expiration = self::getExpiration();
if ($expiration->isEnabled()) {
@@ -833,7 +830,7 @@ class Storage {
* "files" folder
* @param View $view view on data/user/
*/
- private static function createMissingDirectories($filename, $view) {
+ public static function createMissingDirectories($filename, $view) {
$dirname = Filesystem::normalizePath(dirname($filename));
$dirParts = explode('/', $dirname);
$dir = "/files_versions";
diff --git a/apps/files_versions/lib/Versions/BackendNotFoundException.php b/apps/files_versions/lib/Versions/BackendNotFoundException.php
new file mode 100644
index 00000000000..09985a716b9
--- /dev/null
+++ b/apps/files_versions/lib/Versions/BackendNotFoundException.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * @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 OCA\Files_Versions\Versions;
+
+class BackendNotFoundException extends \Exception {
+
+}
diff --git a/apps/files_versions/lib/Versions/IVersion.php b/apps/files_versions/lib/Versions/IVersion.php
new file mode 100644
index 00000000000..b6fc95814d8
--- /dev/null
+++ b/apps/files_versions/lib/Versions/IVersion.php
@@ -0,0 +1,99 @@
+<?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 OCA\Files_Versions\Versions;
+
+use OCP\Files\FileInfo;
+use OCP\IUser;
+
+/**
+ * @since 15.0.0
+ */
+interface IVersion {
+ /**
+ * @return IVersionBackend
+ * @since 15.0.0
+ */
+ public function getBackend(): IVersionBackend;
+
+ /**
+ * Get the file info of the source file
+ *
+ * @return FileInfo
+ * @since 15.0.0
+ */
+ public function getSourceFile(): FileInfo;
+
+ /**
+ * Get the id of the revision for the file
+ *
+ * @return int
+ * @since 15.0.0
+ */
+ public function getRevisionId(): int;
+
+ /**
+ * Get the timestamp this version was created
+ *
+ * @return int
+ * @since 15.0.0
+ */
+ public function getTimestamp(): int;
+
+ /**
+ * Get the size of this version
+ *
+ * @return int
+ * @since 15.0.0
+ */
+ public function getSize(): int;
+
+ /**
+ * Get the name of the source file at the time of making this version
+ *
+ * @return string
+ * @since 15.0.0
+ */
+ public function getSourceFileName(): string;
+
+ /**
+ * Get the mimetype of this version
+ *
+ * @return string
+ * @since 15.0.0
+ */
+ public function getMimeType(): string;
+
+ /**
+ * Get the path of this version
+ *
+ * @return string
+ * @since 15.0.0
+ */
+ public function getVersionPath(): string;
+
+ /**
+ * @return IUser
+ * @since 15.0.0
+ */
+ public function getUser(): IUser;
+}
diff --git a/apps/files_versions/lib/Versions/IVersionBackend.php b/apps/files_versions/lib/Versions/IVersionBackend.php
new file mode 100644
index 00000000000..616d535f7fd
--- /dev/null
+++ b/apps/files_versions/lib/Versions/IVersionBackend.php
@@ -0,0 +1,81 @@
+<?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 OCA\Files_Versions\Versions;
+
+use OCP\Files\File;
+use OCP\Files\FileInfo;
+use OCP\Files\NotFoundException;
+use OCP\Files\SimpleFS\ISimpleFile;
+use OCP\IUser;
+
+/**
+ * @since 15.0.0
+ */
+interface IVersionBackend {
+ /**
+ * Get all versions for a file
+ *
+ * @param IUser $user
+ * @param FileInfo $file
+ * @return IVersion[]
+ * @since 15.0.0
+ */
+ public function getVersionsForFile(IUser $user, FileInfo $file): array;
+
+ /**
+ * Create a new version for a file
+ *
+ * @param IUser $user
+ * @param FileInfo $file
+ * @since 15.0.0
+ */
+ public function createVersion(IUser $user, FileInfo $file);
+
+ /**
+ * Restore this version
+ *
+ * @param IVersion $version
+ * @since 15.0.0
+ */
+ public function rollback(IVersion $version);
+
+ /**
+ * Open the file for reading
+ *
+ * @param IVersion $version
+ * @return resource
+ * @throws NotFoundException
+ * @since 15.0.0
+ */
+ public function read(IVersion $version);
+
+ /**
+ * Get the preview for a specific version of a file
+ *
+ * @param IUser $user
+ * @param FileInfo $sourceFile
+ * @param int $revision
+ * @return ISimpleFile
+ * @since 15.0.0
+ */
+ public function getVersionFile(IUser $user, FileInfo $sourceFile, int $revision): File;
+}
diff --git a/apps/files_versions/lib/Versions/IVersionManager.php b/apps/files_versions/lib/Versions/IVersionManager.php
new file mode 100644
index 00000000000..748b649b1a2
--- /dev/null
+++ b/apps/files_versions/lib/Versions/IVersionManager.php
@@ -0,0 +1,36 @@
+<?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 OCA\Files_Versions\Versions;
+
+/**
+ * @since 15.0.0
+ */
+interface IVersionManager extends IVersionBackend {
+ /**
+ * Register a new backend
+ *
+ * @param string $storageType
+ * @param IVersionBackend $backend
+ * @since 15.0.0
+ */
+ public function registerBackend(string $storageType, IVersionBackend $backend);
+}
diff --git a/apps/files_versions/lib/Versions/LegacyVersionsBackend.php b/apps/files_versions/lib/Versions/LegacyVersionsBackend.php
new file mode 100644
index 00000000000..7293aca641e
--- /dev/null
+++ b/apps/files_versions/lib/Versions/LegacyVersionsBackend.php
@@ -0,0 +1,105 @@
+<?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 OCA\Files_Versions\Versions;
+
+use OC\Files\View;
+use OCA\Files_Versions\Storage;
+use OCP\Files\File;
+use OCP\Files\FileInfo;
+use OCP\Files\Folder;
+use OCP\Files\IRootFolder;
+use OCP\Files\NotFoundException;
+use OCP\IUser;
+
+class LegacyVersionsBackend implements IVersionBackend {
+ /** @var IRootFolder */
+ private $rootFolder;
+
+ public function __construct(IRootFolder $rootFolder) {
+ $this->rootFolder = $rootFolder;
+ }
+
+ public function getVersionsForFile(IUser $user, FileInfo $file): array {
+ $userFolder = $this->rootFolder->getUserFolder($user->getUID());
+ $versions = Storage::getVersions($user->getUID(), $userFolder->getRelativePath($file->getPath()));
+
+ return array_map(function (array $data) use ($file, $user) {
+ return new Version(
+ (int)$data['version'],
+ (int)$data['version'],
+ $data['name'],
+ (int)$data['size'],
+ $data['mimetype'],
+ $data['path'],
+ $file,
+ $this,
+ $user
+ );
+ }, $versions);
+ }
+
+ public function createVersion(IUser $user, FileInfo $file) {
+ $userFolder = $this->rootFolder->getUserFolder($user->getUID());
+ $relativePath = $userFolder->getRelativePath($file->getPath());
+ $userView = new View('/' . $user->getUID());
+ // create all parent folders
+ Storage::createMissingDirectories($relativePath, $userView);
+
+ Storage::scheduleExpire($user->getUID(), $relativePath);
+
+ // store a new version of a file
+ $userView->copy('files/' . $relativePath, 'files_versions/' . $relativePath . '.v' . $file->getMtime());
+ // ensure the file is scanned
+ $userView->getFileInfo('files_versions/' . $relativePath . '.v' . $file->getMtime());
+ }
+
+ public function rollback(IVersion $version) {
+ return Storage::rollback($version->getVersionPath(), $version->getRevisionId());
+ }
+
+ private function getVersionFolder(IUser $user): Folder {
+ $userRoot = $this->rootFolder->getUserFolder($user->getUID())
+ ->getParent();
+ try {
+ /** @var Folder $folder */
+ $folder = $userRoot->get('files_versions');
+ return $folder;
+ } catch (NotFoundException $e) {
+ return $userRoot->newFolder('files_versions');
+ }
+ }
+
+ public function read(IVersion $version) {
+ $versions = $this->getVersionFolder($version->getUser());
+ /** @var File $file */
+ $file = $versions->get($version->getVersionPath() . '.v' . $version->getRevisionId());
+ return $file->fopen('r');
+ }
+
+ public function getVersionFile(IUser $user, FileInfo $sourceFile, int $revision): File {
+ $userFolder = $this->rootFolder->getUserFolder($user->getUID());
+ $versionFolder = $this->getVersionFolder($user);
+ /** @var File $file */
+ $file = $versionFolder->get($userFolder->getRelativePath($sourceFile->getPath()) . '.v' . $revision);
+ return $file;
+ }
+}
diff --git a/apps/files_versions/lib/Versions/Version.php b/apps/files_versions/lib/Versions/Version.php
new file mode 100644
index 00000000000..5988234db61
--- /dev/null
+++ b/apps/files_versions/lib/Versions/Version.php
@@ -0,0 +1,113 @@
+<?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 OCA\Files_Versions\Versions;
+
+use OCP\Files\FileInfo;
+use OCP\IUser;
+
+class Version implements IVersion {
+ /** @var int */
+ private $timestamp;
+
+ /** @var int */
+ private $revisionId;
+
+ /** @var string */
+ private $name;
+
+ /** @var int */
+ private $size;
+
+ /** @var string */
+ private $mimetype;
+
+ /** @var string */
+ private $path;
+
+ /** @var FileInfo */
+ private $sourceFileInfo;
+
+ /** @var IVersionBackend */
+ private $backend;
+
+ /** @var IUser */
+ private $user;
+
+ public function __construct(
+ int $timestamp,
+ int $revisionId,
+ string $name,
+ int $size,
+ string $mimetype,
+ string $path,
+ FileInfo $sourceFileInfo,
+ IVersionBackend $backend,
+ IUser $user
+ ) {
+ $this->timestamp = $timestamp;
+ $this->revisionId = $revisionId;
+ $this->name = $name;
+ $this->size = $size;
+ $this->mimetype = $mimetype;
+ $this->path = $path;
+ $this->sourceFileInfo = $sourceFileInfo;
+ $this->backend = $backend;
+ $this->user = $user;
+ }
+
+ public function getBackend(): IVersionBackend {
+ return $this->backend;
+ }
+
+ public function getSourceFile(): FileInfo {
+ return $this->sourceFileInfo;
+ }
+
+ public function getRevisionId(): int {
+ return $this->revisionId;
+ }
+
+ public function getTimestamp(): int {
+ return $this->timestamp;
+ }
+
+ public function getSize(): int {
+ return $this->size;
+ }
+
+ public function getSourceFileName(): string {
+ return $this->name;
+ }
+
+ public function getMimeType(): string {
+ return $this->mimetype;
+ }
+
+ public function getVersionPath(): string {
+ return $this->path;
+ }
+
+ public function getUser(): IUser {
+ return $this->user;
+ }
+}
diff --git a/apps/files_versions/lib/Versions/VersionManager.php b/apps/files_versions/lib/Versions/VersionManager.php
new file mode 100644
index 00000000000..757b6002710
--- /dev/null
+++ b/apps/files_versions/lib/Versions/VersionManager.php
@@ -0,0 +1,93 @@
+<?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 OCA\Files_Versions\Versions;
+
+use OCP\Files\File;
+use OCP\Files\FileInfo;
+use OCP\Files\Storage\IStorage;
+use OCP\IUser;
+
+class VersionManager implements IVersionManager {
+ /** @var IVersionBackend[] */
+ private $backends = [];
+
+ public function registerBackend(string $storageType, IVersionBackend $backend) {
+ $this->backends[$storageType] = $backend;
+ }
+
+ /**
+ * @return IVersionBackend[]
+ */
+ private function getBackends(): array {
+ return $this->backends;
+ }
+
+ /**
+ * @param IStorage $storage
+ * @return IVersionBackend
+ * @throws BackendNotFoundException
+ */
+ public function getBackendForStorage(IStorage $storage): IVersionBackend {
+ $fullType = get_class($storage);
+ $backends = $this->getBackends();
+ $foundType = array_reduce(array_keys($backends), function ($type, $registeredType) use ($storage) {
+ if (
+ $storage->instanceOfStorage($registeredType) &&
+ ($type === '' || is_subclass_of($registeredType, $type))
+ ) {
+ return $registeredType;
+ } else {
+ return $type;
+ }
+ }, '');
+ if ($foundType === '') {
+ throw new BackendNotFoundException("Version backend for $fullType not found");
+ } else {
+ return $backends[$foundType];
+ }
+ }
+
+ public function getVersionsForFile(IUser $user, FileInfo $file): array {
+ $backend = $this->getBackendForStorage($file->getStorage());
+ return $backend->getVersionsForFile($user, $file);
+ }
+
+ public function createVersion(IUser $user, FileInfo $file) {
+ $backend = $this->getBackendForStorage($file->getStorage());
+ $backend->createVersion($user, $file);
+ }
+
+ public function rollback(IVersion $version) {
+ $backend = $version->getBackend();
+ return $backend->rollback($version);
+ }
+
+ public function read(IVersion $version) {
+ $backend = $version->getBackend();
+ return $backend->read($version);
+ }
+
+ public function getVersionFile(IUser $user, FileInfo $sourceFile, int $revision): File {
+ $backend = $this->getBackendForStorage($sourceFile->getStorage());
+ return $backend->getVersionFile($user, $sourceFile, $revision);
+ }
+}
diff --git a/apps/files_versions/tests/Controller/PreviewControllerTest.php b/apps/files_versions/tests/Controller/PreviewControllerTest.php
index 384f43cf495..7c248b36349 100644
--- a/apps/files_versions/tests/Controller/PreviewControllerTest.php
+++ b/apps/files_versions/tests/Controller/PreviewControllerTest.php
@@ -20,9 +20,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
namespace OCA\Files_Versions\Tests\Controller;
+use OC\User\User;
use OCA\Files_Versions\Controller\PreviewController;
+use OCA\Files_Versions\Versions\IVersionManager;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\Http\FileDisplayResponse;
@@ -34,6 +37,8 @@ use OCP\Files\NotFoundException;
use OCP\Files\SimpleFS\ISimpleFile;
use OCP\IPreview;
use OCP\IRequest;
+use OCP\IUser;
+use OCP\IUserSession;
use Test\TestCase;
class PreviewControllerTest extends TestCase {
@@ -50,23 +55,39 @@ class PreviewControllerTest extends TestCase {
/** @var IPreview|\PHPUnit_Framework_MockObject_MockObject */
private $previewManager;
- /** @var PreviewController */
+ /** @var PreviewController|\PHPUnit_Framework_MockObject_MockObject */
private $controller;
+ /** @var IUserSession|\PHPUnit_Framework_MockObject_MockObject */
+ private $userSession;
+
+ /** @var IVersionManager|\PHPUnit_Framework_MockObject_MockObject */
+ private $versionManager;
+
public function setUp() {
parent::setUp();
$this->rootFolder = $this->createMock(IRootFolder::class);
$this->userId = 'user';
+ $user = $this->createMock(IUser::class);
+ $user->expects($this->any())
+ ->method('getUID')
+ ->willReturn($this->userId);
$this->mimeTypeDetector = $this->createMock(IMimeTypeDetector::class);
$this->previewManager = $this->createMock(IPreview::class);
+ $this->userSession = $this->createMock(IUserSession::class);
+ $this->userSession->expects($this->any())
+ ->method('getUser')
+ ->willReturn($user);
+ $this->versionManager = $this->createMock(IVersionManager::class);
$this->controller = new PreviewController(
'files_versions',
$this->createMock(IRequest::class),
$this->rootFolder,
- $this->userId,
+ $this->userSession,
$this->mimeTypeDetector,
+ $this->versionManager,
$this->previewManager
);
}
@@ -102,24 +123,23 @@ class PreviewControllerTest extends TestCase {
public function testValidPreview() {
$userFolder = $this->createMock(Folder::class);
$userRoot = $this->createMock(Folder::class);
- $versions = $this->createMock(Folder::class);
$this->rootFolder->method('getUserFolder')
->with($this->userId)
->willReturn($userFolder);
$userFolder->method('getParent')
->willReturn($userRoot);
- $userRoot->method('get')
- ->with('files_versions')
- ->willReturn($versions);
- $this->mimeTypeDetector->method('detectPath')
- ->with($this->equalTo('file'))
- ->willReturn('myMime');
+ $sourceFile = $this->createMock(File::class);
+ $userFolder->method('get')
+ ->with('file')
+ ->willReturn($sourceFile);
$file = $this->createMock(File::class);
- $versions->method('get')
- ->with($this->equalTo('file.v42'))
+ $file->method('getMimetype')
+ ->willReturn('myMime');
+
+ $this->versionManager->method('getVersionFile')
->willReturn($file);
$preview = $this->createMock(ISimpleFile::class);
@@ -138,24 +158,23 @@ class PreviewControllerTest extends TestCase {
public function testVersionNotFound() {
$userFolder = $this->createMock(Folder::class);
$userRoot = $this->createMock(Folder::class);
- $versions = $this->createMock(Folder::class);
$this->rootFolder->method('getUserFolder')
->with($this->userId)
->willReturn($userFolder);
$userFolder->method('getParent')
->willReturn($userRoot);
- $userRoot->method('get')
- ->with('files_versions')
- ->willReturn($versions);
+
+ $sourceFile = $this->createMock(File::class);
+ $userFolder->method('get')
+ ->with('file')
+ ->willReturn($sourceFile);
$this->mimeTypeDetector->method('detectPath')
->with($this->equalTo('file'))
->willReturn('myMime');
- $file = $this->createMock(File::class);
- $versions->method('get')
- ->with($this->equalTo('file.v42'))
+ $this->versionManager->method('getVersionFile')
->willThrowException(new NotFoundException());
$res = $this->controller->getPreview('file', 10, 10, '42');
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/composer/composer/autoload_classmap.php b/apps/user_ldap/composer/composer/autoload_classmap.php
index 98a1bbfa1b7..e25b7ee3126 100644
--- a/apps/user_ldap/composer/composer/autoload_classmap.php
+++ b/apps/user_ldap/composer/composer/autoload_classmap.php
@@ -56,7 +56,6 @@ return array(
'OCA\\User_LDAP\\Settings\\Section' => $baseDir . '/../lib/Settings/Section.php',
'OCA\\User_LDAP\\UserPluginManager' => $baseDir . '/../lib/UserPluginManager.php',
'OCA\\User_LDAP\\User\\DeletedUsersIndex' => $baseDir . '/../lib/User/DeletedUsersIndex.php',
- 'OCA\\User_LDAP\\User\\IUserTools' => $baseDir . '/../lib/User/IUserTools.php',
'OCA\\User_LDAP\\User\\Manager' => $baseDir . '/../lib/User/Manager.php',
'OCA\\User_LDAP\\User\\OfflineUser' => $baseDir . '/../lib/User/OfflineUser.php',
'OCA\\User_LDAP\\User\\User' => $baseDir . '/../lib/User/User.php',
diff --git a/apps/user_ldap/composer/composer/autoload_static.php b/apps/user_ldap/composer/composer/autoload_static.php
index 83e49daf0f3..23819055be4 100644
--- a/apps/user_ldap/composer/composer/autoload_static.php
+++ b/apps/user_ldap/composer/composer/autoload_static.php
@@ -71,7 +71,6 @@ class ComposerStaticInitUser_LDAP
'OCA\\User_LDAP\\Settings\\Section' => __DIR__ . '/..' . '/../lib/Settings/Section.php',
'OCA\\User_LDAP\\UserPluginManager' => __DIR__ . '/..' . '/../lib/UserPluginManager.php',
'OCA\\User_LDAP\\User\\DeletedUsersIndex' => __DIR__ . '/..' . '/../lib/User/DeletedUsersIndex.php',
- 'OCA\\User_LDAP\\User\\IUserTools' => __DIR__ . '/..' . '/../lib/User/IUserTools.php',
'OCA\\User_LDAP\\User\\Manager' => __DIR__ . '/..' . '/../lib/User/Manager.php',
'OCA\\User_LDAP\\User\\OfflineUser' => __DIR__ . '/..' . '/../lib/User/OfflineUser.php',
'OCA\\User_LDAP\\User\\User' => __DIR__ . '/..' . '/../lib/User/User.php',
diff --git a/apps/user_ldap/lib/Access.php b/apps/user_ldap/lib/Access.php
index d0d51ae8c85..fb2582e8266 100644
--- a/apps/user_ldap/lib/Access.php
+++ b/apps/user_ldap/lib/Access.php
@@ -46,7 +46,6 @@ namespace OCA\User_LDAP;
use OC\HintException;
use OC\Hooks\PublicEmitter;
use OCA\User_LDAP\Exceptions\ConstraintViolationException;
-use OCA\User_LDAP\User\IUserTools;
use OCA\User_LDAP\User\Manager;
use OCA\User_LDAP\User\OfflineUser;
use OCA\User_LDAP\Mapping\AbstractMapping;
@@ -59,7 +58,7 @@ use OCP\IUserManager;
* Class Access
* @package OCA\User_LDAP
*/
-class Access extends LDAPUtility implements IUserTools {
+class Access extends LDAPUtility {
const UUID_ATTRIBUTES = ['entryuuid', 'nsuniqueid', 'objectguid', 'guid', 'ipauniqueid'];
/** @var \OCA\User_LDAP\Connection */
diff --git a/apps/user_ldap/lib/User/IUserTools.php b/apps/user_ldap/lib/User/IUserTools.php
deleted file mode 100644
index 4ba9cebb1a6..00000000000
--- a/apps/user_ldap/lib/User/IUserTools.php
+++ /dev/null
@@ -1,42 +0,0 @@
-<?php
-/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- *
- * @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 OCA\User_LDAP\User;
-
-/**
- * IUserTools
- *
- * defines methods that are required by User class for LDAP interaction
- */
-interface IUserTools {
- public function getConnection();
-
- public function readAttribute($dn, $attr, $filter = 'objectClass=*');
-
- public function stringResemblesDN($string);
-
- public function dn2username($dn, $ldapname = null);
-
- public function username2dn($name);
-}
diff --git a/apps/user_ldap/lib/User/Manager.php b/apps/user_ldap/lib/User/Manager.php
index 9f2f3649777..13555f9e31b 100644
--- a/apps/user_ldap/lib/User/Manager.php
+++ b/apps/user_ldap/lib/User/Manager.php
@@ -45,7 +45,7 @@ use OCP\Notification\IManager as INotificationManager;
* cache
*/
class Manager {
- /** @var IUserTools */
+ /** @var Access */
protected $access;
/** @var IConfig */
@@ -110,11 +110,11 @@ class Manager {
}
/**
- * @brief binds manager to an instance of IUserTools (implemented by
- * Access). It needs to be assigned first before the manager can be used.
- * @param IUserTools
+ * Binds manager to an instance of Access.
+ * It needs to be assigned first before the manager can be used.
+ * @param Access
*/
- public function setLdapAccess(IUserTools $access) {
+ public function setLdapAccess(Access $access) {
$this->access = $access;
}
diff --git a/apps/user_ldap/lib/User/User.php b/apps/user_ldap/lib/User/User.php
index 02764a72eca..706424d3189 100644
--- a/apps/user_ldap/lib/User/User.php
+++ b/apps/user_ldap/lib/User/User.php
@@ -30,6 +30,7 @@
namespace OCA\User_LDAP\User;
+use OCA\User_LDAP\Access;
use OCA\User_LDAP\Connection;
use OCA\User_LDAP\FilesystemHelper;
use OCA\User_LDAP\LogWrapper;
@@ -48,7 +49,7 @@ use OCP\Notification\IManager as INotificationManager;
*/
class User {
/**
- * @var IUserTools
+ * @var Access
*/
protected $access;
/**
@@ -110,8 +111,7 @@ class User {
* @brief constructor, make sure the subclasses call this one!
* @param string $username the internal username
* @param string $dn the LDAP DN
- * @param IUserTools $access an instance that implements IUserTools for
- * LDAP interaction
+ * @param Access $access
* @param IConfig $config
* @param FilesystemHelper $fs
* @param Image $image any empty instance
@@ -120,7 +120,7 @@ class User {
* @param IUserManager $userManager
* @param INotificationManager $notificationManager
*/
- public function __construct($username, $dn, IUserTools $access,
+ public function __construct($username, $dn, Access $access,
IConfig $config, FilesystemHelper $fs, Image $image,
LogWrapper $log, IAvatarManager $avatarManager, IUserManager $userManager,
INotificationManager $notificationManager) {
@@ -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 104a70ff700..5c111abdc4e 100644
--- a/apps/user_ldap/tests/User/ManagerTest.php
+++ b/apps/user_ldap/tests/User/ManagerTest.php
@@ -28,11 +28,13 @@
namespace OCA\User_LDAP\Tests\User;
+use OCA\User_LDAP\Access;
+use OCA\User_LDAP\Connection;
use OCA\User_LDAP\FilesystemHelper;
use OCA\User_LDAP\ILDAPWrapper;
use OCA\User_LDAP\LogWrapper;
-use OCA\User_LDAP\User\IUserTools;
use OCA\User_LDAP\User\Manager;
+use OCA\User_LDAP\User\User;
use OCP\IAvatarManager;
use OCP\IConfig;
use OCP\IDBConnection;
@@ -48,200 +50,181 @@ use OCP\Notification\IManager as INotificationManager;
* @package OCA\User_LDAP\Tests\User
*/
class ManagerTest extends \Test\TestCase {
+ /** @var Access|\PHPUnit_Framework_MockObject_MockObject */
+ protected $access;
- private function getTestInstances() {
- $access = $this->createMock(IUserTools::class);
- $config = $this->createMock(IConfig::class);
- $filesys = $this->createMock(FilesystemHelper::class);
- $log = $this->createMock(LogWrapper::class);
- $avaMgr = $this->createMock(IAvatarManager::class);
- $image = $this->createMock(Image::class);
- $dbc = $this->createMock(IDBConnection::class);
- $userMgr = $this->createMock(IUserManager::class);
- $notiMgr = $this->createMock(INotificationManager::class);
-
- $connection = new \OCA\User_LDAP\Connection(
- $lw = $this->createMock(ILDAPWrapper::class),
- '',
- null
- );
+ /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */
+ protected $config;
- $access->expects($this->any())
- ->method('getConnection')
- ->will($this->returnValue($connection));
+ /** @var FilesystemHelper|\PHPUnit_Framework_MockObject_MockObject */
+ protected $fileSystemHelper;
- return array($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr);
- }
+ /** @var LogWrapper|\PHPUnit_Framework_MockObject_MockObject */
+ protected $log;
- public function testGetByDNExisting() {
- list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) =
- $this->getTestInstances();
+ /** @var IAvatarManager|\PHPUnit_Framework_MockObject_MockObject */
+ protected $avatarManager;
- $inputDN = 'cn=foo,dc=foobar,dc=bar';
- $uid = '563418fc-423b-1033-8d1c-ad5f418ee02e';
+ /** @var Image|\PHPUnit_Framework_MockObject_MockObject */
+ protected $image;
- $access->expects($this->once())
- ->method('stringResemblesDN')
- ->with($this->equalTo($inputDN))
- ->will($this->returnValue(true));
+ /** @var IDBConnection|\PHPUnit_Framework_MockObject_MockObject */
+ protected $dbc;
- $access->expects($this->once())
- ->method('dn2username')
- ->with($this->equalTo($inputDN))
- ->will($this->returnValue($uid));
+ /** @var IUserManager|\PHPUnit_Framework_MockObject_MockObject */
+ protected $ncUserManager;
- $access->expects($this->never())
- ->method('username2dn');
+ /** @var INotificationManager|\PHPUnit_Framework_MockObject_MockObject */
+ protected $notificationManager;
- $manager = new Manager($config, $filesys, $log, $avaMgr, $image, $dbc, $userMgr, $notiMgr);
- $manager->setLdapAccess($access);
- $user = $manager->get($inputDN);
+ /** @var ILDAPWrapper|\PHPUnit_Framework_MockObject_MockObject */
+ protected $ldapWrapper;
- // Now we fetch the user again. If this leads to a failing test,
- // runtime caching the manager is broken.
- $user = $manager->get($inputDN);
-
- $this->assertInstanceOf('\OCA\User_LDAP\User\User', $user);
- }
+ /** @var Connection */
+ protected $connection;
- public function testGetByEDirectoryDN() {
- list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) =
- $this->getTestInstances();
+ /** @var Manager */
+ protected $manager;
- $inputDN = 'uid=foo,o=foobar,c=bar';
- $uid = '563418fc-423b-1033-8d1c-ad5f418ee02e';
+ public function setUp() {
+ parent::setUp();
- $access->expects($this->once())
- ->method('stringResemblesDN')
- ->with($this->equalTo($inputDN))
- ->will($this->returnValue(true));
-
- $access->expects($this->once())
- ->method('dn2username')
- ->with($this->equalTo($inputDN))
- ->will($this->returnValue($uid));
+ $this->access = $this->createMock(Access::class);
+ $this->config = $this->createMock(IConfig::class);
+ $this->fileSystemHelper = $this->createMock(FilesystemHelper::class);
+ $this->log = $this->createMock(LogWrapper::class);
+ $this->avatarManager = $this->createMock(IAvatarManager::class);
+ $this->image = $this->createMock(Image::class);
+ $this->dbc = $this->createMock(IDBConnection::class);
+ $this->ncUserManager = $this->createMock(IUserManager::class);
+ $this->notificationManager = $this->createMock(INotificationManager::class);
- $access->expects($this->never())
- ->method('username2dn');
+ $this->ldapWrapper = $this->createMock(ILDAPWrapper::class);
+ $this->connection = new Connection($this->ldapWrapper, '', null);
- $manager = new Manager($config, $filesys, $log, $avaMgr, $image, $dbc, $userMgr, $notiMgr);
- $manager->setLdapAccess($access);
- $user = $manager->get($inputDN);
+ $this->access->expects($this->any())
+ ->method('getConnection')
+ ->will($this->returnValue($this->connection));
+
+ /** @noinspection PhpUnhandledExceptionInspection */
+ $this->manager = new Manager(
+ $this->config,
+ $this->fileSystemHelper,
+ $this->log,
+ $this->avatarManager,
+ $this->image,
+ $this->dbc,
+ $this->ncUserManager,
+ $this->notificationManager
+ );
- $this->assertInstanceOf('\OCA\User_LDAP\User\User', $user);
+ $this->manager->setLdapAccess($this->access);
}
- public function testGetByExoticDN() {
- list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) =
- $this->getTestInstances();
+ public function dnProvider() {
+ return [
+ ['cn=foo,dc=foobar,dc=bar'],
+ ['uid=foo,o=foobar,c=bar'],
+ ['ab=cde,f=ghei,mno=pq'],
+ ];
+ }
- $inputDN = 'ab=cde,f=ghei,mno=pq';
+ /**
+ * @dataProvider dnProvider
+ */
+ public function testGetByDNExisting(string $inputDN) {
$uid = '563418fc-423b-1033-8d1c-ad5f418ee02e';
- $access->expects($this->once())
+ $this->access->expects($this->once())
->method('stringResemblesDN')
->with($this->equalTo($inputDN))
->will($this->returnValue(true));
-
- $access->expects($this->once())
+ $this->access->expects($this->once())
->method('dn2username')
->with($this->equalTo($inputDN))
->will($this->returnValue($uid));
-
- $access->expects($this->never())
+ $this->access->expects($this->never())
->method('username2dn');
- $manager = new Manager($config, $filesys, $log, $avaMgr, $image, $dbc, $userMgr, $notiMgr);
- $manager->setLdapAccess($access);
- $user = $manager->get($inputDN);
+ /** @noinspection PhpUnhandledExceptionInspection */
+ $this->manager->get($inputDN);
- $this->assertInstanceOf('\OCA\User_LDAP\User\User', $user);
+ // Now we fetch the user again. If this leads to a failing test,
+ // runtime caching the manager is broken.
+ /** @noinspection PhpUnhandledExceptionInspection */
+ $user = $this->manager->get($inputDN);
+
+ $this->assertInstanceOf(User::class, $user);
}
public function testGetByDNNotExisting() {
- list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) =
- $this->getTestInstances();
-
$inputDN = 'cn=gone,dc=foobar,dc=bar';
- $access->expects($this->once())
+ $this->access->expects($this->once())
->method('stringResemblesDN')
->with($this->equalTo($inputDN))
->will($this->returnValue(true));
-
- $access->expects($this->once())
+ $this->access->expects($this->once())
->method('dn2username')
->with($this->equalTo($inputDN))
->will($this->returnValue(false));
-
- $access->expects($this->once())
+ $this->access->expects($this->once())
->method('username2dn')
->with($this->equalTo($inputDN))
->will($this->returnValue(false));
- $manager = new Manager($config, $filesys, $log, $avaMgr, $image, $dbc, $userMgr, $notiMgr);
- $manager->setLdapAccess($access);
- $user = $manager->get($inputDN);
+ /** @noinspection PhpUnhandledExceptionInspection */
+ $user = $this->manager->get($inputDN);
$this->assertNull($user);
}
public function testGetByUidExisting() {
- list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) =
- $this->getTestInstances();
-
$dn = 'cn=foo,dc=foobar,dc=bar';
$uid = '563418fc-423b-1033-8d1c-ad5f418ee02e';
- $access->expects($this->never())
+ $this->access->expects($this->never())
->method('dn2username');
-
- $access->expects($this->once())
+ $this->access->expects($this->once())
->method('username2dn')
->with($this->equalTo($uid))
->will($this->returnValue($dn));
-
- $access->expects($this->once())
+ $this->access->expects($this->once())
->method('stringResemblesDN')
->with($this->equalTo($uid))
->will($this->returnValue(false));
- $manager = new Manager($config, $filesys, $log, $avaMgr, $image, $dbc, $userMgr, $notiMgr);
- $manager->setLdapAccess($access);
- $user = $manager->get($uid);
+ /** @noinspection PhpUnhandledExceptionInspection */
+ $this->manager->get($uid);
// Now we fetch the user again. If this leads to a failing test,
// runtime caching the manager is broken.
- $user = $manager->get($uid);
+ /** @noinspection PhpUnhandledExceptionInspection */
+ $user = $this->manager->get($uid);
- $this->assertInstanceOf('\OCA\User_LDAP\User\User', $user);
+ $this->assertInstanceOf(User::class, $user);
}
public function testGetByUidNotExisting() {
- list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) =
- $this->getTestInstances();
-
$uid = 'gone';
- $access->expects($this->never())
+ $this->access->expects($this->never())
->method('dn2username');
-
- $access->expects($this->exactly(1))
+ $this->access->expects($this->exactly(1))
->method('username2dn')
->with($this->equalTo($uid))
->will($this->returnValue(false));
- $manager = new Manager($config, $filesys, $log, $avaMgr, $image, $dbc, $userMgr, $notiMgr);
- $manager->setLdapAccess($access);
- $user = $manager->get($uid);
+ /** @noinspection PhpUnhandledExceptionInspection */
+ $user = $this->manager->get($uid);
$this->assertNull($user);
}
public function attributeRequestProvider() {
return [
- [ false ],
- [ true ],
+ [false],
+ [true],
];
}
@@ -249,23 +232,16 @@ class ManagerTest extends \Test\TestCase {
* @dataProvider attributeRequestProvider
*/
public function testGetAttributes($minimal) {
- list($access, $config, $filesys, $image, $log, $avaMgr, $dbc, $userMgr, $notiMgr) =
- $this->getTestInstances();
-
- $manager = new Manager($config, $filesys, $log, $avaMgr, $image, $dbc, $userMgr, $notiMgr);
- $manager->setLdapAccess($access);
-
- $connection = $access->getConnection();
- $connection->setConfiguration([
+ $this->connection->setConfiguration([
'ldapEmailAttribute' => 'mail',
'ldapUserAvatarRule' => 'default',
'ldapQuotaAttribute' => '',
]);
- $attributes = $manager->getAttributes($minimal);
+ $attributes = $this->manager->getAttributes($minimal);
$this->assertTrue(in_array('dn', $attributes));
- $this->assertTrue(in_array($access->getConnection()->ldapEmailAttribute, $attributes));
+ $this->assertTrue(in_array($this->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/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/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/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/apps.scss b/core/css/apps.scss
index 8b94d08ce2e..54372afa45a 100644
--- a/core/css/apps.scss
+++ b/core/css/apps.scss
@@ -781,27 +781,47 @@ kbd {
/* TABS ------------------------------------------------------------ */
.tabHeaders {
- display: inline-block;
- margin: 15px;
+ display: flex;
+ margin-bottom: 16px;
+
.tabHeader {
- float: left;
- padding: 12px;
+ display: flex;
+ flex-direction: column;
+ flex-grow: 1;
+ text-align: center;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
cursor: pointer;
color: var(--color-text-lighter);
margin-bottom: 1px;
+ padding: 5px;
+
+ /* Use same amount as sidebar padding */
+ &:first-child {
+ padding-left: 15px;
+ }
+ &:last-child {
+ padding-right: 15px;
+ }
+
.icon {
display: inline-block;
- width: 16px;
+ width: 100%;
height: 16px;
background-size: 16px;
vertical-align: middle;
margin-top: -2px;
margin-right: 3px;
opacity: .7;
+ cursor: pointer;
}
+
a {
color: var(--color-text-lighter);
margin-bottom: 1px;
+ overflow: hidden;
+ text-overflow: ellipsis;
}
&.selected {
font-weight: bold;
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/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/sharedialogshareelistview.js b/core/js/sharedialogshareelistview.js
index 93373a54435..94abf55a358 100644
--- a/core/js/sharedialogshareelistview.js
+++ b/core/js/sharedialogshareelistview.js
@@ -314,7 +314,9 @@
var $edit = _this.$('#canEdit-' + _this.cid + '-' + sharee.shareId);
if($edit.length === 1) {
$edit.prop('checked', sharee.editPermissionState === 'checked');
- $edit.prop('indeterminate', sharee.editPermissionState === 'indeterminate');
+ if (sharee.isFolder) {
+ $edit.prop('indeterminate', sharee.editPermissionState === 'indeterminate');
+ }
}
});
this.$('.popovermenu').on('afterHide', function() {
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..84715ec87c1 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,
@@ -614,6 +616,12 @@
var hcp = this.hasCreatePermission(shareIndex);
var hup = this.hasUpdatePermission(shareIndex);
var hdp = this.hasDeletePermission(shareIndex);
+ if (this.isFile()) {
+ if (hcp || hup || hdp) {
+ return 'checked';
+ }
+ return '';
+ }
if (!hcp && !hup && !hdp) {
return '';
}
@@ -866,6 +874,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/sharedialogshareelistview.js b/core/js/tests/specs/sharedialogshareelistview.js
index 8e34225d199..e51fc2df72d 100644
--- a/core/js/tests/specs/sharedialogshareelistview.js
+++ b/core/js/tests/specs/sharedialogshareelistview.js
@@ -90,6 +90,37 @@ describe('OC.Share.ShareDialogShareeListView', function () {
});
describe('Sets correct initial checkbox state', function () {
+
+ it('marks edit box as unchecked for file shares without edit permissions', function () {
+ shareModel.set('shares', [{
+ id: 100,
+ item_source: 123,
+ permissions: 1,
+ share_type: OC.Share.SHARE_TYPE_USER,
+ share_with: 'user1',
+ share_with_displayname: 'User One',
+ uid_owner: oc_current_user,
+ itemType: 'file'
+ }]);
+ listView.render();
+ expect(listView.$el.find("input[name='edit']").is(':not(:checked)')).toEqual(true);
+ });
+
+ it('marks edit box as checked for file shares', function () {
+ shareModel.set('shares', [{
+ id: 100,
+ item_source: 123,
+ permissions: 1 | OC.PERMISSION_UPDATE,
+ share_type: OC.Share.SHARE_TYPE_USER,
+ share_with: 'user1',
+ share_with_displayname: 'User One',
+ uid_owner: oc_current_user,
+ itemType: 'file'
+ }]);
+ listView.render();
+ expect(listView.$el.find("input[name='edit']").is(':checked')).toEqual(true);
+ });
+
it('marks edit box as indeterminate when only some permissions are given', function () {
shareModel.set('shares', [{
id: 100,
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 7f7d83e37c5..0b0b26b723e 100644
--- a/core/l10n/is.js
+++ b/core/l10n/is.js
@@ -204,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)...",
@@ -372,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.",
@@ -403,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 a2837609110..05092ee314c 100644
--- a/core/l10n/is.json
+++ b/core/l10n/is.json
@@ -202,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)...",
@@ -370,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.",
@@ -401,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 b1785137d1d..05659963e02 100644
--- a/core/l10n/nb.js
+++ b/core/l10n/nb.js
@@ -210,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…",
@@ -382,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.",
@@ -413,6 +412,7 @@ OC.L10N.register(
"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 704c3dc27f7..75981eb1d71 100644
--- a/core/l10n/nb.json
+++ b/core/l10n/nb.json
@@ -208,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…",
@@ -380,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.",
@@ -411,6 +410,7 @@
"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 ca39729ad29..815c457edf9 100644
--- a/core/l10n/zh_CN.js
+++ b/core/l10n/zh_CN.js
@@ -209,12 +209,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})" : "{share}({type},{owner})",
- "{sharee} (conversation)" : "{sharee}(对话)",
"Share" : "共享",
"Name or email address..." : "姓名或电子邮件地址...",
"Name or federated cloud ID..." : "姓名或联合云 ID...",
@@ -381,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." : "输入用户/组织或邮箱地址来共享给其他人.",
@@ -412,6 +411,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/zh_CN.json b/core/l10n/zh_CN.json
index 3a6f1c58999..87f1b38c1f5 100644
--- a/core/l10n/zh_CN.json
+++ b/core/l10n/zh_CN.json
@@ -207,12 +207,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})" : "{share}({type},{owner})",
- "{sharee} (conversation)" : "{sharee}(对话)",
"Share" : "共享",
"Name or email address..." : "姓名或电子邮件地址...",
"Name or federated cloud ID..." : "姓名或联合云 ID...",
@@ -379,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." : "输入用户/组织或邮箱地址来共享给其他人.",
@@ -410,6 +409,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=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/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 e880d5ede49..d7523d52caa 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',
@@ -652,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',
@@ -803,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',
@@ -811,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 c5f6211b69d..cf2fef4282d 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',
@@ -682,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',
@@ -833,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',
@@ -841,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/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/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/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/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/resources/app-info.xsd b/resources/app-info.xsd
index fa06752c01d..287ed6b9913 100644
--- a/resources/app-info.xsd
+++ b/resources/app-info.xsd
@@ -63,6 +63,8 @@
maxOccurs="1" />
<xs:element name="trash" type="trash" minOccurs="0"
maxOccurs="1" />
+ <xs:element name="versions" type="versions" minOccurs="0"
+ maxOccurs="1" />
</xs:sequence>
</xs:complexType>
<xs:unique name="uniqueNameL10n">
@@ -670,6 +672,21 @@
</xs:simpleContent>
</xs:complexType>
+ <xs:complexType name="versions">
+ <xs:sequence>
+ <xs:element name="backend" type="versions-backend" minOccurs="1"
+ maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="versions-backend">
+ <xs:simpleContent>
+ <xs:extension base="php-class">
+ <xs:attribute name="for" type="php-class" use="required"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
<xs:simpleType name="php-class">
<xs:restriction base="xs:string">
<xs:pattern
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/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/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/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/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/Repair/SetVcardDatabaseUIDTest.php b/tests/lib/Repair/SetVcardDatabaseUIDTest.php
index fe1a7481d7b..97da3c6a901 100644
--- a/tests/lib/Repair/SetVcardDatabaseUIDTest.php
+++ b/tests/lib/Repair/SetVcardDatabaseUIDTest.php
@@ -118,4 +118,4 @@ class SetVcardDatabaseUIDTest extends TestCase {
$this->assertEquals($expected, $this->invokePrivate($this->repair, 'shouldRun'));
}
-} \ No newline at end of file
+}