aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/autoloader.php169
-rw-r--r--lib/base.php83
-rw-r--r--lib/composer/autoload.php5
-rw-r--r--lib/composer/composer/autoload_classmap.php34
-rw-r--r--lib/composer/composer/autoload_static.php34
-rw-r--r--lib/l10n/af.js4
-rw-r--r--lib/l10n/af.json4
-rw-r--r--lib/l10n/an.js3
-rw-r--r--lib/l10n/an.json3
-rw-r--r--lib/l10n/ar.js16
-rw-r--r--lib/l10n/ar.json16
-rw-r--r--lib/l10n/ast.js15
-rw-r--r--lib/l10n/ast.json15
-rw-r--r--lib/l10n/az.js3
-rw-r--r--lib/l10n/az.json3
-rw-r--r--lib/l10n/bg.js23
-rw-r--r--lib/l10n/bg.json23
-rw-r--r--lib/l10n/bn_BD.js3
-rw-r--r--lib/l10n/bn_BD.json3
-rw-r--r--lib/l10n/br.js6
-rw-r--r--lib/l10n/br.json6
-rw-r--r--lib/l10n/bs.js3
-rw-r--r--lib/l10n/bs.json3
-rw-r--r--lib/l10n/ca.js15
-rw-r--r--lib/l10n/ca.json15
-rw-r--r--lib/l10n/cs.js23
-rw-r--r--lib/l10n/cs.json23
-rw-r--r--lib/l10n/cy_GB.js5
-rw-r--r--lib/l10n/cy_GB.json5
-rw-r--r--lib/l10n/da.js15
-rw-r--r--lib/l10n/da.json15
-rw-r--r--lib/l10n/de.js29
-rw-r--r--lib/l10n/de.json29
-rw-r--r--lib/l10n/de_DE.js31
-rw-r--r--lib/l10n/de_DE.json31
-rw-r--r--lib/l10n/el.js15
-rw-r--r--lib/l10n/el.json15
-rw-r--r--lib/l10n/en_GB.js23
-rw-r--r--lib/l10n/en_GB.json23
-rw-r--r--lib/l10n/eo.js15
-rw-r--r--lib/l10n/eo.json15
-rw-r--r--lib/l10n/es.js22
-rw-r--r--lib/l10n/es.json22
-rw-r--r--lib/l10n/es_419.js10
-rw-r--r--lib/l10n/es_419.json10
-rw-r--r--lib/l10n/es_AR.js11
-rw-r--r--lib/l10n/es_AR.json11
-rw-r--r--lib/l10n/es_CL.js10
-rw-r--r--lib/l10n/es_CL.json10
-rw-r--r--lib/l10n/es_CO.js10
-rw-r--r--lib/l10n/es_CO.json10
-rw-r--r--lib/l10n/es_CR.js10
-rw-r--r--lib/l10n/es_CR.json10
-rw-r--r--lib/l10n/es_DO.js10
-rw-r--r--lib/l10n/es_DO.json10
-rw-r--r--lib/l10n/es_EC.js15
-rw-r--r--lib/l10n/es_EC.json15
-rw-r--r--lib/l10n/es_GT.js10
-rw-r--r--lib/l10n/es_GT.json10
-rw-r--r--lib/l10n/es_HN.js10
-rw-r--r--lib/l10n/es_HN.json10
-rw-r--r--lib/l10n/es_MX.js15
-rw-r--r--lib/l10n/es_MX.json15
-rw-r--r--lib/l10n/es_NI.js10
-rw-r--r--lib/l10n/es_NI.json10
-rw-r--r--lib/l10n/es_PA.js10
-rw-r--r--lib/l10n/es_PA.json10
-rw-r--r--lib/l10n/es_PE.js10
-rw-r--r--lib/l10n/es_PE.json10
-rw-r--r--lib/l10n/es_PR.js10
-rw-r--r--lib/l10n/es_PR.json10
-rw-r--r--lib/l10n/es_PY.js10
-rw-r--r--lib/l10n/es_PY.json10
-rw-r--r--lib/l10n/es_SV.js10
-rw-r--r--lib/l10n/es_SV.json10
-rw-r--r--lib/l10n/es_UY.js10
-rw-r--r--lib/l10n/es_UY.json10
-rw-r--r--lib/l10n/et_EE.js135
-rw-r--r--lib/l10n/et_EE.json135
-rw-r--r--lib/l10n/eu.js15
-rw-r--r--lib/l10n/eu.json15
-rw-r--r--lib/l10n/fa.js399
-rw-r--r--lib/l10n/fa.json399
-rw-r--r--lib/l10n/fi.js15
-rw-r--r--lib/l10n/fi.json15
-rw-r--r--lib/l10n/fr.js23
-rw-r--r--lib/l10n/fr.json23
-rw-r--r--lib/l10n/ga.js23
-rw-r--r--lib/l10n/ga.json23
-rw-r--r--lib/l10n/gl.js17
-rw-r--r--lib/l10n/gl.json17
-rw-r--r--lib/l10n/he.js15
-rw-r--r--lib/l10n/he.json15
-rw-r--r--lib/l10n/hr.js15
-rw-r--r--lib/l10n/hr.json15
-rw-r--r--lib/l10n/hu.js17
-rw-r--r--lib/l10n/hu.json17
-rw-r--r--lib/l10n/hy.js3
-rw-r--r--lib/l10n/hy.json3
-rw-r--r--lib/l10n/ia.js3
-rw-r--r--lib/l10n/ia.json3
-rw-r--r--lib/l10n/id.js5
-rw-r--r--lib/l10n/id.json5
-rw-r--r--lib/l10n/is.js15
-rw-r--r--lib/l10n/is.json15
-rw-r--r--lib/l10n/it.js17
-rw-r--r--lib/l10n/it.json17
-rw-r--r--lib/l10n/ja.js23
-rw-r--r--lib/l10n/ja.json23
-rw-r--r--lib/l10n/ka.js15
-rw-r--r--lib/l10n/ka.json15
-rw-r--r--lib/l10n/ka_GE.js10
-rw-r--r--lib/l10n/ka_GE.json10
-rw-r--r--lib/l10n/kab.js3
-rw-r--r--lib/l10n/kab.json3
-rw-r--r--lib/l10n/km.js3
-rw-r--r--lib/l10n/km.json3
-rw-r--r--lib/l10n/kn.js3
-rw-r--r--lib/l10n/kn.json3
-rw-r--r--lib/l10n/ko.js22
-rw-r--r--lib/l10n/ko.json22
-rw-r--r--lib/l10n/lb.js3
-rw-r--r--lib/l10n/lb.json3
-rw-r--r--lib/l10n/lo.js3
-rw-r--r--lib/l10n/lo.json3
-rw-r--r--lib/l10n/lt_LT.js14
-rw-r--r--lib/l10n/lt_LT.json14
-rw-r--r--lib/l10n/lv.js31
-rw-r--r--lib/l10n/lv.json31
-rw-r--r--lib/l10n/mk.js19
-rw-r--r--lib/l10n/mk.json19
-rw-r--r--lib/l10n/mn.js7
-rw-r--r--lib/l10n/mn.json7
-rw-r--r--lib/l10n/ms_MY.js4
-rw-r--r--lib/l10n/ms_MY.json4
-rw-r--r--lib/l10n/nb.js15
-rw-r--r--lib/l10n/nb.json15
-rw-r--r--lib/l10n/nl.js25
-rw-r--r--lib/l10n/nl.json25
-rw-r--r--lib/l10n/nn_NO.js5
-rw-r--r--lib/l10n/nn_NO.json5
-rw-r--r--lib/l10n/oc.js4
-rw-r--r--lib/l10n/oc.json4
-rw-r--r--lib/l10n/pl.js136
-rw-r--r--lib/l10n/pl.json136
-rw-r--r--lib/l10n/ps.js3
-rw-r--r--lib/l10n/ps.json3
-rw-r--r--lib/l10n/pt_BR.js77
-rw-r--r--lib/l10n/pt_BR.json77
-rw-r--r--lib/l10n/pt_PT.js18
-rw-r--r--lib/l10n/pt_PT.json18
-rw-r--r--lib/l10n/ro.js15
-rw-r--r--lib/l10n/ro.json15
-rw-r--r--lib/l10n/ru.js84
-rw-r--r--lib/l10n/ru.json84
-rw-r--r--lib/l10n/sc.js15
-rw-r--r--lib/l10n/sc.json15
-rw-r--r--lib/l10n/si.js4
-rw-r--r--lib/l10n/si.json4
-rw-r--r--lib/l10n/sk.js15
-rw-r--r--lib/l10n/sk.json15
-rw-r--r--lib/l10n/sl.js16
-rw-r--r--lib/l10n/sl.json16
-rw-r--r--lib/l10n/sq.js10
-rw-r--r--lib/l10n/sq.json10
-rw-r--r--lib/l10n/sr.js23
-rw-r--r--lib/l10n/sr.json23
-rw-r--r--lib/l10n/sv.js23
-rw-r--r--lib/l10n/sv.json23
-rw-r--r--lib/l10n/sw.js41
-rw-r--r--lib/l10n/sw.json39
-rw-r--r--lib/l10n/ta.js3
-rw-r--r--lib/l10n/ta.json3
-rw-r--r--lib/l10n/th.js5
-rw-r--r--lib/l10n/th.json5
-rw-r--r--lib/l10n/tr.js41
-rw-r--r--lib/l10n/tr.json41
-rw-r--r--lib/l10n/ug.js15
-rw-r--r--lib/l10n/ug.json15
-rw-r--r--lib/l10n/uk.js21
-rw-r--r--lib/l10n/uk.json21
-rw-r--r--lib/l10n/ur_PK.js3
-rw-r--r--lib/l10n/ur_PK.json3
-rw-r--r--lib/l10n/uz.js6
-rw-r--r--lib/l10n/uz.json6
-rw-r--r--lib/l10n/vi.js6
-rw-r--r--lib/l10n/vi.json6
-rw-r--r--lib/l10n/zh_CN.js23
-rw-r--r--lib/l10n/zh_CN.json23
-rw-r--r--lib/l10n/zh_HK.js23
-rw-r--r--lib/l10n/zh_HK.json23
-rw-r--r--lib/l10n/zh_TW.js23
-rw-r--r--lib/l10n/zh_TW.json23
-rw-r--r--lib/private/Accounts/AccountManager.php4
-rw-r--r--lib/private/Accounts/AccountProperty.php24
-rw-r--r--lib/private/App/AppManager.php38
-rw-r--r--lib/private/App/AppStore/AppNotFoundException.php13
-rw-r--r--lib/private/AppConfig.php97
-rw-r--r--lib/private/AppFramework/Bootstrap/Coordinator.php19
-rw-r--r--lib/private/AppFramework/Bootstrap/RegistrationContext.php2
-rw-r--r--lib/private/AppFramework/Middleware/NotModifiedMiddleware.php2
-rw-r--r--lib/private/AppFramework/Middleware/PublicShare/PublicShareMiddleware.php2
-rw-r--r--lib/private/AppFramework/Middleware/Security/Exceptions/NotConfirmedException.php4
-rw-r--r--lib/private/AppFramework/Middleware/Security/PasswordConfirmationMiddleware.php3
-rw-r--r--lib/private/AppFramework/Routing/RouteConfig.php279
-rw-r--r--lib/private/AppFramework/Routing/RouteParser.php4
-rw-r--r--lib/private/AppFramework/Services/AppConfig.php4
-rw-r--r--lib/private/AppFramework/Utility/SimpleContainer.php43
-rw-r--r--lib/private/Blurhash/Listener/GenerateBlurhashMetadata.php46
-rw-r--r--lib/private/Calendar/Manager.php137
-rw-r--r--lib/private/Collaboration/Reference/File/FileReferenceEventListener.php5
-rw-r--r--lib/private/Config/ConfigManager.php250
-rw-r--r--lib/private/Config/UserConfig.php91
-rw-r--r--lib/private/DB/QueryBuilder/Partitioned/PartitionedQueryBuilder.php15
-rw-r--r--lib/private/Encryption/EncryptionEventListener.php100
-rw-r--r--lib/private/Encryption/EncryptionWrapper.php10
-rw-r--r--lib/private/Encryption/HookManager.php75
-rw-r--r--lib/private/Encryption/Update.php130
-rw-r--r--lib/private/Encryption/Util.php2
-rw-r--r--lib/private/Files/Cache/Cache.php2
-rw-r--r--lib/private/Files/Cache/Scanner.php10
-rw-r--r--lib/private/Files/Cache/Storage.php1
-rw-r--r--lib/private/Files/Cache/Wrapper/CacheJail.php13
-rw-r--r--lib/private/Files/Config/MountProviderCollection.php116
-rw-r--r--lib/private/Files/Config/UserMountCache.php31
-rw-r--r--lib/private/Files/FilenameValidator.php37
-rw-r--r--lib/private/Files/Mount/ObjectHomeMountProvider.php110
-rw-r--r--lib/private/Files/Mount/RootMountProvider.php62
-rw-r--r--lib/private/Files/Node/Folder.php25
-rw-r--r--lib/private/Files/Node/LazyFolder.php4
-rw-r--r--lib/private/Files/ObjectStore/ObjectStoreStorage.php34
-rw-r--r--lib/private/Files/ObjectStore/PrimaryObjectStoreConfig.php140
-rw-r--r--lib/private/Files/ObjectStore/S3.php12
-rw-r--r--lib/private/Files/ObjectStore/S3ConfigTrait.php4
-rw-r--r--lib/private/Files/ObjectStore/S3ConnectionTrait.php4
-rw-r--r--lib/private/Files/ObjectStore/S3ObjectTrait.php103
-rw-r--r--lib/private/Files/Search/QueryOptimizer/OrEqualsToIn.php2
-rw-r--r--lib/private/Files/Search/QueryOptimizer/SplitLargeIn.php2
-rw-r--r--lib/private/Files/SetupManager.php12
-rw-r--r--lib/private/Files/SimpleFS/SimpleFile.php10
-rw-r--r--lib/private/Files/Storage/Common.php5
-rw-r--r--lib/private/Files/Storage/DAV.php10
-rw-r--r--lib/private/Files/Storage/LocalTempFileTrait.php4
-rw-r--r--lib/private/Files/Storage/Temporary.php8
-rw-r--r--lib/private/Files/Storage/Wrapper/Encryption.php57
-rw-r--r--lib/private/Files/Storage/Wrapper/Jail.php3
-rw-r--r--lib/private/Files/Storage/Wrapper/Quota.php8
-rw-r--r--lib/private/Files/Storage/Wrapper/Wrapper.php3
-rw-r--r--lib/private/Files/Template/TemplateManager.php65
-rw-r--r--lib/private/Files/Type/Detection.php29
-rw-r--r--lib/private/Files/Utils/Scanner.php11
-rw-r--r--lib/private/Files/View.php21
-rw-r--r--lib/private/Group/Group.php2
-rw-r--r--lib/private/Http/Client/Response.php33
-rw-r--r--lib/private/Installer.php61
-rw-r--r--lib/private/IntegrityCheck/Checker.php4
-rw-r--r--lib/private/Lockdown/Filesystem/NullCache.php31
-rw-r--r--lib/private/Log/ErrorHandler.php4
-rw-r--r--lib/private/Log/LogDetails.php4
-rw-r--r--lib/private/Log/Rotate.php10
-rw-r--r--lib/private/NavigationManager.php19
-rw-r--r--lib/private/Notification/Manager.php4
-rw-r--r--lib/private/OCM/Model/OCMProvider.php94
-rw-r--r--lib/private/OCM/OCMDiscoveryService.php8
-rw-r--r--lib/private/Preview/Generator.php65
-rw-r--r--lib/private/Preview/Movie.php2
-rw-r--r--lib/private/PreviewManager.php45
-rw-r--r--lib/private/Remote/Instance.php8
-rw-r--r--lib/private/Repair.php3
-rw-r--r--lib/private/Repair/ConfigKeyMigration.php29
-rw-r--r--lib/private/Repair/MoveUpdaterStepFile.php3
-rw-r--r--lib/private/Repair/NC16/CleanupCardDAVPhotoCache.php24
-rw-r--r--lib/private/Route/CachingRouter.php100
-rw-r--r--lib/private/Route/Route.php10
-rw-r--r--lib/private/Route/Router.php72
-rw-r--r--lib/private/Security/Bruteforce/Throttler.php43
-rw-r--r--lib/private/Security/Normalizer/IpAddress.php9
-rw-r--r--lib/private/Security/RateLimiting/Limiter.php7
-rw-r--r--lib/private/Server.php497
-rw-r--r--lib/private/ServerContainer.php23
-rw-r--r--lib/private/Session/CryptoWrapper.php2
-rw-r--r--lib/private/Settings/DeclarativeManager.php71
-rw-r--r--lib/private/Setup.php83
-rw-r--r--lib/private/Setup/AbstractDatabase.php5
-rw-r--r--lib/private/Setup/MySQL.php4
-rw-r--r--lib/private/Setup/OCI.php2
-rw-r--r--lib/private/Setup/PostgreSQL.php5
-rw-r--r--lib/private/Setup/Sqlite.php2
-rw-r--r--lib/private/Share20/DefaultShareProvider.php42
-rw-r--r--lib/private/Share20/Manager.php13
-rw-r--r--lib/private/Share20/ProviderFactory.php206
-rw-r--r--lib/private/Support/CrashReport/Registry.php1
-rw-r--r--lib/private/TaskProcessing/Manager.php1
-rw-r--r--lib/private/TaskProcessing/RemoveOldTasksBackgroundJob.php2
-rw-r--r--lib/private/TempManager.php3
-rw-r--r--lib/private/Template/JSResourceLocator.php2
-rw-r--r--lib/private/TemplateLayout.php2
-rw-r--r--lib/private/URLGenerator.php11
-rw-r--r--lib/private/Updater/VersionCheck.php17
-rw-r--r--lib/private/User/LazyUser.php4
-rw-r--r--lib/private/User/Manager.php3
-rw-r--r--lib/private/User/Session.php20
-rw-r--r--lib/private/User/User.php18
-rw-r--r--lib/private/legacy/OC_App.php67
-rw-r--r--lib/private/legacy/OC_Helper.php249
-rw-r--r--lib/private/legacy/OC_Response.php1
-rw-r--r--lib/private/legacy/OC_Util.php8
-rw-r--r--lib/public/Accounts/IAccountManager.php28
-rw-r--r--lib/public/App/Events/AppUpdateEvent.php8
-rw-r--r--lib/public/App/IAppManager.php4
-rw-r--r--lib/public/AppFramework/ApiController.php5
-rw-r--r--lib/public/AppFramework/App.php46
-rw-r--r--lib/public/AppFramework/Http/Attribute/RequestHeader.php34
-rw-r--r--lib/public/AppFramework/Http/RedirectToDefaultAppResponse.php3
-rw-r--r--lib/public/AppFramework/Http/Response.php11
-rw-r--r--lib/public/AppFramework/Http/Template/PublicTemplateResponse.php1
-rw-r--r--lib/public/Calendar/CalendarExportOptions.php68
-rw-r--r--lib/public/Calendar/ICalendar.php72
-rw-r--r--lib/public/Calendar/ICalendarExport.php31
-rw-r--r--lib/public/Calendar/ICalendarIsEnabled.php24
-rw-r--r--lib/public/Color.php2
-rw-r--r--lib/public/Constants.php8
-rw-r--r--lib/public/Defaults.php2
-rw-r--r--lib/public/Diagnostics/IQueryLogger.php2
-rw-r--r--lib/public/Encryption/Exceptions/InvalidHeaderException.php17
-rw-r--r--lib/public/EventDispatcher/GenericEvent.php4
-rw-r--r--lib/public/Files.php90
-rw-r--r--lib/public/Files/Config/Event/UserMountAddedEvent.php27
-rw-r--r--lib/public/Files/Config/Event/UserMountRemovedEvent.php27
-rw-r--r--lib/public/Files/Config/Event/UserMountUpdatedEvent.php28
-rw-r--r--lib/public/Files/Folder.php11
-rw-r--r--lib/public/Files/IFilenameValidator.php13
-rw-r--r--lib/public/Files/IMimeTypeDetector.php8
-rw-r--r--lib/public/Files/ObjectStore/IObjectStoreMetaData.php11
-rw-r--r--lib/public/Files/SimpleFS/ISimpleFile.php10
-rw-r--r--lib/public/Files/Template/BeforeGetTemplatesEvent.php14
-rw-r--r--lib/public/Files/Template/ITemplateManager.php9
-rw-r--r--lib/public/Files_FullTextSearch/Model/AFilesDocument.php2
-rw-r--r--lib/public/Http/Client/IResponse.php3
-rw-r--r--lib/public/IAppConfig.php2
-rw-r--r--lib/public/IPreview.php8
-rw-r--r--lib/public/IServerContainer.php270
-rw-r--r--lib/public/IUser.php9
-rw-r--r--lib/public/L10N/ILanguageIterator.php10
-rw-r--r--lib/public/Lock/LockedException.php12
-rw-r--r--lib/public/Mail/IMailer.php2
-rw-r--r--lib/public/OCM/ICapabilityAwareOCMProvider.php60
-rw-r--r--lib/public/OCM/IOCMProvider.php1
-rw-r--r--lib/public/Profiler/IProfile.php2
-rw-r--r--lib/public/Route/IRoute.php4
-rw-r--r--lib/public/Security/IContentSecurityPolicyManager.php2
-rw-r--r--lib/public/Security/ICrypto.php4
-rw-r--r--lib/public/Security/IHasher.php4
-rw-r--r--lib/public/Security/ISecureRandom.php2
-rw-r--r--lib/public/Settings/IDeclarativeSettingsForm.php1
-rw-r--r--lib/public/Share/IProviderFactory.php5
-rw-r--r--lib/public/Share/IShareProviderSupportsAllSharesInFolder.php24
-rw-r--r--lib/public/TaskProcessing/TaskTypes/TextToSpeech.php92
-rw-r--r--lib/public/Template.php6
-rw-r--r--lib/public/Util.php125
-rw-r--r--lib/unstable/Config/Lexicon/ConfigLexiconEntry.php25
361 files changed, 5092 insertions, 4989 deletions
diff --git a/lib/autoloader.php b/lib/autoloader.php
deleted file mode 100644
index 41b272a457c..00000000000
--- a/lib/autoloader.php
+++ /dev/null
@@ -1,169 +0,0 @@
-<?php
-
-declare(strict_types=1);
-/**
- * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
- * SPDX-FileCopyrightText: 2013-2016 ownCloud, Inc.
- * SPDX-License-Identifier: AGPL-3.0-only
- */
-namespace OC;
-
-use OCP\App\AppPathNotFoundException;
-use OCP\App\IAppManager;
-use OCP\AutoloadNotAllowedException;
-use OCP\ICache;
-use Psr\Log\LoggerInterface;
-
-class Autoloader {
- /** @var bool */
- private $useGlobalClassPath = true;
- /** @var array */
- private $validRoots = [];
-
- /**
- * Optional low-latency memory cache for class to path mapping.
- *
- * @var \OC\Memcache\Cache
- */
- protected $memoryCache;
-
- /**
- * Autoloader constructor.
- *
- * @param string[] $validRoots
- */
- public function __construct(array $validRoots) {
- foreach ($validRoots as $root) {
- $this->validRoots[$root] = true;
- }
- }
-
- /**
- * Add a path to the list of valid php roots for auto loading
- *
- * @param string $root
- */
- public function addValidRoot(string $root): void {
- $root = stream_resolve_include_path($root);
- $this->validRoots[$root] = true;
- }
-
- /**
- * disable the usage of the global classpath \OC::$CLASSPATH
- */
- public function disableGlobalClassPath(): void {
- $this->useGlobalClassPath = false;
- }
-
- /**
- * enable the usage of the global classpath \OC::$CLASSPATH
- */
- public function enableGlobalClassPath(): void {
- $this->useGlobalClassPath = true;
- }
-
- /**
- * get the possible paths for a class
- *
- * @param string $class
- * @return array an array of possible paths
- */
- public function findClass(string $class): array {
- $class = trim($class, '\\');
-
- $paths = [];
- if ($this->useGlobalClassPath && array_key_exists($class, \OC::$CLASSPATH)) {
- $paths[] = \OC::$CLASSPATH[$class];
- /**
- * @TODO: Remove this when necessary
- * Remove "apps/" from inclusion path for smooth migration to multi app dir
- */
- if (strpos(\OC::$CLASSPATH[$class], 'apps/') === 0) {
- \OCP\Server::get(LoggerInterface::class)->debug('include path for class "' . $class . '" starts with "apps/"', ['app' => 'core']);
- $paths[] = str_replace('apps/', '', \OC::$CLASSPATH[$class]);
- }
- } elseif (strpos($class, 'OC_') === 0) {
- $paths[] = \OC::$SERVERROOT . '/lib/private/legacy/' . strtolower(str_replace('_', '/', substr($class, 3)) . '.php');
- } elseif (strpos($class, 'OCA\\') === 0) {
- [, $app, $rest] = explode('\\', $class, 3);
- $app = strtolower($app);
- try {
- $appPath = \OCP\Server::get(IAppManager::class)->getAppPath($app);
- if (stream_resolve_include_path($appPath)) {
- $paths[] = $appPath . '/' . strtolower(str_replace('\\', '/', $rest) . '.php');
- // If not found in the root of the app directory, insert '/lib' after app id and try again.
- $paths[] = $appPath . '/lib/' . strtolower(str_replace('\\', '/', $rest) . '.php');
- }
- } catch (AppPathNotFoundException) {
- // App not found, ignore
- }
- } elseif ($class === 'Test\\TestCase') {
- // This File is considered public API, so we make sure that the class
- // can still be loaded, although the PSR-4 paths have not been loaded.
- $paths[] = \OC::$SERVERROOT . '/tests/lib/TestCase.php';
- }
- return $paths;
- }
-
- /**
- * @param string $fullPath
- * @return bool
- * @throws AutoloadNotAllowedException
- */
- protected function isValidPath(string $fullPath): bool {
- foreach ($this->validRoots as $root => $true) {
- if (substr($fullPath, 0, strlen($root) + 1) === $root . '/') {
- return true;
- }
- }
- throw new AutoloadNotAllowedException($fullPath);
- }
-
- /**
- * Load the specified class
- *
- * @param string $class
- * @return bool
- * @throws AutoloadNotAllowedException
- */
- public function load(string $class): bool {
- $pathsToRequire = null;
- if ($this->memoryCache) {
- $pathsToRequire = $this->memoryCache->get($class);
- }
-
- if (class_exists($class, false)) {
- return false;
- }
-
- if (!is_array($pathsToRequire)) {
- // No cache or cache miss
- $pathsToRequire = [];
- foreach ($this->findClass($class) as $path) {
- $fullPath = stream_resolve_include_path($path);
- if ($fullPath && $this->isValidPath($fullPath)) {
- $pathsToRequire[] = $fullPath;
- }
- }
-
- if ($this->memoryCache) {
- $this->memoryCache->set($class, $pathsToRequire, 60); // cache 60 sec
- }
- }
-
- foreach ($pathsToRequire as $fullPath) {
- require_once $fullPath;
- }
-
- return false;
- }
-
- /**
- * Sets the optional low-latency cache for class to path mapping.
- *
- * @param ICache $memoryCache Instance of memory cache.
- */
- public function setMemoryCache(?ICache $memoryCache = null): void {
- $this->memoryCache = $memoryCache;
- }
-}
diff --git a/lib/base.php b/lib/base.php
index aa463e206a3..876d62c3596 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -6,13 +6,14 @@ declare(strict_types=1);
* SPDX-FileCopyrightText: 2013-2016 ownCloud, Inc.
* SPDX-License-Identifier: AGPL-3.0-only
*/
-use OC\Encryption\HookManager;
+
use OC\Profiler\BuiltInProfiler;
use OC\Share20\GroupDeletedListener;
use OC\Share20\Hooks;
use OC\Share20\UserDeletedListener;
use OC\Share20\UserRemovedListener;
use OCP\EventDispatcher\IEventDispatcher;
+use OCP\Files\Events\BeforeFileSystemSetupEvent;
use OCP\Group\Events\GroupDeletedEvent;
use OCP\Group\Events\UserRemovedEvent;
use OCP\IConfig;
@@ -22,7 +23,6 @@ use OCP\IURLGenerator;
use OCP\IUserSession;
use OCP\Security\Bruteforce\IThrottler;
use OCP\Server;
-use OCP\Share;
use OCP\Template\ITemplateManager;
use OCP\User\Events\UserChangedEvent;
use OCP\User\Events\UserDeletedEvent;
@@ -40,10 +40,6 @@ require_once 'public/Constants.php';
*/
class OC {
/**
- * Associative array for autoloading. classname => filename
- */
- public static array $CLASSPATH = [];
- /**
* The installation path for Nextcloud on the server (e.g. /srv/http/nextcloud)
*/
public static string $SERVERROOT = '';
@@ -73,8 +69,6 @@ class OC {
*/
public static bool $CLI = false;
- public static \OC\Autoloader $loader;
-
public static \Composer\Autoload\ClassLoader $composerAutoloader;
public static \OC\Server $server;
@@ -188,8 +182,6 @@ class OC {
}
public static function checkConfig(): void {
- $l = Server::get(\OCP\L10N\IFactory::class)->get('lib');
-
// Create config if it does not already exist
$configFilePath = self::$configDir . '/config.php';
if (!file_exists($configFilePath)) {
@@ -198,9 +190,11 @@ class OC {
// Check if config is writable
$configFileWritable = is_writable($configFilePath);
- if (!$configFileWritable && !OC_Helper::isReadOnlyConfigEnabled()
+ $configReadOnly = Server::get(IConfig::class)->getSystemValueBool('config_is_read_only');
+ if (!$configFileWritable && !$configReadOnly
|| !$configFileWritable && \OCP\Util::needUpgrade()) {
$urlGenerator = Server::get(IURLGenerator::class);
+ $l = Server::get(\OCP\L10N\IFactory::class)->get('lib');
if (self::$CLI) {
echo $l->t('Cannot write into "config" directory!') . "\n";
@@ -399,6 +393,12 @@ class OC {
$cookie_path = OC::$WEBROOT ? : '/';
ini_set('session.cookie_path', $cookie_path);
+ // set the cookie domain to the Nextcloud domain
+ $cookie_domain = self::$config->getValue('cookie_domain', '');
+ if ($cookie_domain) {
+ ini_set('session.cookie_domain', $cookie_domain);
+ }
+
// Let the session name be changed in the initSession Hook
$sessionName = OC_Util::getInstanceId();
@@ -551,10 +551,10 @@ class OC {
$processingScript = explode('/', $requestUri);
$processingScript = $processingScript[count($processingScript) - 1];
- // index.php routes are handled in the middleware
- // and cron.php does not need any authentication at all
- if ($processingScript === 'index.php'
- || $processingScript === 'cron.php') {
+ if ($processingScript === 'index.php' // index.php routes are handled in the middleware
+ || $processingScript === 'cron.php' // and cron.php does not need any authentication at all
+ || $processingScript === 'public.php' // For public.php, auth for password protected shares is done in the PublicAuth plugin
+ ) {
return;
}
@@ -597,15 +597,6 @@ class OC {
// register autoloader
$loaderStart = microtime(true);
- require_once __DIR__ . '/autoloader.php';
- self::$loader = new \OC\Autoloader([
- OC::$SERVERROOT . '/lib/private/legacy',
- ]);
- if (defined('PHPUNIT_RUN')) {
- self::$loader->addValidRoot(OC::$SERVERROOT . '/tests');
- }
- spl_autoload_register([self::$loader, 'load']);
- $loaderEnd = microtime(true);
self::$CLI = (php_sapi_name() == 'cli');
@@ -631,6 +622,10 @@ class OC {
print($e->getMessage());
exit();
}
+ $loaderEnd = microtime(true);
+
+ // Enable lazy loading if activated
+ \OC\AppFramework\Utility\SimpleContainer::$useLazyObjects = (bool)self::$config->getValue('enable_lazy_objects', true);
// setup the basic server
self::$server = new \OC\Server(\OC::$WEBROOT, self::$config);
@@ -659,9 +654,6 @@ class OC {
error_reporting(E_ALL);
}
- $systemConfig = Server::get(\OC\SystemConfig::class);
- self::registerAutoloaderCache($systemConfig);
-
// initialize intl fallback if necessary
OC_Util::isSetLocaleWorking();
@@ -695,6 +687,7 @@ class OC {
throw new \OCP\HintException('The PHP SimpleXML/PHP-XML extension is not installed.', 'Install the extension or make sure it is enabled.');
}
+ $systemConfig = Server::get(\OC\SystemConfig::class);
$appManager = Server::get(\OCP\App\IAppManager::class);
if ($systemConfig->getValue('installed', false)) {
$appManager->loadApps(['session']);
@@ -711,6 +704,7 @@ class OC {
self::performSameSiteCookieProtection($config);
if (!defined('OC_CONSOLE')) {
+ $eventLogger->start('check_server', 'Run a few configuration checks');
$errors = OC_Util::checkServer($systemConfig);
if (count($errors) > 0) {
if (!self::$CLI) {
@@ -745,6 +739,7 @@ class OC {
} elseif (self::$CLI && $config->getSystemValueBool('installed', false)) {
$config->deleteAppValue('core', 'cronErrors');
}
+ $eventLogger->end('check_server');
}
// User and Groups
@@ -752,6 +747,7 @@ class OC {
self::$server->getSession()->set('user_id', '');
}
+ $eventLogger->start('setup_backends', 'Setup group and user backends');
Server::get(\OCP\IUserManager::class)->registerBackend(new \OC\User\Database());
Server::get(\OCP\IGroupManager::class)->addBackend(new \OC\Group\Database());
@@ -770,6 +766,7 @@ class OC {
// Run upgrades in incognito mode
OC_User::setIncognitoMode(true);
}
+ $eventLogger->end('setup_backends');
self::registerCleanupHooks($systemConfig);
self::registerShareHooks($systemConfig);
@@ -783,8 +780,8 @@ class OC {
// Make sure that the application class is not loaded before the database is setup
if ($systemConfig->getValue('installed', false)) {
$appManager->loadApp('settings');
- /* Build core application to make sure that listeners are registered */
- Server::get(\OC\Core\Application::class);
+ /* Run core application registration */
+ $bootstrapCoordinator->runLazyRegistration('core');
}
//make sure temporary files are cleaned up
@@ -907,15 +904,16 @@ class OC {
}
private static function registerEncryptionWrapperAndHooks(): void {
+ /** @var \OC\Encryption\Manager */
$manager = Server::get(\OCP\Encryption\IManager::class);
- \OCP\Util::connectHook('OC_Filesystem', 'preSetup', $manager, 'setupStorage');
+ Server::get(IEventDispatcher::class)->addListener(
+ BeforeFileSystemSetupEvent::class,
+ $manager->setupStorage(...),
+ );
$enabled = $manager->isEnabled();
if ($enabled) {
- \OCP\Util::connectHook(Share::class, 'post_shared', HookManager::class, 'postShared');
- \OCP\Util::connectHook(Share::class, 'post_unshare', HookManager::class, 'postUnshared');
- \OCP\Util::connectHook('OC_Filesystem', 'post_rename', HookManager::class, 'postRename');
- \OCP\Util::connectHook('\OCA\Files_Trashbin\Trashbin', 'post_restore', HookManager::class, 'postRestore');
+ \OC\Encryption\EncryptionEventListener::register(Server::get(IEventDispatcher::class));
}
}
@@ -973,23 +971,6 @@ class OC {
}
}
- protected static function registerAutoloaderCache(\OC\SystemConfig $systemConfig): void {
- // The class loader takes an optional low-latency cache, which MUST be
- // namespaced. The instanceid is used for namespacing, but might be
- // unavailable at this point. Furthermore, it might not be possible to
- // generate an instanceid via \OC_Util::getInstanceId() because the
- // config file may not be writable. As such, we only register a class
- // loader cache if instanceid is available without trying to create one.
- $instanceId = $systemConfig->getValue('instanceid', null);
- if ($instanceId) {
- try {
- $memcacheFactory = Server::get(\OCP\ICacheFactory::class);
- self::$loader->setMemoryCache($memcacheFactory->createLocal('Autoloader'));
- } catch (\Exception $ex) {
- }
- }
- }
-
/**
* Handle the request
*/
diff --git a/lib/composer/autoload.php b/lib/composer/autoload.php
index b3b39129e7a..7b1481e876c 100644
--- a/lib/composer/autoload.php
+++ b/lib/composer/autoload.php
@@ -14,10 +14,7 @@ if (PHP_VERSION_ID < 50600) {
echo $err;
}
}
- trigger_error(
- $err,
- E_USER_ERROR
- );
+ throw new RuntimeException($err);
}
require_once __DIR__ . '/composer/autoload_real.php';
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index 3d36f50e950..5300af5242c 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -85,6 +85,7 @@ return array(
'OCP\\AppFramework\\Http\\Attribute\\OpenAPI' => $baseDir . '/lib/public/AppFramework/Http/Attribute/OpenAPI.php',
'OCP\\AppFramework\\Http\\Attribute\\PasswordConfirmationRequired' => $baseDir . '/lib/public/AppFramework/Http/Attribute/PasswordConfirmationRequired.php',
'OCP\\AppFramework\\Http\\Attribute\\PublicPage' => $baseDir . '/lib/public/AppFramework/Http/Attribute/PublicPage.php',
+ 'OCP\\AppFramework\\Http\\Attribute\\RequestHeader' => $baseDir . '/lib/public/AppFramework/Http/Attribute/RequestHeader.php',
'OCP\\AppFramework\\Http\\Attribute\\Route' => $baseDir . '/lib/public/AppFramework/Http/Attribute/Route.php',
'OCP\\AppFramework\\Http\\Attribute\\StrictCookiesRequired' => $baseDir . '/lib/public/AppFramework/Http/Attribute/StrictCookiesRequired.php',
'OCP\\AppFramework\\Http\\Attribute\\SubAdminRequired' => $baseDir . '/lib/public/AppFramework/Http/Attribute/SubAdminRequired.php',
@@ -191,6 +192,7 @@ return array(
'OCP\\Cache\\CappedMemoryCache' => $baseDir . '/lib/public/Cache/CappedMemoryCache.php',
'OCP\\Calendar\\BackendTemporarilyUnavailableException' => $baseDir . '/lib/public/Calendar/BackendTemporarilyUnavailableException.php',
'OCP\\Calendar\\CalendarEventStatus' => $baseDir . '/lib/public/Calendar/CalendarEventStatus.php',
+ 'OCP\\Calendar\\CalendarExportOptions' => $baseDir . '/lib/public/Calendar/CalendarExportOptions.php',
'OCP\\Calendar\\Events\\AbstractCalendarObjectEvent' => $baseDir . '/lib/public/Calendar/Events/AbstractCalendarObjectEvent.php',
'OCP\\Calendar\\Events\\CalendarObjectCreatedEvent' => $baseDir . '/lib/public/Calendar/Events/CalendarObjectCreatedEvent.php',
'OCP\\Calendar\\Events\\CalendarObjectDeletedEvent' => $baseDir . '/lib/public/Calendar/Events/CalendarObjectDeletedEvent.php',
@@ -202,6 +204,8 @@ return array(
'OCP\\Calendar\\IAvailabilityResult' => $baseDir . '/lib/public/Calendar/IAvailabilityResult.php',
'OCP\\Calendar\\ICalendar' => $baseDir . '/lib/public/Calendar/ICalendar.php',
'OCP\\Calendar\\ICalendarEventBuilder' => $baseDir . '/lib/public/Calendar/ICalendarEventBuilder.php',
+ 'OCP\\Calendar\\ICalendarExport' => $baseDir . '/lib/public/Calendar/ICalendarExport.php',
+ 'OCP\\Calendar\\ICalendarIsEnabled' => $baseDir . '/lib/public/Calendar/ICalendarIsEnabled.php',
'OCP\\Calendar\\ICalendarIsShared' => $baseDir . '/lib/public/Calendar/ICalendarIsShared.php',
'OCP\\Calendar\\ICalendarIsWritable' => $baseDir . '/lib/public/Calendar/ICalendarIsWritable.php',
'OCP\\Calendar\\ICalendarProvider' => $baseDir . '/lib/public/Calendar/ICalendarProvider.php',
@@ -318,6 +322,7 @@ return array(
'OCP\\DirectEditing\\IToken' => $baseDir . '/lib/public/DirectEditing/IToken.php',
'OCP\\DirectEditing\\RegisterDirectEditorEvent' => $baseDir . '/lib/public/DirectEditing/RegisterDirectEditorEvent.php',
'OCP\\Encryption\\Exceptions\\GenericEncryptionException' => $baseDir . '/lib/public/Encryption/Exceptions/GenericEncryptionException.php',
+ 'OCP\\Encryption\\Exceptions\\InvalidHeaderException' => $baseDir . '/lib/public/Encryption/Exceptions/InvalidHeaderException.php',
'OCP\\Encryption\\IEncryptionModule' => $baseDir . '/lib/public/Encryption/IEncryptionModule.php',
'OCP\\Encryption\\IFile' => $baseDir . '/lib/public/Encryption/IFile.php',
'OCP\\Encryption\\IManager' => $baseDir . '/lib/public/Encryption/IManager.php',
@@ -377,6 +382,9 @@ return array(
'OCP\\Files\\Cache\\IScanner' => $baseDir . '/lib/public/Files/Cache/IScanner.php',
'OCP\\Files\\Cache\\IUpdater' => $baseDir . '/lib/public/Files/Cache/IUpdater.php',
'OCP\\Files\\Cache\\IWatcher' => $baseDir . '/lib/public/Files/Cache/IWatcher.php',
+ 'OCP\\Files\\Config\\Event\\UserMountAddedEvent' => $baseDir . '/lib/public/Files/Config/Event/UserMountAddedEvent.php',
+ 'OCP\\Files\\Config\\Event\\UserMountRemovedEvent' => $baseDir . '/lib/public/Files/Config/Event/UserMountRemovedEvent.php',
+ 'OCP\\Files\\Config\\Event\\UserMountUpdatedEvent' => $baseDir . '/lib/public/Files/Config/Event/UserMountUpdatedEvent.php',
'OCP\\Files\\Config\\ICachedMountFileInfo' => $baseDir . '/lib/public/Files/Config/ICachedMountFileInfo.php',
'OCP\\Files\\Config\\ICachedMountInfo' => $baseDir . '/lib/public/Files/Config/ICachedMountInfo.php',
'OCP\\Files\\Config\\IHomeMountProvider' => $baseDir . '/lib/public/Files/Config/IHomeMountProvider.php',
@@ -671,6 +679,7 @@ return array(
'OCP\\OCM\\Events\\ResourceTypeRegisterEvent' => $baseDir . '/lib/public/OCM/Events/ResourceTypeRegisterEvent.php',
'OCP\\OCM\\Exceptions\\OCMArgumentException' => $baseDir . '/lib/public/OCM/Exceptions/OCMArgumentException.php',
'OCP\\OCM\\Exceptions\\OCMProviderException' => $baseDir . '/lib/public/OCM/Exceptions/OCMProviderException.php',
+ 'OCP\\OCM\\ICapabilityAwareOCMProvider' => $baseDir . '/lib/public/OCM/ICapabilityAwareOCMProvider.php',
'OCP\\OCM\\IOCMDiscoveryService' => $baseDir . '/lib/public/OCM/IOCMDiscoveryService.php',
'OCP\\OCM\\IOCMProvider' => $baseDir . '/lib/public/OCM/IOCMProvider.php',
'OCP\\OCM\\IOCMResource' => $baseDir . '/lib/public/OCM/IOCMResource.php',
@@ -778,6 +787,7 @@ return array(
'OCP\\Share\\IShareHelper' => $baseDir . '/lib/public/Share/IShareHelper.php',
'OCP\\Share\\IShareProvider' => $baseDir . '/lib/public/Share/IShareProvider.php',
'OCP\\Share\\IShareProviderSupportsAccept' => $baseDir . '/lib/public/Share/IShareProviderSupportsAccept.php',
+ 'OCP\\Share\\IShareProviderSupportsAllSharesInFolder' => $baseDir . '/lib/public/Share/IShareProviderSupportsAllSharesInFolder.php',
'OCP\\Share\\IShareProviderWithNotification' => $baseDir . '/lib/public/Share/IShareProviderWithNotification.php',
'OCP\\Share_Backend' => $baseDir . '/lib/public/Share_Backend.php',
'OCP\\Share_Backend_Collection' => $baseDir . '/lib/public/Share_Backend_Collection.php',
@@ -837,6 +847,7 @@ return array(
'OCP\\TaskProcessing\\TaskTypes\\ContextWrite' => $baseDir . '/lib/public/TaskProcessing/TaskTypes/ContextWrite.php',
'OCP\\TaskProcessing\\TaskTypes\\GenerateEmoji' => $baseDir . '/lib/public/TaskProcessing/TaskTypes/GenerateEmoji.php',
'OCP\\TaskProcessing\\TaskTypes\\TextToImage' => $baseDir . '/lib/public/TaskProcessing/TaskTypes/TextToImage.php',
+ 'OCP\\TaskProcessing\\TaskTypes\\TextToSpeech' => $baseDir . '/lib/public/TaskProcessing/TaskTypes/TextToSpeech.php',
'OCP\\TaskProcessing\\TaskTypes\\TextToText' => $baseDir . '/lib/public/TaskProcessing/TaskTypes/TextToText.php',
'OCP\\TaskProcessing\\TaskTypes\\TextToTextChangeTone' => $baseDir . '/lib/public/TaskProcessing/TaskTypes/TextToTextChangeTone.php',
'OCP\\TaskProcessing\\TaskTypes\\TextToTextChat' => $baseDir . '/lib/public/TaskProcessing/TaskTypes/TextToTextChat.php',
@@ -1028,7 +1039,6 @@ return array(
'OC\\AppFramework\\OCS\\V1Response' => $baseDir . '/lib/private/AppFramework/OCS/V1Response.php',
'OC\\AppFramework\\OCS\\V2Response' => $baseDir . '/lib/private/AppFramework/OCS/V2Response.php',
'OC\\AppFramework\\Routing\\RouteActionHandler' => $baseDir . '/lib/private/AppFramework/Routing/RouteActionHandler.php',
- 'OC\\AppFramework\\Routing\\RouteConfig' => $baseDir . '/lib/private/AppFramework/Routing/RouteConfig.php',
'OC\\AppFramework\\Routing\\RouteParser' => $baseDir . '/lib/private/AppFramework/Routing/RouteParser.php',
'OC\\AppFramework\\ScopedPsrLogger' => $baseDir . '/lib/private/AppFramework/ScopedPsrLogger.php',
'OC\\AppFramework\\Services\\AppConfig' => $baseDir . '/lib/private/AppFramework/Services/AppConfig.php',
@@ -1040,6 +1050,7 @@ return array(
'OC\\AppScriptDependency' => $baseDir . '/lib/private/AppScriptDependency.php',
'OC\\AppScriptSort' => $baseDir . '/lib/private/AppScriptSort.php',
'OC\\App\\AppManager' => $baseDir . '/lib/private/App/AppManager.php',
+ 'OC\\App\\AppStore\\AppNotFoundException' => $baseDir . '/lib/private/App/AppStore/AppNotFoundException.php',
'OC\\App\\AppStore\\Bundles\\Bundle' => $baseDir . '/lib/private/App/AppStore/Bundles/Bundle.php',
'OC\\App\\AppStore\\Bundles\\BundleFetcher' => $baseDir . '/lib/private/App/AppStore/Bundles/BundleFetcher.php',
'OC\\App\\AppStore\\Bundles\\EducationBundle' => $baseDir . '/lib/private/App/AppStore/Bundles/EducationBundle.php',
@@ -1179,6 +1190,7 @@ return array(
'OC\\Comments\\Manager' => $baseDir . '/lib/private/Comments/Manager.php',
'OC\\Comments\\ManagerFactory' => $baseDir . '/lib/private/Comments/ManagerFactory.php',
'OC\\Config' => $baseDir . '/lib/private/Config.php',
+ 'OC\\Config\\ConfigManager' => $baseDir . '/lib/private/Config/ConfigManager.php',
'OC\\Config\\Lexicon\\CoreConfigLexicon' => $baseDir . '/lib/private/Config/Lexicon/CoreConfigLexicon.php',
'OC\\Config\\UserConfig' => $baseDir . '/lib/private/Config/UserConfig.php',
'OC\\Console\\Application' => $baseDir . '/lib/private/Console/Application.php',
@@ -1193,7 +1205,7 @@ return array(
'OC\\Contacts\\ContactsMenu\\Providers\\EMailProvider' => $baseDir . '/lib/private/Contacts/ContactsMenu/Providers/EMailProvider.php',
'OC\\Contacts\\ContactsMenu\\Providers\\LocalTimeProvider' => $baseDir . '/lib/private/Contacts/ContactsMenu/Providers/LocalTimeProvider.php',
'OC\\Contacts\\ContactsMenu\\Providers\\ProfileProvider' => $baseDir . '/lib/private/Contacts/ContactsMenu/Providers/ProfileProvider.php',
- 'OC\\Core\\Application' => $baseDir . '/core/Application.php',
+ 'OC\\Core\\AppInfo\\Application' => $baseDir . '/core/AppInfo/Application.php',
'OC\\Core\\BackgroundJobs\\BackgroundCleanupUpdaterBackupsJob' => $baseDir . '/core/BackgroundJobs/BackgroundCleanupUpdaterBackupsJob.php',
'OC\\Core\\BackgroundJobs\\CheckForUserCertificates' => $baseDir . '/core/BackgroundJobs/CheckForUserCertificates.php',
'OC\\Core\\BackgroundJobs\\CleanupLoginFlowV2' => $baseDir . '/core/BackgroundJobs/CleanupLoginFlowV2.php',
@@ -1222,6 +1234,7 @@ return array(
'OC\\Core\\Command\\Config\\Import' => $baseDir . '/core/Command/Config/Import.php',
'OC\\Core\\Command\\Config\\ListConfigs' => $baseDir . '/core/Command/Config/ListConfigs.php',
'OC\\Core\\Command\\Config\\System\\Base' => $baseDir . '/core/Command/Config/System/Base.php',
+ 'OC\\Core\\Command\\Config\\System\\CastHelper' => $baseDir . '/core/Command/Config/System/CastHelper.php',
'OC\\Core\\Command\\Config\\System\\DeleteConfig' => $baseDir . '/core/Command/Config/System/DeleteConfig.php',
'OC\\Core\\Command\\Config\\System\\GetConfig' => $baseDir . '/core/Command/Config/System/GetConfig.php',
'OC\\Core\\Command\\Config\\System\\SetConfig' => $baseDir . '/core/Command/Config/System/SetConfig.php',
@@ -1260,6 +1273,8 @@ return array(
'OC\\Core\\Command\\Info\\File' => $baseDir . '/core/Command/Info/File.php',
'OC\\Core\\Command\\Info\\FileUtils' => $baseDir . '/core/Command/Info/FileUtils.php',
'OC\\Core\\Command\\Info\\Space' => $baseDir . '/core/Command/Info/Space.php',
+ 'OC\\Core\\Command\\Info\\Storage' => $baseDir . '/core/Command/Info/Storage.php',
+ 'OC\\Core\\Command\\Info\\Storages' => $baseDir . '/core/Command/Info/Storages.php',
'OC\\Core\\Command\\Integrity\\CheckApp' => $baseDir . '/core/Command/Integrity/CheckApp.php',
'OC\\Core\\Command\\Integrity\\CheckCore' => $baseDir . '/core/Command/Integrity/CheckCore.php',
'OC\\Core\\Command\\Integrity\\SignApp' => $baseDir . '/core/Command/Integrity/SignApp.php',
@@ -1278,11 +1293,17 @@ return array(
'OC\\Core\\Command\\Maintenance\\RepairShareOwnership' => $baseDir . '/core/Command/Maintenance/RepairShareOwnership.php',
'OC\\Core\\Command\\Maintenance\\UpdateHtaccess' => $baseDir . '/core/Command/Maintenance/UpdateHtaccess.php',
'OC\\Core\\Command\\Maintenance\\UpdateTheme' => $baseDir . '/core/Command/Maintenance/UpdateTheme.php',
+ 'OC\\Core\\Command\\Memcache\\DistributedClear' => $baseDir . '/core/Command/Memcache/DistributedClear.php',
+ 'OC\\Core\\Command\\Memcache\\DistributedDelete' => $baseDir . '/core/Command/Memcache/DistributedDelete.php',
+ 'OC\\Core\\Command\\Memcache\\DistributedGet' => $baseDir . '/core/Command/Memcache/DistributedGet.php',
+ 'OC\\Core\\Command\\Memcache\\DistributedSet' => $baseDir . '/core/Command/Memcache/DistributedSet.php',
'OC\\Core\\Command\\Memcache\\RedisCommand' => $baseDir . '/core/Command/Memcache/RedisCommand.php',
'OC\\Core\\Command\\Preview\\Cleanup' => $baseDir . '/core/Command/Preview/Cleanup.php',
'OC\\Core\\Command\\Preview\\Generate' => $baseDir . '/core/Command/Preview/Generate.php',
'OC\\Core\\Command\\Preview\\Repair' => $baseDir . '/core/Command/Preview/Repair.php',
'OC\\Core\\Command\\Preview\\ResetRenderedTexts' => $baseDir . '/core/Command/Preview/ResetRenderedTexts.php',
+ 'OC\\Core\\Command\\Router\\ListRoutes' => $baseDir . '/core/Command/Router/ListRoutes.php',
+ 'OC\\Core\\Command\\Router\\MatchRoute' => $baseDir . '/core/Command/Router/MatchRoute.php',
'OC\\Core\\Command\\Security\\BruteforceAttempts' => $baseDir . '/core/Command/Security/BruteforceAttempts.php',
'OC\\Core\\Command\\Security\\BruteforceResetAttempts' => $baseDir . '/core/Command/Security/BruteforceResetAttempts.php',
'OC\\Core\\Command\\Security\\ExportCertificates' => $baseDir . '/core/Command/Security/ExportCertificates.php',
@@ -1318,6 +1339,7 @@ return array(
'OC\\Core\\Command\\User\\Keys\\Verify' => $baseDir . '/core/Command/User/Keys/Verify.php',
'OC\\Core\\Command\\User\\LastSeen' => $baseDir . '/core/Command/User/LastSeen.php',
'OC\\Core\\Command\\User\\ListCommand' => $baseDir . '/core/Command/User/ListCommand.php',
+ 'OC\\Core\\Command\\User\\Profile' => $baseDir . '/core/Command/User/Profile.php',
'OC\\Core\\Command\\User\\Report' => $baseDir . '/core/Command/User/Report.php',
'OC\\Core\\Command\\User\\ResetPassword' => $baseDir . '/core/Command/User/ResetPassword.php',
'OC\\Core\\Command\\User\\Setting' => $baseDir . '/core/Command/User/Setting.php',
@@ -1374,8 +1396,11 @@ return array(
'OC\\Core\\Exception\\LoginFlowV2ClientForbiddenException' => $baseDir . '/core/Exception/LoginFlowV2ClientForbiddenException.php',
'OC\\Core\\Exception\\LoginFlowV2NotFoundException' => $baseDir . '/core/Exception/LoginFlowV2NotFoundException.php',
'OC\\Core\\Exception\\ResetPasswordException' => $baseDir . '/core/Exception/ResetPasswordException.php',
+ 'OC\\Core\\Listener\\AddMissingIndicesListener' => $baseDir . '/core/Listener/AddMissingIndicesListener.php',
+ 'OC\\Core\\Listener\\AddMissingPrimaryKeyListener' => $baseDir . '/core/Listener/AddMissingPrimaryKeyListener.php',
'OC\\Core\\Listener\\BeforeMessageLoggedEventListener' => $baseDir . '/core/Listener/BeforeMessageLoggedEventListener.php',
'OC\\Core\\Listener\\BeforeTemplateRenderedListener' => $baseDir . '/core/Listener/BeforeTemplateRenderedListener.php',
+ 'OC\\Core\\Listener\\FeedBackHandler' => $baseDir . '/core/Listener/FeedBackHandler.php',
'OC\\Core\\Middleware\\TwoFactorMiddleware' => $baseDir . '/core/Middleware/TwoFactorMiddleware.php',
'OC\\Core\\Migrations\\Version13000Date20170705121758' => $baseDir . '/core/Migrations/Version13000Date20170705121758.php',
'OC\\Core\\Migrations\\Version13000Date20170718121200' => $baseDir . '/core/Migrations/Version13000Date20170718121200.php',
@@ -1455,6 +1480,7 @@ return array(
'OC\\Core\\Migrations\\Version31000Date20240101084401' => $baseDir . '/core/Migrations/Version31000Date20240101084401.php',
'OC\\Core\\Migrations\\Version31000Date20240814184402' => $baseDir . '/core/Migrations/Version31000Date20240814184402.php',
'OC\\Core\\Migrations\\Version31000Date20250213102442' => $baseDir . '/core/Migrations/Version31000Date20250213102442.php',
+ 'OC\\Core\\Migrations\\Version32000Date20250620081925' => $baseDir . '/core/Migrations/Version32000Date20250620081925.php',
'OC\\Core\\Notification\\CoreNotifier' => $baseDir . '/core/Notification/CoreNotifier.php',
'OC\\Core\\ResponseDefinitions' => $baseDir . '/core/ResponseDefinitions.php',
'OC\\Core\\Service\\LoginFlowV2Service' => $baseDir . '/core/Service/LoginFlowV2Service.php',
@@ -1533,6 +1559,7 @@ return array(
'OC\\DirectEditing\\Token' => $baseDir . '/lib/private/DirectEditing/Token.php',
'OC\\EmojiHelper' => $baseDir . '/lib/private/EmojiHelper.php',
'OC\\Encryption\\DecryptAll' => $baseDir . '/lib/private/Encryption/DecryptAll.php',
+ 'OC\\Encryption\\EncryptionEventListener' => $baseDir . '/lib/private/Encryption/EncryptionEventListener.php',
'OC\\Encryption\\EncryptionWrapper' => $baseDir . '/lib/private/Encryption/EncryptionWrapper.php',
'OC\\Encryption\\Exceptions\\DecryptionFailedException' => $baseDir . '/lib/private/Encryption/Exceptions/DecryptionFailedException.php',
'OC\\Encryption\\Exceptions\\EmptyEncryptionDataException' => $baseDir . '/lib/private/Encryption/Exceptions/EmptyEncryptionDataException.php',
@@ -1543,7 +1570,6 @@ return array(
'OC\\Encryption\\Exceptions\\ModuleDoesNotExistsException' => $baseDir . '/lib/private/Encryption/Exceptions/ModuleDoesNotExistsException.php',
'OC\\Encryption\\Exceptions\\UnknownCipherException' => $baseDir . '/lib/private/Encryption/Exceptions/UnknownCipherException.php',
'OC\\Encryption\\File' => $baseDir . '/lib/private/Encryption/File.php',
- 'OC\\Encryption\\HookManager' => $baseDir . '/lib/private/Encryption/HookManager.php',
'OC\\Encryption\\Keys\\Storage' => $baseDir . '/lib/private/Encryption/Keys/Storage.php',
'OC\\Encryption\\Manager' => $baseDir . '/lib/private/Encryption/Manager.php',
'OC\\Encryption\\Update' => $baseDir . '/lib/private/Encryption/Update.php',
@@ -1632,6 +1658,7 @@ return array(
'OC\\Files\\ObjectStore\\Mapper' => $baseDir . '/lib/private/Files/ObjectStore/Mapper.php',
'OC\\Files\\ObjectStore\\ObjectStoreScanner' => $baseDir . '/lib/private/Files/ObjectStore/ObjectStoreScanner.php',
'OC\\Files\\ObjectStore\\ObjectStoreStorage' => $baseDir . '/lib/private/Files/ObjectStore/ObjectStoreStorage.php',
+ 'OC\\Files\\ObjectStore\\PrimaryObjectStoreConfig' => $baseDir . '/lib/private/Files/ObjectStore/PrimaryObjectStoreConfig.php',
'OC\\Files\\ObjectStore\\S3' => $baseDir . '/lib/private/Files/ObjectStore/S3.php',
'OC\\Files\\ObjectStore\\S3ConfigTrait' => $baseDir . '/lib/private/Files/ObjectStore/S3ConfigTrait.php',
'OC\\Files\\ObjectStore\\S3ConnectionTrait' => $baseDir . '/lib/private/Files/ObjectStore/S3ConnectionTrait.php',
@@ -1882,6 +1909,7 @@ return array(
'OC\\Repair\\ClearGeneratedAvatarCache' => $baseDir . '/lib/private/Repair/ClearGeneratedAvatarCache.php',
'OC\\Repair\\ClearGeneratedAvatarCacheJob' => $baseDir . '/lib/private/Repair/ClearGeneratedAvatarCacheJob.php',
'OC\\Repair\\Collation' => $baseDir . '/lib/private/Repair/Collation.php',
+ 'OC\\Repair\\ConfigKeyMigration' => $baseDir . '/lib/private/Repair/ConfigKeyMigration.php',
'OC\\Repair\\Events\\RepairAdvanceEvent' => $baseDir . '/lib/private/Repair/Events/RepairAdvanceEvent.php',
'OC\\Repair\\Events\\RepairErrorEvent' => $baseDir . '/lib/private/Repair/Events/RepairErrorEvent.php',
'OC\\Repair\\Events\\RepairFinishEvent' => $baseDir . '/lib/private/Repair/Events/RepairFinishEvent.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index 7085d0b4a44..69231e62689 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -126,6 +126,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OCP\\AppFramework\\Http\\Attribute\\OpenAPI' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/OpenAPI.php',
'OCP\\AppFramework\\Http\\Attribute\\PasswordConfirmationRequired' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/PasswordConfirmationRequired.php',
'OCP\\AppFramework\\Http\\Attribute\\PublicPage' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/PublicPage.php',
+ 'OCP\\AppFramework\\Http\\Attribute\\RequestHeader' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/RequestHeader.php',
'OCP\\AppFramework\\Http\\Attribute\\Route' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/Route.php',
'OCP\\AppFramework\\Http\\Attribute\\StrictCookiesRequired' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/StrictCookiesRequired.php',
'OCP\\AppFramework\\Http\\Attribute\\SubAdminRequired' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/SubAdminRequired.php',
@@ -232,6 +233,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OCP\\Cache\\CappedMemoryCache' => __DIR__ . '/../../..' . '/lib/public/Cache/CappedMemoryCache.php',
'OCP\\Calendar\\BackendTemporarilyUnavailableException' => __DIR__ . '/../../..' . '/lib/public/Calendar/BackendTemporarilyUnavailableException.php',
'OCP\\Calendar\\CalendarEventStatus' => __DIR__ . '/../../..' . '/lib/public/Calendar/CalendarEventStatus.php',
+ 'OCP\\Calendar\\CalendarExportOptions' => __DIR__ . '/../../..' . '/lib/public/Calendar/CalendarExportOptions.php',
'OCP\\Calendar\\Events\\AbstractCalendarObjectEvent' => __DIR__ . '/../../..' . '/lib/public/Calendar/Events/AbstractCalendarObjectEvent.php',
'OCP\\Calendar\\Events\\CalendarObjectCreatedEvent' => __DIR__ . '/../../..' . '/lib/public/Calendar/Events/CalendarObjectCreatedEvent.php',
'OCP\\Calendar\\Events\\CalendarObjectDeletedEvent' => __DIR__ . '/../../..' . '/lib/public/Calendar/Events/CalendarObjectDeletedEvent.php',
@@ -243,6 +245,8 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OCP\\Calendar\\IAvailabilityResult' => __DIR__ . '/../../..' . '/lib/public/Calendar/IAvailabilityResult.php',
'OCP\\Calendar\\ICalendar' => __DIR__ . '/../../..' . '/lib/public/Calendar/ICalendar.php',
'OCP\\Calendar\\ICalendarEventBuilder' => __DIR__ . '/../../..' . '/lib/public/Calendar/ICalendarEventBuilder.php',
+ 'OCP\\Calendar\\ICalendarExport' => __DIR__ . '/../../..' . '/lib/public/Calendar/ICalendarExport.php',
+ 'OCP\\Calendar\\ICalendarIsEnabled' => __DIR__ . '/../../..' . '/lib/public/Calendar/ICalendarIsEnabled.php',
'OCP\\Calendar\\ICalendarIsShared' => __DIR__ . '/../../..' . '/lib/public/Calendar/ICalendarIsShared.php',
'OCP\\Calendar\\ICalendarIsWritable' => __DIR__ . '/../../..' . '/lib/public/Calendar/ICalendarIsWritable.php',
'OCP\\Calendar\\ICalendarProvider' => __DIR__ . '/../../..' . '/lib/public/Calendar/ICalendarProvider.php',
@@ -359,6 +363,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OCP\\DirectEditing\\IToken' => __DIR__ . '/../../..' . '/lib/public/DirectEditing/IToken.php',
'OCP\\DirectEditing\\RegisterDirectEditorEvent' => __DIR__ . '/../../..' . '/lib/public/DirectEditing/RegisterDirectEditorEvent.php',
'OCP\\Encryption\\Exceptions\\GenericEncryptionException' => __DIR__ . '/../../..' . '/lib/public/Encryption/Exceptions/GenericEncryptionException.php',
+ 'OCP\\Encryption\\Exceptions\\InvalidHeaderException' => __DIR__ . '/../../..' . '/lib/public/Encryption/Exceptions/InvalidHeaderException.php',
'OCP\\Encryption\\IEncryptionModule' => __DIR__ . '/../../..' . '/lib/public/Encryption/IEncryptionModule.php',
'OCP\\Encryption\\IFile' => __DIR__ . '/../../..' . '/lib/public/Encryption/IFile.php',
'OCP\\Encryption\\IManager' => __DIR__ . '/../../..' . '/lib/public/Encryption/IManager.php',
@@ -418,6 +423,9 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OCP\\Files\\Cache\\IScanner' => __DIR__ . '/../../..' . '/lib/public/Files/Cache/IScanner.php',
'OCP\\Files\\Cache\\IUpdater' => __DIR__ . '/../../..' . '/lib/public/Files/Cache/IUpdater.php',
'OCP\\Files\\Cache\\IWatcher' => __DIR__ . '/../../..' . '/lib/public/Files/Cache/IWatcher.php',
+ 'OCP\\Files\\Config\\Event\\UserMountAddedEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Config/Event/UserMountAddedEvent.php',
+ 'OCP\\Files\\Config\\Event\\UserMountRemovedEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Config/Event/UserMountRemovedEvent.php',
+ 'OCP\\Files\\Config\\Event\\UserMountUpdatedEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Config/Event/UserMountUpdatedEvent.php',
'OCP\\Files\\Config\\ICachedMountFileInfo' => __DIR__ . '/../../..' . '/lib/public/Files/Config/ICachedMountFileInfo.php',
'OCP\\Files\\Config\\ICachedMountInfo' => __DIR__ . '/../../..' . '/lib/public/Files/Config/ICachedMountInfo.php',
'OCP\\Files\\Config\\IHomeMountProvider' => __DIR__ . '/../../..' . '/lib/public/Files/Config/IHomeMountProvider.php',
@@ -712,6 +720,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OCP\\OCM\\Events\\ResourceTypeRegisterEvent' => __DIR__ . '/../../..' . '/lib/public/OCM/Events/ResourceTypeRegisterEvent.php',
'OCP\\OCM\\Exceptions\\OCMArgumentException' => __DIR__ . '/../../..' . '/lib/public/OCM/Exceptions/OCMArgumentException.php',
'OCP\\OCM\\Exceptions\\OCMProviderException' => __DIR__ . '/../../..' . '/lib/public/OCM/Exceptions/OCMProviderException.php',
+ 'OCP\\OCM\\ICapabilityAwareOCMProvider' => __DIR__ . '/../../..' . '/lib/public/OCM/ICapabilityAwareOCMProvider.php',
'OCP\\OCM\\IOCMDiscoveryService' => __DIR__ . '/../../..' . '/lib/public/OCM/IOCMDiscoveryService.php',
'OCP\\OCM\\IOCMProvider' => __DIR__ . '/../../..' . '/lib/public/OCM/IOCMProvider.php',
'OCP\\OCM\\IOCMResource' => __DIR__ . '/../../..' . '/lib/public/OCM/IOCMResource.php',
@@ -819,6 +828,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OCP\\Share\\IShareHelper' => __DIR__ . '/../../..' . '/lib/public/Share/IShareHelper.php',
'OCP\\Share\\IShareProvider' => __DIR__ . '/../../..' . '/lib/public/Share/IShareProvider.php',
'OCP\\Share\\IShareProviderSupportsAccept' => __DIR__ . '/../../..' . '/lib/public/Share/IShareProviderSupportsAccept.php',
+ 'OCP\\Share\\IShareProviderSupportsAllSharesInFolder' => __DIR__ . '/../../..' . '/lib/public/Share/IShareProviderSupportsAllSharesInFolder.php',
'OCP\\Share\\IShareProviderWithNotification' => __DIR__ . '/../../..' . '/lib/public/Share/IShareProviderWithNotification.php',
'OCP\\Share_Backend' => __DIR__ . '/../../..' . '/lib/public/Share_Backend.php',
'OCP\\Share_Backend_Collection' => __DIR__ . '/../../..' . '/lib/public/Share_Backend_Collection.php',
@@ -878,6 +888,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OCP\\TaskProcessing\\TaskTypes\\ContextWrite' => __DIR__ . '/../../..' . '/lib/public/TaskProcessing/TaskTypes/ContextWrite.php',
'OCP\\TaskProcessing\\TaskTypes\\GenerateEmoji' => __DIR__ . '/../../..' . '/lib/public/TaskProcessing/TaskTypes/GenerateEmoji.php',
'OCP\\TaskProcessing\\TaskTypes\\TextToImage' => __DIR__ . '/../../..' . '/lib/public/TaskProcessing/TaskTypes/TextToImage.php',
+ 'OCP\\TaskProcessing\\TaskTypes\\TextToSpeech' => __DIR__ . '/../../..' . '/lib/public/TaskProcessing/TaskTypes/TextToSpeech.php',
'OCP\\TaskProcessing\\TaskTypes\\TextToText' => __DIR__ . '/../../..' . '/lib/public/TaskProcessing/TaskTypes/TextToText.php',
'OCP\\TaskProcessing\\TaskTypes\\TextToTextChangeTone' => __DIR__ . '/../../..' . '/lib/public/TaskProcessing/TaskTypes/TextToTextChangeTone.php',
'OCP\\TaskProcessing\\TaskTypes\\TextToTextChat' => __DIR__ . '/../../..' . '/lib/public/TaskProcessing/TaskTypes/TextToTextChat.php',
@@ -1069,7 +1080,6 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\AppFramework\\OCS\\V1Response' => __DIR__ . '/../../..' . '/lib/private/AppFramework/OCS/V1Response.php',
'OC\\AppFramework\\OCS\\V2Response' => __DIR__ . '/../../..' . '/lib/private/AppFramework/OCS/V2Response.php',
'OC\\AppFramework\\Routing\\RouteActionHandler' => __DIR__ . '/../../..' . '/lib/private/AppFramework/Routing/RouteActionHandler.php',
- 'OC\\AppFramework\\Routing\\RouteConfig' => __DIR__ . '/../../..' . '/lib/private/AppFramework/Routing/RouteConfig.php',
'OC\\AppFramework\\Routing\\RouteParser' => __DIR__ . '/../../..' . '/lib/private/AppFramework/Routing/RouteParser.php',
'OC\\AppFramework\\ScopedPsrLogger' => __DIR__ . '/../../..' . '/lib/private/AppFramework/ScopedPsrLogger.php',
'OC\\AppFramework\\Services\\AppConfig' => __DIR__ . '/../../..' . '/lib/private/AppFramework/Services/AppConfig.php',
@@ -1081,6 +1091,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\AppScriptDependency' => __DIR__ . '/../../..' . '/lib/private/AppScriptDependency.php',
'OC\\AppScriptSort' => __DIR__ . '/../../..' . '/lib/private/AppScriptSort.php',
'OC\\App\\AppManager' => __DIR__ . '/../../..' . '/lib/private/App/AppManager.php',
+ 'OC\\App\\AppStore\\AppNotFoundException' => __DIR__ . '/../../..' . '/lib/private/App/AppStore/AppNotFoundException.php',
'OC\\App\\AppStore\\Bundles\\Bundle' => __DIR__ . '/../../..' . '/lib/private/App/AppStore/Bundles/Bundle.php',
'OC\\App\\AppStore\\Bundles\\BundleFetcher' => __DIR__ . '/../../..' . '/lib/private/App/AppStore/Bundles/BundleFetcher.php',
'OC\\App\\AppStore\\Bundles\\EducationBundle' => __DIR__ . '/../../..' . '/lib/private/App/AppStore/Bundles/EducationBundle.php',
@@ -1220,6 +1231,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\Comments\\Manager' => __DIR__ . '/../../..' . '/lib/private/Comments/Manager.php',
'OC\\Comments\\ManagerFactory' => __DIR__ . '/../../..' . '/lib/private/Comments/ManagerFactory.php',
'OC\\Config' => __DIR__ . '/../../..' . '/lib/private/Config.php',
+ 'OC\\Config\\ConfigManager' => __DIR__ . '/../../..' . '/lib/private/Config/ConfigManager.php',
'OC\\Config\\Lexicon\\CoreConfigLexicon' => __DIR__ . '/../../..' . '/lib/private/Config/Lexicon/CoreConfigLexicon.php',
'OC\\Config\\UserConfig' => __DIR__ . '/../../..' . '/lib/private/Config/UserConfig.php',
'OC\\Console\\Application' => __DIR__ . '/../../..' . '/lib/private/Console/Application.php',
@@ -1234,7 +1246,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\Contacts\\ContactsMenu\\Providers\\EMailProvider' => __DIR__ . '/../../..' . '/lib/private/Contacts/ContactsMenu/Providers/EMailProvider.php',
'OC\\Contacts\\ContactsMenu\\Providers\\LocalTimeProvider' => __DIR__ . '/../../..' . '/lib/private/Contacts/ContactsMenu/Providers/LocalTimeProvider.php',
'OC\\Contacts\\ContactsMenu\\Providers\\ProfileProvider' => __DIR__ . '/../../..' . '/lib/private/Contacts/ContactsMenu/Providers/ProfileProvider.php',
- 'OC\\Core\\Application' => __DIR__ . '/../../..' . '/core/Application.php',
+ 'OC\\Core\\AppInfo\\Application' => __DIR__ . '/../../..' . '/core/AppInfo/Application.php',
'OC\\Core\\BackgroundJobs\\BackgroundCleanupUpdaterBackupsJob' => __DIR__ . '/../../..' . '/core/BackgroundJobs/BackgroundCleanupUpdaterBackupsJob.php',
'OC\\Core\\BackgroundJobs\\CheckForUserCertificates' => __DIR__ . '/../../..' . '/core/BackgroundJobs/CheckForUserCertificates.php',
'OC\\Core\\BackgroundJobs\\CleanupLoginFlowV2' => __DIR__ . '/../../..' . '/core/BackgroundJobs/CleanupLoginFlowV2.php',
@@ -1263,6 +1275,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\Core\\Command\\Config\\Import' => __DIR__ . '/../../..' . '/core/Command/Config/Import.php',
'OC\\Core\\Command\\Config\\ListConfigs' => __DIR__ . '/../../..' . '/core/Command/Config/ListConfigs.php',
'OC\\Core\\Command\\Config\\System\\Base' => __DIR__ . '/../../..' . '/core/Command/Config/System/Base.php',
+ 'OC\\Core\\Command\\Config\\System\\CastHelper' => __DIR__ . '/../../..' . '/core/Command/Config/System/CastHelper.php',
'OC\\Core\\Command\\Config\\System\\DeleteConfig' => __DIR__ . '/../../..' . '/core/Command/Config/System/DeleteConfig.php',
'OC\\Core\\Command\\Config\\System\\GetConfig' => __DIR__ . '/../../..' . '/core/Command/Config/System/GetConfig.php',
'OC\\Core\\Command\\Config\\System\\SetConfig' => __DIR__ . '/../../..' . '/core/Command/Config/System/SetConfig.php',
@@ -1301,6 +1314,8 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\Core\\Command\\Info\\File' => __DIR__ . '/../../..' . '/core/Command/Info/File.php',
'OC\\Core\\Command\\Info\\FileUtils' => __DIR__ . '/../../..' . '/core/Command/Info/FileUtils.php',
'OC\\Core\\Command\\Info\\Space' => __DIR__ . '/../../..' . '/core/Command/Info/Space.php',
+ 'OC\\Core\\Command\\Info\\Storage' => __DIR__ . '/../../..' . '/core/Command/Info/Storage.php',
+ 'OC\\Core\\Command\\Info\\Storages' => __DIR__ . '/../../..' . '/core/Command/Info/Storages.php',
'OC\\Core\\Command\\Integrity\\CheckApp' => __DIR__ . '/../../..' . '/core/Command/Integrity/CheckApp.php',
'OC\\Core\\Command\\Integrity\\CheckCore' => __DIR__ . '/../../..' . '/core/Command/Integrity/CheckCore.php',
'OC\\Core\\Command\\Integrity\\SignApp' => __DIR__ . '/../../..' . '/core/Command/Integrity/SignApp.php',
@@ -1319,11 +1334,17 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\Core\\Command\\Maintenance\\RepairShareOwnership' => __DIR__ . '/../../..' . '/core/Command/Maintenance/RepairShareOwnership.php',
'OC\\Core\\Command\\Maintenance\\UpdateHtaccess' => __DIR__ . '/../../..' . '/core/Command/Maintenance/UpdateHtaccess.php',
'OC\\Core\\Command\\Maintenance\\UpdateTheme' => __DIR__ . '/../../..' . '/core/Command/Maintenance/UpdateTheme.php',
+ 'OC\\Core\\Command\\Memcache\\DistributedClear' => __DIR__ . '/../../..' . '/core/Command/Memcache/DistributedClear.php',
+ 'OC\\Core\\Command\\Memcache\\DistributedDelete' => __DIR__ . '/../../..' . '/core/Command/Memcache/DistributedDelete.php',
+ 'OC\\Core\\Command\\Memcache\\DistributedGet' => __DIR__ . '/../../..' . '/core/Command/Memcache/DistributedGet.php',
+ 'OC\\Core\\Command\\Memcache\\DistributedSet' => __DIR__ . '/../../..' . '/core/Command/Memcache/DistributedSet.php',
'OC\\Core\\Command\\Memcache\\RedisCommand' => __DIR__ . '/../../..' . '/core/Command/Memcache/RedisCommand.php',
'OC\\Core\\Command\\Preview\\Cleanup' => __DIR__ . '/../../..' . '/core/Command/Preview/Cleanup.php',
'OC\\Core\\Command\\Preview\\Generate' => __DIR__ . '/../../..' . '/core/Command/Preview/Generate.php',
'OC\\Core\\Command\\Preview\\Repair' => __DIR__ . '/../../..' . '/core/Command/Preview/Repair.php',
'OC\\Core\\Command\\Preview\\ResetRenderedTexts' => __DIR__ . '/../../..' . '/core/Command/Preview/ResetRenderedTexts.php',
+ 'OC\\Core\\Command\\Router\\ListRoutes' => __DIR__ . '/../../..' . '/core/Command/Router/ListRoutes.php',
+ 'OC\\Core\\Command\\Router\\MatchRoute' => __DIR__ . '/../../..' . '/core/Command/Router/MatchRoute.php',
'OC\\Core\\Command\\Security\\BruteforceAttempts' => __DIR__ . '/../../..' . '/core/Command/Security/BruteforceAttempts.php',
'OC\\Core\\Command\\Security\\BruteforceResetAttempts' => __DIR__ . '/../../..' . '/core/Command/Security/BruteforceResetAttempts.php',
'OC\\Core\\Command\\Security\\ExportCertificates' => __DIR__ . '/../../..' . '/core/Command/Security/ExportCertificates.php',
@@ -1359,6 +1380,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\Core\\Command\\User\\Keys\\Verify' => __DIR__ . '/../../..' . '/core/Command/User/Keys/Verify.php',
'OC\\Core\\Command\\User\\LastSeen' => __DIR__ . '/../../..' . '/core/Command/User/LastSeen.php',
'OC\\Core\\Command\\User\\ListCommand' => __DIR__ . '/../../..' . '/core/Command/User/ListCommand.php',
+ 'OC\\Core\\Command\\User\\Profile' => __DIR__ . '/../../..' . '/core/Command/User/Profile.php',
'OC\\Core\\Command\\User\\Report' => __DIR__ . '/../../..' . '/core/Command/User/Report.php',
'OC\\Core\\Command\\User\\ResetPassword' => __DIR__ . '/../../..' . '/core/Command/User/ResetPassword.php',
'OC\\Core\\Command\\User\\Setting' => __DIR__ . '/../../..' . '/core/Command/User/Setting.php',
@@ -1415,8 +1437,11 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\Core\\Exception\\LoginFlowV2ClientForbiddenException' => __DIR__ . '/../../..' . '/core/Exception/LoginFlowV2ClientForbiddenException.php',
'OC\\Core\\Exception\\LoginFlowV2NotFoundException' => __DIR__ . '/../../..' . '/core/Exception/LoginFlowV2NotFoundException.php',
'OC\\Core\\Exception\\ResetPasswordException' => __DIR__ . '/../../..' . '/core/Exception/ResetPasswordException.php',
+ 'OC\\Core\\Listener\\AddMissingIndicesListener' => __DIR__ . '/../../..' . '/core/Listener/AddMissingIndicesListener.php',
+ 'OC\\Core\\Listener\\AddMissingPrimaryKeyListener' => __DIR__ . '/../../..' . '/core/Listener/AddMissingPrimaryKeyListener.php',
'OC\\Core\\Listener\\BeforeMessageLoggedEventListener' => __DIR__ . '/../../..' . '/core/Listener/BeforeMessageLoggedEventListener.php',
'OC\\Core\\Listener\\BeforeTemplateRenderedListener' => __DIR__ . '/../../..' . '/core/Listener/BeforeTemplateRenderedListener.php',
+ 'OC\\Core\\Listener\\FeedBackHandler' => __DIR__ . '/../../..' . '/core/Listener/FeedBackHandler.php',
'OC\\Core\\Middleware\\TwoFactorMiddleware' => __DIR__ . '/../../..' . '/core/Middleware/TwoFactorMiddleware.php',
'OC\\Core\\Migrations\\Version13000Date20170705121758' => __DIR__ . '/../../..' . '/core/Migrations/Version13000Date20170705121758.php',
'OC\\Core\\Migrations\\Version13000Date20170718121200' => __DIR__ . '/../../..' . '/core/Migrations/Version13000Date20170718121200.php',
@@ -1496,6 +1521,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\Core\\Migrations\\Version31000Date20240101084401' => __DIR__ . '/../../..' . '/core/Migrations/Version31000Date20240101084401.php',
'OC\\Core\\Migrations\\Version31000Date20240814184402' => __DIR__ . '/../../..' . '/core/Migrations/Version31000Date20240814184402.php',
'OC\\Core\\Migrations\\Version31000Date20250213102442' => __DIR__ . '/../../..' . '/core/Migrations/Version31000Date20250213102442.php',
+ 'OC\\Core\\Migrations\\Version32000Date20250620081925' => __DIR__ . '/../../..' . '/core/Migrations/Version32000Date20250620081925.php',
'OC\\Core\\Notification\\CoreNotifier' => __DIR__ . '/../../..' . '/core/Notification/CoreNotifier.php',
'OC\\Core\\ResponseDefinitions' => __DIR__ . '/../../..' . '/core/ResponseDefinitions.php',
'OC\\Core\\Service\\LoginFlowV2Service' => __DIR__ . '/../../..' . '/core/Service/LoginFlowV2Service.php',
@@ -1574,6 +1600,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\DirectEditing\\Token' => __DIR__ . '/../../..' . '/lib/private/DirectEditing/Token.php',
'OC\\EmojiHelper' => __DIR__ . '/../../..' . '/lib/private/EmojiHelper.php',
'OC\\Encryption\\DecryptAll' => __DIR__ . '/../../..' . '/lib/private/Encryption/DecryptAll.php',
+ 'OC\\Encryption\\EncryptionEventListener' => __DIR__ . '/../../..' . '/lib/private/Encryption/EncryptionEventListener.php',
'OC\\Encryption\\EncryptionWrapper' => __DIR__ . '/../../..' . '/lib/private/Encryption/EncryptionWrapper.php',
'OC\\Encryption\\Exceptions\\DecryptionFailedException' => __DIR__ . '/../../..' . '/lib/private/Encryption/Exceptions/DecryptionFailedException.php',
'OC\\Encryption\\Exceptions\\EmptyEncryptionDataException' => __DIR__ . '/../../..' . '/lib/private/Encryption/Exceptions/EmptyEncryptionDataException.php',
@@ -1584,7 +1611,6 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\Encryption\\Exceptions\\ModuleDoesNotExistsException' => __DIR__ . '/../../..' . '/lib/private/Encryption/Exceptions/ModuleDoesNotExistsException.php',
'OC\\Encryption\\Exceptions\\UnknownCipherException' => __DIR__ . '/../../..' . '/lib/private/Encryption/Exceptions/UnknownCipherException.php',
'OC\\Encryption\\File' => __DIR__ . '/../../..' . '/lib/private/Encryption/File.php',
- 'OC\\Encryption\\HookManager' => __DIR__ . '/../../..' . '/lib/private/Encryption/HookManager.php',
'OC\\Encryption\\Keys\\Storage' => __DIR__ . '/../../..' . '/lib/private/Encryption/Keys/Storage.php',
'OC\\Encryption\\Manager' => __DIR__ . '/../../..' . '/lib/private/Encryption/Manager.php',
'OC\\Encryption\\Update' => __DIR__ . '/../../..' . '/lib/private/Encryption/Update.php',
@@ -1673,6 +1699,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\Files\\ObjectStore\\Mapper' => __DIR__ . '/../../..' . '/lib/private/Files/ObjectStore/Mapper.php',
'OC\\Files\\ObjectStore\\ObjectStoreScanner' => __DIR__ . '/../../..' . '/lib/private/Files/ObjectStore/ObjectStoreScanner.php',
'OC\\Files\\ObjectStore\\ObjectStoreStorage' => __DIR__ . '/../../..' . '/lib/private/Files/ObjectStore/ObjectStoreStorage.php',
+ 'OC\\Files\\ObjectStore\\PrimaryObjectStoreConfig' => __DIR__ . '/../../..' . '/lib/private/Files/ObjectStore/PrimaryObjectStoreConfig.php',
'OC\\Files\\ObjectStore\\S3' => __DIR__ . '/../../..' . '/lib/private/Files/ObjectStore/S3.php',
'OC\\Files\\ObjectStore\\S3ConfigTrait' => __DIR__ . '/../../..' . '/lib/private/Files/ObjectStore/S3ConfigTrait.php',
'OC\\Files\\ObjectStore\\S3ConnectionTrait' => __DIR__ . '/../../..' . '/lib/private/Files/ObjectStore/S3ConnectionTrait.php',
@@ -1923,6 +1950,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\Repair\\ClearGeneratedAvatarCache' => __DIR__ . '/../../..' . '/lib/private/Repair/ClearGeneratedAvatarCache.php',
'OC\\Repair\\ClearGeneratedAvatarCacheJob' => __DIR__ . '/../../..' . '/lib/private/Repair/ClearGeneratedAvatarCacheJob.php',
'OC\\Repair\\Collation' => __DIR__ . '/../../..' . '/lib/private/Repair/Collation.php',
+ 'OC\\Repair\\ConfigKeyMigration' => __DIR__ . '/../../..' . '/lib/private/Repair/ConfigKeyMigration.php',
'OC\\Repair\\Events\\RepairAdvanceEvent' => __DIR__ . '/../../..' . '/lib/private/Repair/Events/RepairAdvanceEvent.php',
'OC\\Repair\\Events\\RepairErrorEvent' => __DIR__ . '/../../..' . '/lib/private/Repair/Events/RepairErrorEvent.php',
'OC\\Repair\\Events\\RepairFinishEvent' => __DIR__ . '/../../..' . '/lib/private/Repair/Events/RepairFinishEvent.php',
diff --git a/lib/l10n/af.js b/lib/l10n/af.js
index db8d58e5af7..e5f6ef63633 100644
--- a/lib/l10n/af.js
+++ b/lib/l10n/af.js
@@ -27,8 +27,6 @@ OC.L10N.register(
"a safe home for all your data" : "’n veilige tuiste vir al u data",
"Storage is temporarily not available" : "Berging is tydelik nie beskikbaar nie",
"Text" : "Teks",
- "Summary" : "Opsomming",
- "Users" : "Gebruikers",
- "Open »%s«" : "Open »%s«"
+ "Summary" : "Opsomming"
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/af.json b/lib/l10n/af.json
index 4fd5d48c869..751b24be3cc 100644
--- a/lib/l10n/af.json
+++ b/lib/l10n/af.json
@@ -25,8 +25,6 @@
"a safe home for all your data" : "’n veilige tuiste vir al u data",
"Storage is temporarily not available" : "Berging is tydelik nie beskikbaar nie",
"Text" : "Teks",
- "Summary" : "Opsomming",
- "Users" : "Gebruikers",
- "Open »%s«" : "Open »%s«"
+ "Summary" : "Opsomming"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/an.js b/lib/l10n/an.js
index fb664bfbfd6..a5fb073752e 100644
--- a/lib/l10n/an.js
+++ b/lib/l10n/an.js
@@ -11,7 +11,6 @@ OC.L10N.register(
"last year" : "Zaguero anyo",
"Apps" : "Aplicacions",
"Settings" : "Configuración",
- "Email" : "Correu electronico",
- "Users" : "Usuarios"
+ "Email" : "Correu electronico"
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/an.json b/lib/l10n/an.json
index 0ad8e3e637d..52f81577846 100644
--- a/lib/l10n/an.json
+++ b/lib/l10n/an.json
@@ -9,7 +9,6 @@
"last year" : "Zaguero anyo",
"Apps" : "Aplicacions",
"Settings" : "Configuración",
- "Email" : "Correu electronico",
- "Users" : "Usuarios"
+ "Email" : "Correu electronico"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/ar.js b/lib/l10n/ar.js
index f1efaa4e971..4747362aaa8 100644
--- a/lib/l10n/ar.js
+++ b/lib/l10n/ar.js
@@ -93,6 +93,7 @@ OC.L10N.register(
"Destination does not exist" : "المَقصِد غير موجود",
"Destination is not creatable" : "المِقصِد لايمكن إنشاؤه",
"Dot files are not allowed" : "الملفات النقطية (ملفات ذات أسماء تبدأ بنقطة) غير مسموح بها",
+ "renamed file" : "ملف معاد تسميته",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" غير مسموح به أن يكون اسم ملف أو مجلد.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" غير مسموح به أن يكون بادئة لاسم ملف أو مجلد.",
"\"%1$s\" is not allowed inside a file or folder name." : "\"%1$s\" غير مسموح به أن يكون داخل اسم ملف أو مجلد.",
@@ -441,20 +442,7 @@ OC.L10N.register(
"Generate headline" : "توليد العنوان",
"Summarizes text by reducing its length without losing key information." : "يُلَخِّص النص بتقليل طوله دون فقدان المعنى.",
"Extracts topics from a text and outputs them separated by commas." : "يستخلص المواضيع من النص و إخراجها مفصولة بفواصل.",
- "Education Edition" : "الإصدار التعليمي",
- "File name is a reserved word" : "اسم الملف كلمة محجوزة",
- "File name contains at least one invalid character" : "اسم الملف به ، على الأقل ، حرف غير صالح",
- "File name is too long" : "اسم الملف طويل جداً",
- "Users" : "المستخدمين",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s شارك »%2$s« معك و يرغب في إضافة:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s شارك »%2$s« معك و يرغب في إضافة",
- "»%s« added a note to a file shared with you" : "»%s« أضاف ملاحظة لملفٍ سلفت مشاركته معك",
- "Open »%s«" : "فتح »%s«",
- "%1$s shared »%2$s« with you" : "%1$s شارك »%2$s« معك",
- "%1$s shared »%2$s« with you." : "%1$s شَارَكَ »%2$s« معك.",
- "Click the button below to open it." : "اضغط على الزر الذي تحته ليتم فتحه.",
"File is currently busy, please try again later" : "إنّ الملف مشغول الآمن، يرجى إعادة المحاولة لاحقًا",
- "Cannot download file" : "لا يمكن تنزيل الملف",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "تأكد من وجود ملفٍ باسم \".ocdata\" في جذر دليل البيانات data directory."
+ "Cannot download file" : "لا يمكن تنزيل الملف"
},
"nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;");
diff --git a/lib/l10n/ar.json b/lib/l10n/ar.json
index b5647e17ffc..2bc87515bac 100644
--- a/lib/l10n/ar.json
+++ b/lib/l10n/ar.json
@@ -91,6 +91,7 @@
"Destination does not exist" : "المَقصِد غير موجود",
"Destination is not creatable" : "المِقصِد لايمكن إنشاؤه",
"Dot files are not allowed" : "الملفات النقطية (ملفات ذات أسماء تبدأ بنقطة) غير مسموح بها",
+ "renamed file" : "ملف معاد تسميته",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" غير مسموح به أن يكون اسم ملف أو مجلد.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" غير مسموح به أن يكون بادئة لاسم ملف أو مجلد.",
"\"%1$s\" is not allowed inside a file or folder name." : "\"%1$s\" غير مسموح به أن يكون داخل اسم ملف أو مجلد.",
@@ -439,20 +440,7 @@
"Generate headline" : "توليد العنوان",
"Summarizes text by reducing its length without losing key information." : "يُلَخِّص النص بتقليل طوله دون فقدان المعنى.",
"Extracts topics from a text and outputs them separated by commas." : "يستخلص المواضيع من النص و إخراجها مفصولة بفواصل.",
- "Education Edition" : "الإصدار التعليمي",
- "File name is a reserved word" : "اسم الملف كلمة محجوزة",
- "File name contains at least one invalid character" : "اسم الملف به ، على الأقل ، حرف غير صالح",
- "File name is too long" : "اسم الملف طويل جداً",
- "Users" : "المستخدمين",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s شارك »%2$s« معك و يرغب في إضافة:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s شارك »%2$s« معك و يرغب في إضافة",
- "»%s« added a note to a file shared with you" : "»%s« أضاف ملاحظة لملفٍ سلفت مشاركته معك",
- "Open »%s«" : "فتح »%s«",
- "%1$s shared »%2$s« with you" : "%1$s شارك »%2$s« معك",
- "%1$s shared »%2$s« with you." : "%1$s شَارَكَ »%2$s« معك.",
- "Click the button below to open it." : "اضغط على الزر الذي تحته ليتم فتحه.",
"File is currently busy, please try again later" : "إنّ الملف مشغول الآمن، يرجى إعادة المحاولة لاحقًا",
- "Cannot download file" : "لا يمكن تنزيل الملف",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "تأكد من وجود ملفٍ باسم \".ocdata\" في جذر دليل البيانات data directory."
+ "Cannot download file" : "لا يمكن تنزيل الملف"
},"pluralForm" :"nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;"
} \ No newline at end of file
diff --git a/lib/l10n/ast.js b/lib/l10n/ast.js
index d0c5339e92f..2dae4044047 100644
--- a/lib/l10n/ast.js
+++ b/lib/l10n/ast.js
@@ -211,19 +211,6 @@ OC.L10N.register(
"Target language" : "Llingua de destín",
"Result" : "Resultáu",
"Summarizes text by reducing its length without losing key information." : "Resume'l testu amenorgando la so llongura ensin perder la información importante.",
- "Extracts topics from a text and outputs them separated by commas." : "Estrái temes d'un testu y devuélvelos separtaos per comes.",
- "Education Edition" : "Edición educativa",
- "File name is a reserved word" : "El nome de ficheru ye una pallabra acutada",
- "File name contains at least one invalid character" : "El nome del ficheru contién polo menos un caráuter inváldu",
- "File name is too long" : "El nome del ficheru ye mui llongu",
- "Users" : "Usuarios",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s compartío «%2$s» contigo y quier amestar:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s compartío «%2$s» contigo y quier amestar",
- "»%s« added a note to a file shared with you" : "«%s» amestó una nota a un ficheru compartío contigo",
- "Open »%s«" : "Abrir «%s»",
- "%1$s shared »%2$s« with you" : "%1$s compartió «%2$s» contigo",
- "%1$s shared »%2$s« with you." : "%1$s compartió «%2$s» contigo.",
- "Click the button below to open it." : "Calca nel botón p'abrilo.",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegúrate de que'l ficheru llamáu «.ocdata» ta nel raigañu del direutoriu de datos."
+ "Extracts topics from a text and outputs them separated by commas." : "Estrái temes d'un testu y devuélvelos separtaos per comes."
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/ast.json b/lib/l10n/ast.json
index ccdbc79ad25..ef0f160334a 100644
--- a/lib/l10n/ast.json
+++ b/lib/l10n/ast.json
@@ -209,19 +209,6 @@
"Target language" : "Llingua de destín",
"Result" : "Resultáu",
"Summarizes text by reducing its length without losing key information." : "Resume'l testu amenorgando la so llongura ensin perder la información importante.",
- "Extracts topics from a text and outputs them separated by commas." : "Estrái temes d'un testu y devuélvelos separtaos per comes.",
- "Education Edition" : "Edición educativa",
- "File name is a reserved word" : "El nome de ficheru ye una pallabra acutada",
- "File name contains at least one invalid character" : "El nome del ficheru contién polo menos un caráuter inváldu",
- "File name is too long" : "El nome del ficheru ye mui llongu",
- "Users" : "Usuarios",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s compartío «%2$s» contigo y quier amestar:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s compartío «%2$s» contigo y quier amestar",
- "»%s« added a note to a file shared with you" : "«%s» amestó una nota a un ficheru compartío contigo",
- "Open »%s«" : "Abrir «%s»",
- "%1$s shared »%2$s« with you" : "%1$s compartió «%2$s» contigo",
- "%1$s shared »%2$s« with you." : "%1$s compartió «%2$s» contigo.",
- "Click the button below to open it." : "Calca nel botón p'abrilo.",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegúrate de que'l ficheru llamáu «.ocdata» ta nel raigañu del direutoriu de datos."
+ "Extracts topics from a text and outputs them separated by commas." : "Estrái temes d'un testu y devuélvelos separtaos per comes."
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/az.js b/lib/l10n/az.js
index 3c5d659f0e5..ee9fc7b6387 100644
--- a/lib/l10n/az.js
+++ b/lib/l10n/az.js
@@ -65,7 +65,6 @@ OC.L10N.register(
"Authentication error" : "Təyinat metodikası",
"Token expired. Please reload page." : "Token vaxtı bitib. Xahiş olunur səhifəni yenidən yükləyəsiniz.",
"This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "Bu ola bilər ki, cache/accelerator such tərəfindən cağırılıb hansi ki, Zend OPcache və eAccelerator-da olduğu kimidir.",
- "Summary" : "Xülasə",
- "Users" : "İstifadəçilər"
+ "Summary" : "Xülasə"
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/az.json b/lib/l10n/az.json
index f355835ace3..75d1c258247 100644
--- a/lib/l10n/az.json
+++ b/lib/l10n/az.json
@@ -63,7 +63,6 @@
"Authentication error" : "Təyinat metodikası",
"Token expired. Please reload page." : "Token vaxtı bitib. Xahiş olunur səhifəni yenidən yükləyəsiniz.",
"This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "Bu ola bilər ki, cache/accelerator such tərəfindən cağırılıb hansi ki, Zend OPcache və eAccelerator-da olduğu kimidir.",
- "Summary" : "Xülasə",
- "Users" : "İstifadəçilər"
+ "Summary" : "Xülasə"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/bg.js b/lib/l10n/bg.js
index cc29e62324b..445da4c9626 100644
--- a/lib/l10n/bg.js
+++ b/lib/l10n/bg.js
@@ -92,6 +92,7 @@ OC.L10N.register(
"Administration settings" : "Административни настройки",
"Settings" : "Настройки",
"Log out" : "Отписване",
+ "Accounts" : "Профили",
"Email" : "Имейл",
"Mail %s" : "Поща %s",
"Fediverse" : "Fediverse /съвкупност от обединени сървъри/",
@@ -103,12 +104,13 @@ OC.L10N.register(
"Website" : "Уеб сайт",
"Visit %s" : "Посещение %s",
"Address" : "Адрес",
- "Profile picture" : "Снимка на профила",
+ "Profile picture" : "Профилна снимка",
"About" : "Относно",
"Display name" : "Име за визуализация",
"Headline" : "Заглавие",
"Organisation" : "Организация",
"Role" : "Роля",
+ "Pronouns" : "Обръщение",
"Additional settings" : "Допълнителни настройки",
"Enter the database name for %s" : "Въведете името на базата данни за %s",
"You cannot use dots in the database name %s" : "Не можете да използвате точки в името на базата данни %s",
@@ -196,8 +198,8 @@ OC.L10N.register(
"This can usually be fixed by giving the web server write access to the root directory. See %s" : "Това обикновено може да бъде оправено като, се даде достъп на уеб сървъра да записва в основната директория. Погледнете %s",
"Permissions can usually be fixed by giving the web server write access to the root directory. See %s." : "Права обикновено могат да бъдат оправени когато се даде достъп на уеб сървъра да пише в основната директория. Погледнете %s.",
"Your data directory is not writable." : "Вашата директория с данни не е записваема.",
- "Setting locale to %s failed." : "Неуспешно задаване на езикова променлива %s.",
- "Please install one of these locales on your system and restart your web server." : "Моля, инсталирайте една от тези езикови променливи на вашата система и си рестартирайте уеб сървъра.",
+ "Setting locale to %s failed." : "Неуспешно задаване на регион %s. ",
+ "Please install one of these locales on your system and restart your web server." : "Моля, задайте един от следните региони във Вашата система след което рестартирайте сървъра.",
"PHP module %s not installed." : "PHP модулът %s не е инсталиран.",
"Please ask your server administrator to install the module." : "Моля, помолете вашия администратор да инсталира модула.",
"PHP setting \"%s\" is not set to \"%s\"." : "PHP настройка \"%s\" не е зададена на \"%s\".",
@@ -231,20 +233,7 @@ OC.L10N.register(
"Translate" : "Превод",
"Target language" : "Целеви език",
"Result" : "Резултат",
- "Education Edition" : "Образователно издание",
- "File name is a reserved word" : "Името на файла е запазена дума",
- "File name contains at least one invalid character" : "Името на файла съдържа поне един невалиден символ",
- "File name is too long" : "Името на файла е твърде дълго",
- "Users" : "Потребители",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s сподели »%2$s« с вас и иска да добави:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s сподели »%2$s« с вас и иска да добави",
- "»%s« added a note to a file shared with you" : "»%s« добави бележка към файл, споделен с вас ",
- "Open »%s«" : "Отвори »%s«",
- "%1$s shared »%2$s« with you" : "%1$s сподели »%2$s« с вас",
- "%1$s shared »%2$s« with you." : "%1$s сподели »%2$s« с вас.",
- "Click the button below to open it." : "Щракнете върху бутона по-долу, за да го отворите.",
"File is currently busy, please try again later" : "Файлът в момента е зает, моля, опитайте отново по-късно",
- "Cannot download file" : "Файлът не можа да бъде изтеглен",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Уверете се, че има файл, наречен \".ocdata\" в корена на директорията с данни."
+ "Cannot download file" : "Файлът не можа да бъде изтеглен"
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/bg.json b/lib/l10n/bg.json
index 862e3cf0086..a4bc3162762 100644
--- a/lib/l10n/bg.json
+++ b/lib/l10n/bg.json
@@ -90,6 +90,7 @@
"Administration settings" : "Административни настройки",
"Settings" : "Настройки",
"Log out" : "Отписване",
+ "Accounts" : "Профили",
"Email" : "Имейл",
"Mail %s" : "Поща %s",
"Fediverse" : "Fediverse /съвкупност от обединени сървъри/",
@@ -101,12 +102,13 @@
"Website" : "Уеб сайт",
"Visit %s" : "Посещение %s",
"Address" : "Адрес",
- "Profile picture" : "Снимка на профила",
+ "Profile picture" : "Профилна снимка",
"About" : "Относно",
"Display name" : "Име за визуализация",
"Headline" : "Заглавие",
"Organisation" : "Организация",
"Role" : "Роля",
+ "Pronouns" : "Обръщение",
"Additional settings" : "Допълнителни настройки",
"Enter the database name for %s" : "Въведете името на базата данни за %s",
"You cannot use dots in the database name %s" : "Не можете да използвате точки в името на базата данни %s",
@@ -194,8 +196,8 @@
"This can usually be fixed by giving the web server write access to the root directory. See %s" : "Това обикновено може да бъде оправено като, се даде достъп на уеб сървъра да записва в основната директория. Погледнете %s",
"Permissions can usually be fixed by giving the web server write access to the root directory. See %s." : "Права обикновено могат да бъдат оправени когато се даде достъп на уеб сървъра да пише в основната директория. Погледнете %s.",
"Your data directory is not writable." : "Вашата директория с данни не е записваема.",
- "Setting locale to %s failed." : "Неуспешно задаване на езикова променлива %s.",
- "Please install one of these locales on your system and restart your web server." : "Моля, инсталирайте една от тези езикови променливи на вашата система и си рестартирайте уеб сървъра.",
+ "Setting locale to %s failed." : "Неуспешно задаване на регион %s. ",
+ "Please install one of these locales on your system and restart your web server." : "Моля, задайте един от следните региони във Вашата система след което рестартирайте сървъра.",
"PHP module %s not installed." : "PHP модулът %s не е инсталиран.",
"Please ask your server administrator to install the module." : "Моля, помолете вашия администратор да инсталира модула.",
"PHP setting \"%s\" is not set to \"%s\"." : "PHP настройка \"%s\" не е зададена на \"%s\".",
@@ -229,20 +231,7 @@
"Translate" : "Превод",
"Target language" : "Целеви език",
"Result" : "Резултат",
- "Education Edition" : "Образователно издание",
- "File name is a reserved word" : "Името на файла е запазена дума",
- "File name contains at least one invalid character" : "Името на файла съдържа поне един невалиден символ",
- "File name is too long" : "Името на файла е твърде дълго",
- "Users" : "Потребители",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s сподели »%2$s« с вас и иска да добави:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s сподели »%2$s« с вас и иска да добави",
- "»%s« added a note to a file shared with you" : "»%s« добави бележка към файл, споделен с вас ",
- "Open »%s«" : "Отвори »%s«",
- "%1$s shared »%2$s« with you" : "%1$s сподели »%2$s« с вас",
- "%1$s shared »%2$s« with you." : "%1$s сподели »%2$s« с вас.",
- "Click the button below to open it." : "Щракнете върху бутона по-долу, за да го отворите.",
"File is currently busy, please try again later" : "Файлът в момента е зает, моля, опитайте отново по-късно",
- "Cannot download file" : "Файлът не можа да бъде изтеглен",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Уверете се, че има файл, наречен \".ocdata\" в корена на директорията с данни."
+ "Cannot download file" : "Файлът не можа да бъде изтеглен"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/bn_BD.js b/lib/l10n/bn_BD.js
index 8eecb5228ea..6f845de9c0d 100644
--- a/lib/l10n/bn_BD.js
+++ b/lib/l10n/bn_BD.js
@@ -62,7 +62,6 @@ OC.L10N.register(
"Dec." : "ডিসে.",
"Application is not enabled" : "অ্যাপ্লিকেসনটি সক্রিয় নয়",
"Authentication error" : "অনুমোদন ঘটিত সমস্যা",
- "Token expired. Please reload page." : "টোকেন মেয়াদোত্তীর্ণ। দয়া করে পৃষ্ঠাটি পূনরায় লোড করুন।",
- "Users" : "ব্যবহারকারী"
+ "Token expired. Please reload page." : "টোকেন মেয়াদোত্তীর্ণ। দয়া করে পৃষ্ঠাটি পূনরায় লোড করুন।"
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/bn_BD.json b/lib/l10n/bn_BD.json
index 5ef2ad8d485..e94d9262761 100644
--- a/lib/l10n/bn_BD.json
+++ b/lib/l10n/bn_BD.json
@@ -60,7 +60,6 @@
"Dec." : "ডিসে.",
"Application is not enabled" : "অ্যাপ্লিকেসনটি সক্রিয় নয়",
"Authentication error" : "অনুমোদন ঘটিত সমস্যা",
- "Token expired. Please reload page." : "টোকেন মেয়াদোত্তীর্ণ। দয়া করে পৃষ্ঠাটি পূনরায় লোড করুন।",
- "Users" : "ব্যবহারকারী"
+ "Token expired. Please reload page." : "টোকেন মেয়াদোত্তীর্ণ। দয়া করে পৃষ্ঠাটি পূনরায় লোড করুন।"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/br.js b/lib/l10n/br.js
index 6d30de9da02..79c6e326bb6 100644
--- a/lib/l10n/br.js
+++ b/lib/l10n/br.js
@@ -76,10 +76,6 @@ OC.L10N.register(
"Text" : "Testenn",
"Summary" : "Diverrañ",
"Translate" : "Treiñ",
- "Origin text" : "Testenn orin",
- "File name contains at least one invalid character" : "Un arouez fall ez eus d'an neubeutañ en anv restr",
- "File name is too long" : "Anv ar restr a zo re hir",
- "Users" : "Implijer",
- "Open »%s«" : "Digeriñ »%s«"
+ "Origin text" : "Testenn orin"
},
"nplurals=5; plural=((n%10 == 1) && (n%100 != 11) && (n%100 !=71) && (n%100 !=91) ? 0 :(n%10 == 2) && (n%100 != 12) && (n%100 !=72) && (n%100 !=92) ? 1 :(n%10 ==3 || n%10==4 || n%10==9) && (n%100 < 10 || n% 100 > 19) && (n%100 < 70 || n%100 > 79) && (n%100 < 90 || n%100 > 99) ? 2 :(n != 0 && n % 1000000 == 0) ? 3 : 4);");
diff --git a/lib/l10n/br.json b/lib/l10n/br.json
index 8d9d5d41951..c250f436eeb 100644
--- a/lib/l10n/br.json
+++ b/lib/l10n/br.json
@@ -74,10 +74,6 @@
"Text" : "Testenn",
"Summary" : "Diverrañ",
"Translate" : "Treiñ",
- "Origin text" : "Testenn orin",
- "File name contains at least one invalid character" : "Un arouez fall ez eus d'an neubeutañ en anv restr",
- "File name is too long" : "Anv ar restr a zo re hir",
- "Users" : "Implijer",
- "Open »%s«" : "Digeriñ »%s«"
+ "Origin text" : "Testenn orin"
},"pluralForm" :"nplurals=5; plural=((n%10 == 1) && (n%100 != 11) && (n%100 !=71) && (n%100 !=91) ? 0 :(n%10 == 2) && (n%100 != 12) && (n%100 !=72) && (n%100 !=92) ? 1 :(n%10 ==3 || n%10==4 || n%10==9) && (n%100 < 10 || n% 100 > 19) && (n%100 < 70 || n%100 > 79) && (n%100 < 90 || n%100 > 99) ? 2 :(n != 0 && n % 1000000 == 0) ? 3 : 4);"
} \ No newline at end of file
diff --git a/lib/l10n/bs.js b/lib/l10n/bs.js
index 6ffc3336928..e813de70a76 100644
--- a/lib/l10n/bs.js
+++ b/lib/l10n/bs.js
@@ -54,7 +54,6 @@ OC.L10N.register(
"Dec." : "Dec.",
"A valid password must be provided" : "Nužno je navesti valjanu lozinku",
"Authentication error" : "Grešna autentifikacije",
- "This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "Uzrok tome je vjerojatno neki ubrzivač predmemorisanja kao što je Zend OPcache ili eAccelerator.",
- "Users" : "Korisnici"
+ "This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "Uzrok tome je vjerojatno neki ubrzivač predmemorisanja kao što je Zend OPcache ili eAccelerator."
},
"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/lib/l10n/bs.json b/lib/l10n/bs.json
index aaa1cf38490..d1b0b8f341e 100644
--- a/lib/l10n/bs.json
+++ b/lib/l10n/bs.json
@@ -52,7 +52,6 @@
"Dec." : "Dec.",
"A valid password must be provided" : "Nužno je navesti valjanu lozinku",
"Authentication error" : "Grešna autentifikacije",
- "This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "Uzrok tome je vjerojatno neki ubrzivač predmemorisanja kao što je Zend OPcache ili eAccelerator.",
- "Users" : "Korisnici"
+ "This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "Uzrok tome je vjerojatno neki ubrzivač predmemorisanja kao što je Zend OPcache ili eAccelerator."
},"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);"
} \ No newline at end of file
diff --git a/lib/l10n/ca.js b/lib/l10n/ca.js
index 725e668ae9c..2ad5dbcb9ef 100644
--- a/lib/l10n/ca.js
+++ b/lib/l10n/ca.js
@@ -439,20 +439,7 @@ OC.L10N.register(
"Generate headline" : "Genera un titular",
"Summarizes text by reducing its length without losing key information." : "Resumeix el text reduint-ne la longitud sense perdre la informació clau.",
"Extracts topics from a text and outputs them separated by commas." : "Extreu els temes d'un text i els retorna separats per comes.",
- "Education Edition" : "Edició educativa",
- "File name is a reserved word" : "El nom del fitxer és una paraula reservada",
- "File name contains at least one invalid character" : "El nom del fitxer conté almenys un caràcter no vàlid",
- "File name is too long" : "El nom del fitxer és massa llarg",
- "Users" : "Usuaris",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s ha compartit «%2$s» amb vós i vol afegir:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s ha compartit «%2$s» amb vós i vol afegir",
- "»%s« added a note to a file shared with you" : "%s ha afegit una nota a un fitxer compartit amb vós",
- "Open »%s«" : "Obre «%s»",
- "%1$s shared »%2$s« with you" : "%1$s ha compartit «%2$s» amb vós",
- "%1$s shared »%2$s« with you." : "%1$s ha compartit «%2$s» amb vós.",
- "Click the button below to open it." : "Feu clic en el botó següent per a obrir-ho.",
"File is currently busy, please try again later" : "El fitxer està ocupat actualment; torneu-ho a provar més tard",
- "Cannot download file" : "No es pot baixar el fitxer",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Assegureu-vos que hi hagi un fitxer anomenat «.ocdata» en l'arrel de la carpeta de dades."
+ "Cannot download file" : "No es pot baixar el fitxer"
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/ca.json b/lib/l10n/ca.json
index 91c64b745f4..919bbee74b5 100644
--- a/lib/l10n/ca.json
+++ b/lib/l10n/ca.json
@@ -437,20 +437,7 @@
"Generate headline" : "Genera un titular",
"Summarizes text by reducing its length without losing key information." : "Resumeix el text reduint-ne la longitud sense perdre la informació clau.",
"Extracts topics from a text and outputs them separated by commas." : "Extreu els temes d'un text i els retorna separats per comes.",
- "Education Edition" : "Edició educativa",
- "File name is a reserved word" : "El nom del fitxer és una paraula reservada",
- "File name contains at least one invalid character" : "El nom del fitxer conté almenys un caràcter no vàlid",
- "File name is too long" : "El nom del fitxer és massa llarg",
- "Users" : "Usuaris",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s ha compartit «%2$s» amb vós i vol afegir:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s ha compartit «%2$s» amb vós i vol afegir",
- "»%s« added a note to a file shared with you" : "%s ha afegit una nota a un fitxer compartit amb vós",
- "Open »%s«" : "Obre «%s»",
- "%1$s shared »%2$s« with you" : "%1$s ha compartit «%2$s» amb vós",
- "%1$s shared »%2$s« with you." : "%1$s ha compartit «%2$s» amb vós.",
- "Click the button below to open it." : "Feu clic en el botó següent per a obrir-ho.",
"File is currently busy, please try again later" : "El fitxer està ocupat actualment; torneu-ho a provar més tard",
- "Cannot download file" : "No es pot baixar el fitxer",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Assegureu-vos que hi hagi un fitxer anomenat «.ocdata» en l'arrel de la carpeta de dades."
+ "Cannot download file" : "No es pot baixar el fitxer"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/cs.js b/lib/l10n/cs.js
index 06f4631fa3c..78b1ce3dfe2 100644
--- a/lib/l10n/cs.js
+++ b/lib/l10n/cs.js
@@ -93,6 +93,8 @@ OC.L10N.register(
"Destination does not exist" : "Cíl neexistuje",
"Destination is not creatable" : "Cíl není možné vytvořit",
"Dot files are not allowed" : "Názvy souborů, začínající na tečku nejsou dovolené",
+ "%1$s (renamed)" : "%1$s (přejmenované)",
+ "renamed file" : "přejmenovaný soubor",
"\"%1$s\" is a forbidden file or folder name." : "„%1$s“ je zakázáno v názvu souboru nebo složky.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "„%1$s“ je zakázaná předpona pro názvy souborů či složek.",
"\"%1$s\" is not allowed inside a file or folder name." : "„%1$s“ není povoleno v rámci názvu souboru či složky.",
@@ -273,7 +275,7 @@ OC.L10N.register(
"A valid Login must be provided" : "Je třeba zadat platné přihlašovací jméno",
"Login contains whitespace at the beginning or at the end" : "Přihlašovací jméno je chybné – na jeho začátku či konci se nachází prázdný znak (mezera, tabulátor, atp.)",
"Login must not consist of dots only" : "Přihlašovací jméno se nemůže skládat pouze ze samých teček",
- "Login is too long" : "Přihlašovací jméno je příliš dlouhé",
+ "Username is too long" : "Uživatelské jméno je příliš dlouhé",
"Login is invalid because files already exist for this user" : "Přihlašovací jméno není platné, protože protože pro tohoto uživatele už existují soubory",
"Account disabled" : "Účet znepřístupněn",
"Login canceled by app" : "Přihlášení zrušeno aplikací",
@@ -364,6 +366,11 @@ OC.L10N.register(
"How many images to generate" : "Kolik obrázků vytvořit",
"Output images" : "Výstupní obrázky",
"The generated images" : "Vytvořené obrázky",
+ "Generate speech" : "Vytvořit řeč",
+ "Generate speech from a transcript" : "Vytvořit řeč z přepisu",
+ "Write transcript that you want the assistant to generate speech from" : "Napište přepis, ze kterého chcete, aby asistent vytvořil řeč",
+ "Output speech" : "Výstupní řeč",
+ "The generated speech" : "Vytvořená řeč",
"Free text to text prompt" : "Volný text na textový prompt",
"Runs an arbitrary prompt through a language model that returns a reply" : "Spouští libovolnou výzvu skrze jazykový model který vrací odpověď",
"Describe a task that you want the assistant to do or ask a question" : "Popište úkol který chcete aby asistent udělal nebo položte dotaz",
@@ -443,20 +450,8 @@ OC.L10N.register(
"Generate headline" : "Vytvořit nadpis",
"Summarizes text by reducing its length without losing key information." : "Vytvoří stručný souhrn textu tím, že zkrátí jeho délku aniž by byly ztraceny klíčové informace",
"Extracts topics from a text and outputs them separated by commas." : "Vyzíská témata z textu a vypíše je oddělované čárkami.",
- "Education Edition" : "Vydání pro vzdělávací instituce",
- "File name is a reserved word" : "Název souboru je rezervované slovo",
- "File name contains at least one invalid character" : "Název souboru obsahuje přinejmenším jeden neplatný znak",
- "File name is too long" : "Název souboru je příliš dlouhý",
- "Users" : "Uživatelé",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s sdílí „%2$s“ a dodává:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s sdílí „%2$s“ a dodává",
- "»%s« added a note to a file shared with you" : "„%s“ dodává poznámku k nasdílenému souboru ",
- "Open »%s«" : "Otevřít „%s“",
- "%1$s shared »%2$s« with you" : "%1$s vám sdílí „%2$s“",
- "%1$s shared »%2$s« with you." : "%1$s vám nasdílel(a) „%2$s“.",
- "Click the button below to open it." : "Pro otevření klikněte na tlačítko níže.",
"File is currently busy, please try again later" : "Soubor je nyní používán, zkuste to později",
"Cannot download file" : "Soubor se nedaří stáhnout",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Ověřte, že v kořeni datového adresáře je soubor s názvem „.ocdata“."
+ "Login is too long" : "Přihlašovací jméno je příliš dlouhé"
},
"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/lib/l10n/cs.json b/lib/l10n/cs.json
index 0fd7ca64748..aa3b9876ad3 100644
--- a/lib/l10n/cs.json
+++ b/lib/l10n/cs.json
@@ -91,6 +91,8 @@
"Destination does not exist" : "Cíl neexistuje",
"Destination is not creatable" : "Cíl není možné vytvořit",
"Dot files are not allowed" : "Názvy souborů, začínající na tečku nejsou dovolené",
+ "%1$s (renamed)" : "%1$s (přejmenované)",
+ "renamed file" : "přejmenovaný soubor",
"\"%1$s\" is a forbidden file or folder name." : "„%1$s“ je zakázáno v názvu souboru nebo složky.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "„%1$s“ je zakázaná předpona pro názvy souborů či složek.",
"\"%1$s\" is not allowed inside a file or folder name." : "„%1$s“ není povoleno v rámci názvu souboru či složky.",
@@ -271,7 +273,7 @@
"A valid Login must be provided" : "Je třeba zadat platné přihlašovací jméno",
"Login contains whitespace at the beginning or at the end" : "Přihlašovací jméno je chybné – na jeho začátku či konci se nachází prázdný znak (mezera, tabulátor, atp.)",
"Login must not consist of dots only" : "Přihlašovací jméno se nemůže skládat pouze ze samých teček",
- "Login is too long" : "Přihlašovací jméno je příliš dlouhé",
+ "Username is too long" : "Uživatelské jméno je příliš dlouhé",
"Login is invalid because files already exist for this user" : "Přihlašovací jméno není platné, protože protože pro tohoto uživatele už existují soubory",
"Account disabled" : "Účet znepřístupněn",
"Login canceled by app" : "Přihlášení zrušeno aplikací",
@@ -362,6 +364,11 @@
"How many images to generate" : "Kolik obrázků vytvořit",
"Output images" : "Výstupní obrázky",
"The generated images" : "Vytvořené obrázky",
+ "Generate speech" : "Vytvořit řeč",
+ "Generate speech from a transcript" : "Vytvořit řeč z přepisu",
+ "Write transcript that you want the assistant to generate speech from" : "Napište přepis, ze kterého chcete, aby asistent vytvořil řeč",
+ "Output speech" : "Výstupní řeč",
+ "The generated speech" : "Vytvořená řeč",
"Free text to text prompt" : "Volný text na textový prompt",
"Runs an arbitrary prompt through a language model that returns a reply" : "Spouští libovolnou výzvu skrze jazykový model který vrací odpověď",
"Describe a task that you want the assistant to do or ask a question" : "Popište úkol který chcete aby asistent udělal nebo položte dotaz",
@@ -441,20 +448,8 @@
"Generate headline" : "Vytvořit nadpis",
"Summarizes text by reducing its length without losing key information." : "Vytvoří stručný souhrn textu tím, že zkrátí jeho délku aniž by byly ztraceny klíčové informace",
"Extracts topics from a text and outputs them separated by commas." : "Vyzíská témata z textu a vypíše je oddělované čárkami.",
- "Education Edition" : "Vydání pro vzdělávací instituce",
- "File name is a reserved word" : "Název souboru je rezervované slovo",
- "File name contains at least one invalid character" : "Název souboru obsahuje přinejmenším jeden neplatný znak",
- "File name is too long" : "Název souboru je příliš dlouhý",
- "Users" : "Uživatelé",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s sdílí „%2$s“ a dodává:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s sdílí „%2$s“ a dodává",
- "»%s« added a note to a file shared with you" : "„%s“ dodává poznámku k nasdílenému souboru ",
- "Open »%s«" : "Otevřít „%s“",
- "%1$s shared »%2$s« with you" : "%1$s vám sdílí „%2$s“",
- "%1$s shared »%2$s« with you." : "%1$s vám nasdílel(a) „%2$s“.",
- "Click the button below to open it." : "Pro otevření klikněte na tlačítko níže.",
"File is currently busy, please try again later" : "Soubor je nyní používán, zkuste to později",
"Cannot download file" : "Soubor se nedaří stáhnout",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Ověřte, že v kořeni datového adresáře je soubor s názvem „.ocdata“."
+ "Login is too long" : "Přihlašovací jméno je příliš dlouhé"
},"pluralForm" :"nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;"
} \ No newline at end of file
diff --git a/lib/l10n/cy_GB.js b/lib/l10n/cy_GB.js
index 78d7e3818ae..f6b0f73ef0a 100644
--- a/lib/l10n/cy_GB.js
+++ b/lib/l10n/cy_GB.js
@@ -60,9 +60,6 @@ OC.L10N.register(
"Authentication error" : "Gwall dilysu",
"Token expired. Please reload page." : "Tocyn wedi dod i ben. Ail-lwythwch y dudalen.",
"Summary" : "Crynodeb",
- "Translate" : "Cyfieithu",
- "Users" : "Defnyddwyr",
- "Open »%s«" : "Agor »%s«",
- "Click the button below to open it." : "Cliciwch ar y botwm isod i'w agor."
+ "Translate" : "Cyfieithu"
},
"nplurals=4; plural=(n==1) ? 0 : (n==2) ? 1 : (n != 8 && n != 11) ? 2 : 3;");
diff --git a/lib/l10n/cy_GB.json b/lib/l10n/cy_GB.json
index 81fc666cfb6..d3ba0eeaa82 100644
--- a/lib/l10n/cy_GB.json
+++ b/lib/l10n/cy_GB.json
@@ -58,9 +58,6 @@
"Authentication error" : "Gwall dilysu",
"Token expired. Please reload page." : "Tocyn wedi dod i ben. Ail-lwythwch y dudalen.",
"Summary" : "Crynodeb",
- "Translate" : "Cyfieithu",
- "Users" : "Defnyddwyr",
- "Open »%s«" : "Agor »%s«",
- "Click the button below to open it." : "Cliciwch ar y botwm isod i'w agor."
+ "Translate" : "Cyfieithu"
},"pluralForm" :"nplurals=4; plural=(n==1) ? 0 : (n==2) ? 1 : (n != 8 && n != 11) ? 2 : 3;"
} \ No newline at end of file
diff --git a/lib/l10n/da.js b/lib/l10n/da.js
index 05e77f8d59e..e1ed6d62bcd 100644
--- a/lib/l10n/da.js
+++ b/lib/l10n/da.js
@@ -273,7 +273,6 @@ OC.L10N.register(
"A valid Login must be provided" : "Et gyldigt login skal angives",
"Login contains whitespace at the beginning or at the end" : "Login indeholder mellemrum i begyndelsen eller slutningen",
"Login must not consist of dots only" : "Login må ikke kun bestå af prikker",
- "Login is too long" : "Login er for lang",
"Login is invalid because files already exist for this user" : "Login er ugyldigt, fordi filer allerede eksisterer for denne bruger",
"Account disabled" : "Konto deaktiveret",
"Login canceled by app" : "Login annulleret af app",
@@ -443,20 +442,8 @@ OC.L10N.register(
"Generate headline" : "Generer overskrift",
"Summarizes text by reducing its length without losing key information." : "Opsummerer tekst ved at reducere dens længde uden at miste nøgleinformation.",
"Extracts topics from a text and outputs them separated by commas." : "Uddrager emner fra en tekst og skriver dem adskilt af kommaer.",
- "Education Edition" : "Uddanelses Version",
- "File name is a reserved word" : "Filnavnet er et reserveret ord",
- "File name contains at least one invalid character" : "Filnavnet indeholder mindst et ugyldigt tegn",
- "File name is too long" : "Filnavnet er for langt",
- "Users" : "Brugere",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s delte »%2$s« med dig og vil gerne tilføje:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s delte »%2$s« med dig og vil gerne tilføje",
- "»%s« added a note to a file shared with you" : "»%s« tilføjede en note til en fil delt med dig",
- "Open »%s«" : "Åbn »%s«",
- "%1$s shared »%2$s« with you" : "%1$s delte »%2$s« med dig",
- "%1$s shared »%2$s« with you." : "%1$s delte »%2$s« med dig",
- "Click the button below to open it." : "Klik på knappen nedenunder for at åbne.",
"File is currently busy, please try again later" : "Filen er i øjeblikket optaget - forsøg igen senere",
"Cannot download file" : "Kan ikke downloade filen",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Du bedes sikre at filen \".ocdata\" befinder sig i roden af din datamappe."
+ "Login is too long" : "Login er for lang"
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/da.json b/lib/l10n/da.json
index 107ff24a9fb..36bd40121d8 100644
--- a/lib/l10n/da.json
+++ b/lib/l10n/da.json
@@ -271,7 +271,6 @@
"A valid Login must be provided" : "Et gyldigt login skal angives",
"Login contains whitespace at the beginning or at the end" : "Login indeholder mellemrum i begyndelsen eller slutningen",
"Login must not consist of dots only" : "Login må ikke kun bestå af prikker",
- "Login is too long" : "Login er for lang",
"Login is invalid because files already exist for this user" : "Login er ugyldigt, fordi filer allerede eksisterer for denne bruger",
"Account disabled" : "Konto deaktiveret",
"Login canceled by app" : "Login annulleret af app",
@@ -441,20 +440,8 @@
"Generate headline" : "Generer overskrift",
"Summarizes text by reducing its length without losing key information." : "Opsummerer tekst ved at reducere dens længde uden at miste nøgleinformation.",
"Extracts topics from a text and outputs them separated by commas." : "Uddrager emner fra en tekst og skriver dem adskilt af kommaer.",
- "Education Edition" : "Uddanelses Version",
- "File name is a reserved word" : "Filnavnet er et reserveret ord",
- "File name contains at least one invalid character" : "Filnavnet indeholder mindst et ugyldigt tegn",
- "File name is too long" : "Filnavnet er for langt",
- "Users" : "Brugere",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s delte »%2$s« med dig og vil gerne tilføje:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s delte »%2$s« med dig og vil gerne tilføje",
- "»%s« added a note to a file shared with you" : "»%s« tilføjede en note til en fil delt med dig",
- "Open »%s«" : "Åbn »%s«",
- "%1$s shared »%2$s« with you" : "%1$s delte »%2$s« med dig",
- "%1$s shared »%2$s« with you." : "%1$s delte »%2$s« med dig",
- "Click the button below to open it." : "Klik på knappen nedenunder for at åbne.",
"File is currently busy, please try again later" : "Filen er i øjeblikket optaget - forsøg igen senere",
"Cannot download file" : "Kan ikke downloade filen",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Du bedes sikre at filen \".ocdata\" befinder sig i roden af din datamappe."
+ "Login is too long" : "Login er for lang"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/de.js b/lib/l10n/de.js
index 565432632e8..d1090a1d341 100644
--- a/lib/l10n/de.js
+++ b/lib/l10n/de.js
@@ -93,6 +93,8 @@ OC.L10N.register(
"Destination does not exist" : "Ziel existiert nicht",
"Destination is not creatable" : "Ziel kann nicht erstellt werden",
"Dot files are not allowed" : "Dateinamen mit einem Punkt am Anfang sind nicht erlaubt",
+ "%1$s (renamed)" : "%1$s (umbenannt)",
+ "renamed file" : "Umbenannte Datei",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" ist ein unzulässiger Datei- oder Ordnername.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" ist ein unzulässiges Präfix für Datei- oder Ordnernamen.",
"\"%1$s\" is not allowed inside a file or folder name." : "\"%1$s\" ist in einem Datei- oder Ordnernamen unzulässig.",
@@ -101,7 +103,7 @@ OC.L10N.register(
"Invalid parent path" : "Ungültiger übergeordneter Pfad",
"File already exists" : "Datei bereits vorhanden",
"Invalid path" : "Ungültiger Pfad",
- "Failed to create file from template" : "Fehler beim Erstellen der Datei aus Vorlage",
+ "Failed to create file from template" : "Datei konnte nicht aus Vorlage erstellt werden",
"Templates" : "Vorlagen",
"Storage %s cannot be moved" : "Speicherplatz %s kann nicht verschoben werden",
"Moving a share (%s) into a shared folder is not allowed" : "Verschieben einer Freigabe (%s) in einen freigegebenen Ordner ist unzulässig",
@@ -120,10 +122,10 @@ OC.L10N.register(
"__language_name__" : "Deutsch (Persönlich: Du)",
"This is an automatically sent email, please do not reply." : "Dies ist eine automatisch gesendete E-Mail. Bitte antworte nicht auf diese E-Mail.",
"Help & privacy" : "Hilfe & Datenschutz",
- "Appearance and accessibility" : "Erscheinungsbild und Barrierefreiheit",
+ "Appearance and accessibility" : "Aussehen und Barrierefreiheit",
"Apps" : "Apps",
"Personal settings" : "Persönliche Einstellungen",
- "Administration settings" : "Verwaltungseinstellungen",
+ "Administration settings" : "Administrationseinstellungen",
"Settings" : "Einstellungen",
"Log out" : "Abmelden",
"Accounts" : "Konten",
@@ -273,7 +275,7 @@ OC.L10N.register(
"A valid Login must be provided" : "Ein gültiger Anmeldename muss eingegeben werden.",
"Login contains whitespace at the beginning or at the end" : "Anmeldename enthält Leerzeichen am Anfang oder am Ende",
"Login must not consist of dots only" : "Der Anmeldename darf nicht nur aus Punkten bestehen",
- "Login is too long" : "Die Anmeldung dauert zu lange",
+ "Username is too long" : "Benutzername ist zu lang",
"Login is invalid because files already exist for this user" : "Der Anmeldename ist ungültig, da bereits Dateien von diesem Konto existieren",
"Account disabled" : "Konto deaktiviert",
"Login canceled by app" : "Anmeldung durch die App abgebrochen",
@@ -364,6 +366,11 @@ OC.L10N.register(
"How many images to generate" : "Wie viele Bilder erstellt werden sollen",
"Output images" : "Ausgegebene Bilder",
"The generated images" : "Die erstellten Bilder",
+ "Generate speech" : "Sprache erstellen",
+ "Generate speech from a transcript" : "Sprache aus einem Transkript erstellen",
+ "Write transcript that you want the assistant to generate speech from" : "Schreibe ein Transkript, aus dem der Assistent Sprache erstellen soll",
+ "Output speech" : "Sprachausgabe",
+ "The generated speech" : "Die erstellte Sprache",
"Free text to text prompt" : "Freie Text-zu-Text-Eingabeaufforderung",
"Runs an arbitrary prompt through a language model that returns a reply" : "Führt eine beliebige Eingabeaufforderung mit einem Sprachmodell aus, das eine Antwort zurückgibt",
"Describe a task that you want the assistant to do or ask a question" : "Eine Aufgabe beschreiben, die der Assistent erledigen soll, oder eine Frage stellen",
@@ -443,20 +450,8 @@ OC.L10N.register(
"Generate headline" : "Überschrift erzeugen",
"Summarizes text by reducing its length without losing key information." : "Fasst Text zusammen, indem die Länge reduziert wird, ohne dass wichtige Informationen verloren gehen.",
"Extracts topics from a text and outputs them separated by commas." : "Extrahiert Themen aus einem Text und gibt sie durch Kommas getrennt aus.",
- "Education Edition" : "Bildungsausgabe",
- "File name is a reserved word" : "Der Dateiname ist ein reserviertes Wort",
- "File name contains at least one invalid character" : "Der Dateiname enthält mindestens ein ungültiges Zeichen",
- "File name is too long" : "Dateiname ist zu lang",
- "Users" : "Benutzer",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s hat »%2$s« mit dir geteilt und möchte folgendes hinzufügen:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$shat »%2$s« mit dir geteilt und möchte folgendes hinzufügen",
- "»%s« added a note to a file shared with you" : "»%s« hat eine Bemerkung zu einer mit dir geteilten Datei hinzugefügt",
- "Open »%s«" : "»%s« öffnen",
- "%1$s shared »%2$s« with you" : "%1$s hat »%2$s« mit dir geteilt",
- "%1$s shared »%2$s« with you." : "%1$s hat »%2$s« mit dir geteilt.",
- "Click the button below to open it." : "Klicke zum Öffnen auf die untere Schaltfläche.",
"File is currently busy, please try again later" : "Die Datei ist in Benutzung, bitte versuche es später noch einmal",
"Cannot download file" : "Datei kann nicht heruntergeladen werden.",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Stelle sicher, dass eine Datei \".ocdata\" im Wurzelverzeichnis des data-Verzeichnisses existiert."
+ "Login is too long" : "Die Anmeldung dauert zu lange"
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/de.json b/lib/l10n/de.json
index f9b01867ab0..1c5a9e52f3d 100644
--- a/lib/l10n/de.json
+++ b/lib/l10n/de.json
@@ -91,6 +91,8 @@
"Destination does not exist" : "Ziel existiert nicht",
"Destination is not creatable" : "Ziel kann nicht erstellt werden",
"Dot files are not allowed" : "Dateinamen mit einem Punkt am Anfang sind nicht erlaubt",
+ "%1$s (renamed)" : "%1$s (umbenannt)",
+ "renamed file" : "Umbenannte Datei",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" ist ein unzulässiger Datei- oder Ordnername.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" ist ein unzulässiges Präfix für Datei- oder Ordnernamen.",
"\"%1$s\" is not allowed inside a file or folder name." : "\"%1$s\" ist in einem Datei- oder Ordnernamen unzulässig.",
@@ -99,7 +101,7 @@
"Invalid parent path" : "Ungültiger übergeordneter Pfad",
"File already exists" : "Datei bereits vorhanden",
"Invalid path" : "Ungültiger Pfad",
- "Failed to create file from template" : "Fehler beim Erstellen der Datei aus Vorlage",
+ "Failed to create file from template" : "Datei konnte nicht aus Vorlage erstellt werden",
"Templates" : "Vorlagen",
"Storage %s cannot be moved" : "Speicherplatz %s kann nicht verschoben werden",
"Moving a share (%s) into a shared folder is not allowed" : "Verschieben einer Freigabe (%s) in einen freigegebenen Ordner ist unzulässig",
@@ -118,10 +120,10 @@
"__language_name__" : "Deutsch (Persönlich: Du)",
"This is an automatically sent email, please do not reply." : "Dies ist eine automatisch gesendete E-Mail. Bitte antworte nicht auf diese E-Mail.",
"Help & privacy" : "Hilfe & Datenschutz",
- "Appearance and accessibility" : "Erscheinungsbild und Barrierefreiheit",
+ "Appearance and accessibility" : "Aussehen und Barrierefreiheit",
"Apps" : "Apps",
"Personal settings" : "Persönliche Einstellungen",
- "Administration settings" : "Verwaltungseinstellungen",
+ "Administration settings" : "Administrationseinstellungen",
"Settings" : "Einstellungen",
"Log out" : "Abmelden",
"Accounts" : "Konten",
@@ -271,7 +273,7 @@
"A valid Login must be provided" : "Ein gültiger Anmeldename muss eingegeben werden.",
"Login contains whitespace at the beginning or at the end" : "Anmeldename enthält Leerzeichen am Anfang oder am Ende",
"Login must not consist of dots only" : "Der Anmeldename darf nicht nur aus Punkten bestehen",
- "Login is too long" : "Die Anmeldung dauert zu lange",
+ "Username is too long" : "Benutzername ist zu lang",
"Login is invalid because files already exist for this user" : "Der Anmeldename ist ungültig, da bereits Dateien von diesem Konto existieren",
"Account disabled" : "Konto deaktiviert",
"Login canceled by app" : "Anmeldung durch die App abgebrochen",
@@ -362,6 +364,11 @@
"How many images to generate" : "Wie viele Bilder erstellt werden sollen",
"Output images" : "Ausgegebene Bilder",
"The generated images" : "Die erstellten Bilder",
+ "Generate speech" : "Sprache erstellen",
+ "Generate speech from a transcript" : "Sprache aus einem Transkript erstellen",
+ "Write transcript that you want the assistant to generate speech from" : "Schreibe ein Transkript, aus dem der Assistent Sprache erstellen soll",
+ "Output speech" : "Sprachausgabe",
+ "The generated speech" : "Die erstellte Sprache",
"Free text to text prompt" : "Freie Text-zu-Text-Eingabeaufforderung",
"Runs an arbitrary prompt through a language model that returns a reply" : "Führt eine beliebige Eingabeaufforderung mit einem Sprachmodell aus, das eine Antwort zurückgibt",
"Describe a task that you want the assistant to do or ask a question" : "Eine Aufgabe beschreiben, die der Assistent erledigen soll, oder eine Frage stellen",
@@ -441,20 +448,8 @@
"Generate headline" : "Überschrift erzeugen",
"Summarizes text by reducing its length without losing key information." : "Fasst Text zusammen, indem die Länge reduziert wird, ohne dass wichtige Informationen verloren gehen.",
"Extracts topics from a text and outputs them separated by commas." : "Extrahiert Themen aus einem Text und gibt sie durch Kommas getrennt aus.",
- "Education Edition" : "Bildungsausgabe",
- "File name is a reserved word" : "Der Dateiname ist ein reserviertes Wort",
- "File name contains at least one invalid character" : "Der Dateiname enthält mindestens ein ungültiges Zeichen",
- "File name is too long" : "Dateiname ist zu lang",
- "Users" : "Benutzer",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s hat »%2$s« mit dir geteilt und möchte folgendes hinzufügen:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$shat »%2$s« mit dir geteilt und möchte folgendes hinzufügen",
- "»%s« added a note to a file shared with you" : "»%s« hat eine Bemerkung zu einer mit dir geteilten Datei hinzugefügt",
- "Open »%s«" : "»%s« öffnen",
- "%1$s shared »%2$s« with you" : "%1$s hat »%2$s« mit dir geteilt",
- "%1$s shared »%2$s« with you." : "%1$s hat »%2$s« mit dir geteilt.",
- "Click the button below to open it." : "Klicke zum Öffnen auf die untere Schaltfläche.",
"File is currently busy, please try again later" : "Die Datei ist in Benutzung, bitte versuche es später noch einmal",
"Cannot download file" : "Datei kann nicht heruntergeladen werden.",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Stelle sicher, dass eine Datei \".ocdata\" im Wurzelverzeichnis des data-Verzeichnisses existiert."
+ "Login is too long" : "Die Anmeldung dauert zu lange"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/de_DE.js b/lib/l10n/de_DE.js
index d43d052a549..d8599c0262f 100644
--- a/lib/l10n/de_DE.js
+++ b/lib/l10n/de_DE.js
@@ -12,7 +12,7 @@ OC.L10N.register(
"%s email verification" : "%s E-Mail-Überprüfung",
"Email verification" : "E-Mail-Überprüfung",
"Click the following button to confirm your email." : "Klicken Sie auf die folgende Schaltfläche, um Ihre E-Mail zu bestätigen.",
- "Click the following link to confirm your email." : "Auf den nachfolgenden Link klicken um Ihre E-Mail-Adresse zu bestätigen",
+ "Click the following link to confirm your email." : "Auf den nachfolgenden Link klicken, um Ihre E-Mail-Adresse zu bestätigen",
"Confirm your email" : "Ihre E-Mail-Adresse bestätigen",
"Other activities" : "Andere Aktivitäten",
"%1$s and %2$s" : "%1$s und %2$s",
@@ -93,6 +93,8 @@ OC.L10N.register(
"Destination does not exist" : "Ziel existiert nicht",
"Destination is not creatable" : "Ziel kann nicht erstellt werden",
"Dot files are not allowed" : "Dateinamen mit einem Punkt am Anfang sind nicht erlaubt",
+ "%1$s (renamed)" : "%1$s (umbenannt)",
+ "renamed file" : "Umbenannte Datei",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" ist ein verbotener Datei- oder Ordnername.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" ist ein verbotenes Präfix für Datei- oder Ordnernamen.",
"\"%1$s\" is not allowed inside a file or folder name." : "\"%1$s\" ist in einem Datei- oder Ordnernamen unzulässig.",
@@ -101,7 +103,7 @@ OC.L10N.register(
"Invalid parent path" : "Ungültiger übergeordneter Pfad",
"File already exists" : "Datei bereits vorhanden",
"Invalid path" : "Ungültiger Pfad",
- "Failed to create file from template" : "Fehler beim Erstellen der Datei aus Vorlage",
+ "Failed to create file from template" : "Datei konnte nicht aus Vorlage erstellt werden",
"Templates" : "Vorlagen",
"Storage %s cannot be moved" : "Speicherplatz %s kann nicht verschoben werden",
"Moving a share (%s) into a shared folder is not allowed" : "Verschieben einer Freigabe (%s) in einen freigegebenen Ordner ist unzulässig",
@@ -133,7 +135,7 @@ OC.L10N.register(
"View %s on the fediverse" : "Zeige %s auf dem Fediverse",
"Phone" : "Telefon",
"Call %s" : "%s anrufen",
- "Twitter" : "Twitter",
+ "Twitter" : "X",
"View %s on Twitter" : "%s auf Twitter anzeigen",
"Website" : "Webseite",
"Visit %s" : "%s besuchen",
@@ -273,7 +275,7 @@ OC.L10N.register(
"A valid Login must be provided" : "Ein gültiger Anmeldename muss angegeben werden.",
"Login contains whitespace at the beginning or at the end" : "Anmeldename enthält Leerzeichen am Anfang oder am Ende",
"Login must not consist of dots only" : "Der Anmeldename darf nicht nur aus Punkten bestehen",
- "Login is too long" : "Die Anmeldung dauert zu lange",
+ "Username is too long" : "Benutzername ist zu lang",
"Login is invalid because files already exist for this user" : "Der Anmeldename ist ungültig, da bereits Dateien von diesem Benutzer existieren",
"Account disabled" : "Konto deaktiviert",
"Login canceled by app" : "Anmeldung durch die App abgebrochen",
@@ -313,7 +315,7 @@ OC.L10N.register(
"Your data directory is invalid." : "Ihr Datenverzeichnis ist ungültig.",
"Ensure there is a file called \"%1$s\" in the root of the data directory. It should have the content: \"%2$s\"" : "Stellen Sie sicher, dass eine Datei \"%1$s\" im Wurzelverzeichnis des Datenverzeichnisses existiert. Sie sollte folgenden Inhalt haben: \"%2$s\"",
"Action \"%s\" not supported or implemented." : "Aktion \"%s\" wird nicht unterstützt oder ist nicht implementiert.",
- "Authentication failed, wrong token or provider ID given" : "Authentifizierung ist fehlgeschlagen. Falsches Token oder Provider-ID wurde übertragen.",
+ "Authentication failed, wrong token or provider ID given" : "Authentifizierung fehlgeschlagen, falsches Token oder falsche Provider-ID angegeben",
"Parameters missing in order to complete the request. Missing Parameters: \"%s\"" : "Es fehlen Parameter um die Anfrage zu bearbeiten. Fehlende Parameter: \"%s\"",
"ID \"%1$s\" already used by cloud federation provider \"%2$s\"" : "ID \"%1$s\" wird bereits von Cloud-Federation-Provider \"%2$s\" verwendet.",
"Cloud Federation Provider with ID: \"%s\" does not exist." : "Cloud-Federation-Provider mit ID: \"%s\" ist nicht vorhanden.",
@@ -364,6 +366,11 @@ OC.L10N.register(
"How many images to generate" : "Wie viele Bilder erstellt werden sollen",
"Output images" : "Ausgegebene Bilder",
"The generated images" : "Die erstellten Bilder",
+ "Generate speech" : "Sprache erstellen",
+ "Generate speech from a transcript" : "Sprache aus einem Transkript erstellen",
+ "Write transcript that you want the assistant to generate speech from" : "Schreiben Sie ein Transkript, aus dem der Assistent Sprache erstellen soll",
+ "Output speech" : "Sprachausgabe",
+ "The generated speech" : "Die erstellte Sprache",
"Free text to text prompt" : "Freie Text-zu-Text-Eingabeaufforderung",
"Runs an arbitrary prompt through a language model that returns a reply" : "Führt eine beliebige Eingabeaufforderung mit einem Sprachmodell aus, das eine Antwort zurückgibt",
"Describe a task that you want the assistant to do or ask a question" : "Beschreiben Sie eine Aufgabe, die der Assistent erledigen soll, oder stellen Sie eine Frage",
@@ -443,20 +450,8 @@ OC.L10N.register(
"Generate headline" : "Kopfzeile erzeugen",
"Summarizes text by reducing its length without losing key information." : "Fasst Text zusammen, indem die Länge reduziert wird, ohne dass wichtige Informationen verloren gehen.",
"Extracts topics from a text and outputs them separated by commas." : "Extrahiert Themen aus einem Text und gibt sie durch Kommas getrennt aus.",
- "Education Edition" : "Bildungsausgabe",
- "File name is a reserved word" : "Der Dateiname ist ein reserviertes Wort",
- "File name contains at least one invalid character" : "Der Dateiname enthält mindestens ein ungültiges Zeichen",
- "File name is too long" : "Dateiname ist zu lang",
- "Users" : "Benutzer",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s hat »%2$s« mit Ihnen geteilt und möchte folgendes hinzufügen:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s hat »%2$s« mit Ihnen geteilt und möchte folgendes hinzufügen",
- "»%s« added a note to a file shared with you" : "»%s« hat eine Bemerkung zu einer mit Ihnen geteilten Datei hinzugefügt",
- "Open »%s«" : "»%s« öffnen",
- "%1$s shared »%2$s« with you" : "%1$s hat »%2$s« mit Ihnen geteilt",
- "%1$s shared »%2$s« with you." : "%1$s hat »%2$s« mit Ihnen geteilt.",
- "Click the button below to open it." : "Klicken Sie zum Öffnen auf die untere Schaltfläche.",
"File is currently busy, please try again later" : "Die Datei ist in Benutzung, bitte später erneut versuchen.",
"Cannot download file" : "Datei kann nicht heruntergeladen werden",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Stellen Sie sicher, dass eine Datei \".ocdata\" im Wurzelverzeichnis des Datenverzeichnisses existiert."
+ "Login is too long" : "Der Kontenname ist zu lang"
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/de_DE.json b/lib/l10n/de_DE.json
index 9e974ad5fac..5149f3f2d97 100644
--- a/lib/l10n/de_DE.json
+++ b/lib/l10n/de_DE.json
@@ -10,7 +10,7 @@
"%s email verification" : "%s E-Mail-Überprüfung",
"Email verification" : "E-Mail-Überprüfung",
"Click the following button to confirm your email." : "Klicken Sie auf die folgende Schaltfläche, um Ihre E-Mail zu bestätigen.",
- "Click the following link to confirm your email." : "Auf den nachfolgenden Link klicken um Ihre E-Mail-Adresse zu bestätigen",
+ "Click the following link to confirm your email." : "Auf den nachfolgenden Link klicken, um Ihre E-Mail-Adresse zu bestätigen",
"Confirm your email" : "Ihre E-Mail-Adresse bestätigen",
"Other activities" : "Andere Aktivitäten",
"%1$s and %2$s" : "%1$s und %2$s",
@@ -91,6 +91,8 @@
"Destination does not exist" : "Ziel existiert nicht",
"Destination is not creatable" : "Ziel kann nicht erstellt werden",
"Dot files are not allowed" : "Dateinamen mit einem Punkt am Anfang sind nicht erlaubt",
+ "%1$s (renamed)" : "%1$s (umbenannt)",
+ "renamed file" : "Umbenannte Datei",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" ist ein verbotener Datei- oder Ordnername.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" ist ein verbotenes Präfix für Datei- oder Ordnernamen.",
"\"%1$s\" is not allowed inside a file or folder name." : "\"%1$s\" ist in einem Datei- oder Ordnernamen unzulässig.",
@@ -99,7 +101,7 @@
"Invalid parent path" : "Ungültiger übergeordneter Pfad",
"File already exists" : "Datei bereits vorhanden",
"Invalid path" : "Ungültiger Pfad",
- "Failed to create file from template" : "Fehler beim Erstellen der Datei aus Vorlage",
+ "Failed to create file from template" : "Datei konnte nicht aus Vorlage erstellt werden",
"Templates" : "Vorlagen",
"Storage %s cannot be moved" : "Speicherplatz %s kann nicht verschoben werden",
"Moving a share (%s) into a shared folder is not allowed" : "Verschieben einer Freigabe (%s) in einen freigegebenen Ordner ist unzulässig",
@@ -131,7 +133,7 @@
"View %s on the fediverse" : "Zeige %s auf dem Fediverse",
"Phone" : "Telefon",
"Call %s" : "%s anrufen",
- "Twitter" : "Twitter",
+ "Twitter" : "X",
"View %s on Twitter" : "%s auf Twitter anzeigen",
"Website" : "Webseite",
"Visit %s" : "%s besuchen",
@@ -271,7 +273,7 @@
"A valid Login must be provided" : "Ein gültiger Anmeldename muss angegeben werden.",
"Login contains whitespace at the beginning or at the end" : "Anmeldename enthält Leerzeichen am Anfang oder am Ende",
"Login must not consist of dots only" : "Der Anmeldename darf nicht nur aus Punkten bestehen",
- "Login is too long" : "Die Anmeldung dauert zu lange",
+ "Username is too long" : "Benutzername ist zu lang",
"Login is invalid because files already exist for this user" : "Der Anmeldename ist ungültig, da bereits Dateien von diesem Benutzer existieren",
"Account disabled" : "Konto deaktiviert",
"Login canceled by app" : "Anmeldung durch die App abgebrochen",
@@ -311,7 +313,7 @@
"Your data directory is invalid." : "Ihr Datenverzeichnis ist ungültig.",
"Ensure there is a file called \"%1$s\" in the root of the data directory. It should have the content: \"%2$s\"" : "Stellen Sie sicher, dass eine Datei \"%1$s\" im Wurzelverzeichnis des Datenverzeichnisses existiert. Sie sollte folgenden Inhalt haben: \"%2$s\"",
"Action \"%s\" not supported or implemented." : "Aktion \"%s\" wird nicht unterstützt oder ist nicht implementiert.",
- "Authentication failed, wrong token or provider ID given" : "Authentifizierung ist fehlgeschlagen. Falsches Token oder Provider-ID wurde übertragen.",
+ "Authentication failed, wrong token or provider ID given" : "Authentifizierung fehlgeschlagen, falsches Token oder falsche Provider-ID angegeben",
"Parameters missing in order to complete the request. Missing Parameters: \"%s\"" : "Es fehlen Parameter um die Anfrage zu bearbeiten. Fehlende Parameter: \"%s\"",
"ID \"%1$s\" already used by cloud federation provider \"%2$s\"" : "ID \"%1$s\" wird bereits von Cloud-Federation-Provider \"%2$s\" verwendet.",
"Cloud Federation Provider with ID: \"%s\" does not exist." : "Cloud-Federation-Provider mit ID: \"%s\" ist nicht vorhanden.",
@@ -362,6 +364,11 @@
"How many images to generate" : "Wie viele Bilder erstellt werden sollen",
"Output images" : "Ausgegebene Bilder",
"The generated images" : "Die erstellten Bilder",
+ "Generate speech" : "Sprache erstellen",
+ "Generate speech from a transcript" : "Sprache aus einem Transkript erstellen",
+ "Write transcript that you want the assistant to generate speech from" : "Schreiben Sie ein Transkript, aus dem der Assistent Sprache erstellen soll",
+ "Output speech" : "Sprachausgabe",
+ "The generated speech" : "Die erstellte Sprache",
"Free text to text prompt" : "Freie Text-zu-Text-Eingabeaufforderung",
"Runs an arbitrary prompt through a language model that returns a reply" : "Führt eine beliebige Eingabeaufforderung mit einem Sprachmodell aus, das eine Antwort zurückgibt",
"Describe a task that you want the assistant to do or ask a question" : "Beschreiben Sie eine Aufgabe, die der Assistent erledigen soll, oder stellen Sie eine Frage",
@@ -441,20 +448,8 @@
"Generate headline" : "Kopfzeile erzeugen",
"Summarizes text by reducing its length without losing key information." : "Fasst Text zusammen, indem die Länge reduziert wird, ohne dass wichtige Informationen verloren gehen.",
"Extracts topics from a text and outputs them separated by commas." : "Extrahiert Themen aus einem Text und gibt sie durch Kommas getrennt aus.",
- "Education Edition" : "Bildungsausgabe",
- "File name is a reserved word" : "Der Dateiname ist ein reserviertes Wort",
- "File name contains at least one invalid character" : "Der Dateiname enthält mindestens ein ungültiges Zeichen",
- "File name is too long" : "Dateiname ist zu lang",
- "Users" : "Benutzer",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s hat »%2$s« mit Ihnen geteilt und möchte folgendes hinzufügen:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s hat »%2$s« mit Ihnen geteilt und möchte folgendes hinzufügen",
- "»%s« added a note to a file shared with you" : "»%s« hat eine Bemerkung zu einer mit Ihnen geteilten Datei hinzugefügt",
- "Open »%s«" : "»%s« öffnen",
- "%1$s shared »%2$s« with you" : "%1$s hat »%2$s« mit Ihnen geteilt",
- "%1$s shared »%2$s« with you." : "%1$s hat »%2$s« mit Ihnen geteilt.",
- "Click the button below to open it." : "Klicken Sie zum Öffnen auf die untere Schaltfläche.",
"File is currently busy, please try again later" : "Die Datei ist in Benutzung, bitte später erneut versuchen.",
"Cannot download file" : "Datei kann nicht heruntergeladen werden",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Stellen Sie sicher, dass eine Datei \".ocdata\" im Wurzelverzeichnis des Datenverzeichnisses existiert."
+ "Login is too long" : "Der Kontenname ist zu lang"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/el.js b/lib/l10n/el.js
index d875b0e0be4..677e1364147 100644
--- a/lib/l10n/el.js
+++ b/lib/l10n/el.js
@@ -233,20 +233,7 @@ OC.L10N.register(
"Summary" : "Σύνοψη",
"Translate" : "Μετάφραση",
"Result" : "Αποτέλεσμα",
- "Education Edition" : "Εκπαιδευτική Έκδοση",
- "File name is a reserved word" : "Το όνομα αρχείου είναι λέξη που έχει δεσμευτεί",
- "File name contains at least one invalid character" : "Το όνομα αρχείου περιέχει έναν τουλάχιστον μη έγκυρο χαρακτήρα",
- "File name is too long" : "Το όνομα αρχείου είναι πολύ μεγάλο",
- "Users" : "Χρήστες",
- "%1$s shared »%2$s« with you and wants to add:" : "Ο %1$s διαμοιράστηκε το »%2$s« με εσάς και θέλει να προσθέσει:",
- "%1$s shared »%2$s« with you and wants to add" : "Ο %1$s διαμοιράστηκε το »%2$s« με εσάς και θέλει να προσθέσει",
- "»%s« added a note to a file shared with you" : "Ο »%s« πρόσθεσε μια σημείωση στο κοινόχρηστο αρχείο",
- "Open »%s«" : "Άνοιγμα »%s«",
- "%1$s shared »%2$s« with you" : "Ο/η %1$s διαμοιράστηκε το »%2$s« με εσάς.",
- "%1$s shared »%2$s« with you." : "Ο/η %1$s διαμοιράστηκε »%2$s« με εσάς.",
- "Click the button below to open it." : "Κάντε κλικ στο παρακάτω κουμπί για να το ανοίξετε.",
"File is currently busy, please try again later" : "Το αρχείο χρησιμοποιείται αυτή τη στιγμή, παρακαλούμε προσπαθήστε αργότερα",
- "Cannot download file" : "Δεν είναι δυνατή η λήψη του αρχείου",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Εξασφαλίστε ότι υπάρχει ένα αρχείο με όνομα \".ocdata\" στον βασικό κατάλογο του καταλόγου δεδομένων."
+ "Cannot download file" : "Δεν είναι δυνατή η λήψη του αρχείου"
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/el.json b/lib/l10n/el.json
index b983a325f2d..70f34db9a55 100644
--- a/lib/l10n/el.json
+++ b/lib/l10n/el.json
@@ -231,20 +231,7 @@
"Summary" : "Σύνοψη",
"Translate" : "Μετάφραση",
"Result" : "Αποτέλεσμα",
- "Education Edition" : "Εκπαιδευτική Έκδοση",
- "File name is a reserved word" : "Το όνομα αρχείου είναι λέξη που έχει δεσμευτεί",
- "File name contains at least one invalid character" : "Το όνομα αρχείου περιέχει έναν τουλάχιστον μη έγκυρο χαρακτήρα",
- "File name is too long" : "Το όνομα αρχείου είναι πολύ μεγάλο",
- "Users" : "Χρήστες",
- "%1$s shared »%2$s« with you and wants to add:" : "Ο %1$s διαμοιράστηκε το »%2$s« με εσάς και θέλει να προσθέσει:",
- "%1$s shared »%2$s« with you and wants to add" : "Ο %1$s διαμοιράστηκε το »%2$s« με εσάς και θέλει να προσθέσει",
- "»%s« added a note to a file shared with you" : "Ο »%s« πρόσθεσε μια σημείωση στο κοινόχρηστο αρχείο",
- "Open »%s«" : "Άνοιγμα »%s«",
- "%1$s shared »%2$s« with you" : "Ο/η %1$s διαμοιράστηκε το »%2$s« με εσάς.",
- "%1$s shared »%2$s« with you." : "Ο/η %1$s διαμοιράστηκε »%2$s« με εσάς.",
- "Click the button below to open it." : "Κάντε κλικ στο παρακάτω κουμπί για να το ανοίξετε.",
"File is currently busy, please try again later" : "Το αρχείο χρησιμοποιείται αυτή τη στιγμή, παρακαλούμε προσπαθήστε αργότερα",
- "Cannot download file" : "Δεν είναι δυνατή η λήψη του αρχείου",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Εξασφαλίστε ότι υπάρχει ένα αρχείο με όνομα \".ocdata\" στον βασικό κατάλογο του καταλόγου δεδομένων."
+ "Cannot download file" : "Δεν είναι δυνατή η λήψη του αρχείου"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/en_GB.js b/lib/l10n/en_GB.js
index 93782960c94..b1a73cec9ad 100644
--- a/lib/l10n/en_GB.js
+++ b/lib/l10n/en_GB.js
@@ -93,6 +93,8 @@ OC.L10N.register(
"Destination does not exist" : "Destination does not exist",
"Destination is not creatable" : "Destination is not creatable",
"Dot files are not allowed" : "Dot files are not allowed",
+ "%1$s (renamed)" : "%1$s (renamed)",
+ "renamed file" : "renamed file",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" is a forbidden file or folder name.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" is a forbidden prefix for file or folder names.",
"\"%1$s\" is not allowed inside a file or folder name." : "\"%1$s\" is not allowed inside a file or folder name.",
@@ -201,6 +203,7 @@ OC.L10N.register(
"Path is already shared with this group" : "Path is already shared with this group",
"Link sharing is not allowed" : "Link sharing is not allowed",
"Public upload is not allowed" : "Public upload is not allowed",
+ "You cannot share a folder that contains other shares" : "You cannot share a folder that contains other shares",
"Sharing is disabled" : "Sharing is disabled",
"Sharing is disabled for you" : "Sharing is disabled for you",
"Cannot share with the share owner" : "Cannot share with the share owner",
@@ -272,6 +275,7 @@ OC.L10N.register(
"A valid Login must be provided" : "A valid Login must be provided",
"Login contains whitespace at the beginning or at the end" : "Login contains whitespace at the beginning or at the end",
"Login must not consist of dots only" : "Login must not consist of dots only",
+ "Username is too long" : "Username is too long",
"Login is invalid because files already exist for this user" : "Login is invalid because files already exist for this user",
"Account disabled" : "Account disabled",
"Login canceled by app" : "Login cancelled by app",
@@ -362,6 +366,11 @@ OC.L10N.register(
"How many images to generate" : "How many images to generate",
"Output images" : "Output images",
"The generated images" : "The generated images",
+ "Generate speech" : "Generate speech",
+ "Generate speech from a transcript" : "Generate speech from a transcript",
+ "Write transcript that you want the assistant to generate speech from" : "Write transcript that you want the assistant to generate speech from",
+ "Output speech" : "Output speech",
+ "The generated speech" : "The generated speech",
"Free text to text prompt" : "Free text to text prompt",
"Runs an arbitrary prompt through a language model that returns a reply" : "Runs an arbitrary prompt through a language model that returns a reply",
"Describe a task that you want the assistant to do or ask a question" : "Describe a task that you want the assistant to do or ask a question",
@@ -441,20 +450,8 @@ OC.L10N.register(
"Generate headline" : "Generate headline",
"Summarizes text by reducing its length without losing key information." : "Summarizes text by reducing its length without losing key information.",
"Extracts topics from a text and outputs them separated by commas." : "Extracts topics from a text and outputs them separated by commas.",
- "Education Edition" : "Education Edition",
- "File name is a reserved word" : "File name is a reserved word",
- "File name contains at least one invalid character" : "File name contains at least one invalid character",
- "File name is too long" : "File name is too long",
- "Users" : "Users",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s shared »%2$s« with you and wants to add:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s shared »%2$s« with you and wants to add",
- "»%s« added a note to a file shared with you" : "»%s« added a note to a file shared with you",
- "Open »%s«" : "Open »%s«",
- "%1$s shared »%2$s« with you" : "%1$s shared »%2$s« with you",
- "%1$s shared »%2$s« with you." : "%1$s shared »%2$s« with you.",
- "Click the button below to open it." : "Click the button below to open it.",
"File is currently busy, please try again later" : "File is currently busy, please try again later",
"Cannot download file" : "Cannot download file",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Ensure there is a file called \".ocdata\" in the root of the data directory."
+ "Login is too long" : "Login is too long"
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/en_GB.json b/lib/l10n/en_GB.json
index 40402118ddf..fb477ccbca3 100644
--- a/lib/l10n/en_GB.json
+++ b/lib/l10n/en_GB.json
@@ -91,6 +91,8 @@
"Destination does not exist" : "Destination does not exist",
"Destination is not creatable" : "Destination is not creatable",
"Dot files are not allowed" : "Dot files are not allowed",
+ "%1$s (renamed)" : "%1$s (renamed)",
+ "renamed file" : "renamed file",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" is a forbidden file or folder name.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" is a forbidden prefix for file or folder names.",
"\"%1$s\" is not allowed inside a file or folder name." : "\"%1$s\" is not allowed inside a file or folder name.",
@@ -199,6 +201,7 @@
"Path is already shared with this group" : "Path is already shared with this group",
"Link sharing is not allowed" : "Link sharing is not allowed",
"Public upload is not allowed" : "Public upload is not allowed",
+ "You cannot share a folder that contains other shares" : "You cannot share a folder that contains other shares",
"Sharing is disabled" : "Sharing is disabled",
"Sharing is disabled for you" : "Sharing is disabled for you",
"Cannot share with the share owner" : "Cannot share with the share owner",
@@ -270,6 +273,7 @@
"A valid Login must be provided" : "A valid Login must be provided",
"Login contains whitespace at the beginning or at the end" : "Login contains whitespace at the beginning or at the end",
"Login must not consist of dots only" : "Login must not consist of dots only",
+ "Username is too long" : "Username is too long",
"Login is invalid because files already exist for this user" : "Login is invalid because files already exist for this user",
"Account disabled" : "Account disabled",
"Login canceled by app" : "Login cancelled by app",
@@ -360,6 +364,11 @@
"How many images to generate" : "How many images to generate",
"Output images" : "Output images",
"The generated images" : "The generated images",
+ "Generate speech" : "Generate speech",
+ "Generate speech from a transcript" : "Generate speech from a transcript",
+ "Write transcript that you want the assistant to generate speech from" : "Write transcript that you want the assistant to generate speech from",
+ "Output speech" : "Output speech",
+ "The generated speech" : "The generated speech",
"Free text to text prompt" : "Free text to text prompt",
"Runs an arbitrary prompt through a language model that returns a reply" : "Runs an arbitrary prompt through a language model that returns a reply",
"Describe a task that you want the assistant to do or ask a question" : "Describe a task that you want the assistant to do or ask a question",
@@ -439,20 +448,8 @@
"Generate headline" : "Generate headline",
"Summarizes text by reducing its length without losing key information." : "Summarizes text by reducing its length without losing key information.",
"Extracts topics from a text and outputs them separated by commas." : "Extracts topics from a text and outputs them separated by commas.",
- "Education Edition" : "Education Edition",
- "File name is a reserved word" : "File name is a reserved word",
- "File name contains at least one invalid character" : "File name contains at least one invalid character",
- "File name is too long" : "File name is too long",
- "Users" : "Users",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s shared »%2$s« with you and wants to add:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s shared »%2$s« with you and wants to add",
- "»%s« added a note to a file shared with you" : "»%s« added a note to a file shared with you",
- "Open »%s«" : "Open »%s«",
- "%1$s shared »%2$s« with you" : "%1$s shared »%2$s« with you",
- "%1$s shared »%2$s« with you." : "%1$s shared »%2$s« with you.",
- "Click the button below to open it." : "Click the button below to open it.",
"File is currently busy, please try again later" : "File is currently busy, please try again later",
"Cannot download file" : "Cannot download file",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Ensure there is a file called \".ocdata\" in the root of the data directory."
+ "Login is too long" : "Login is too long"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/eo.js b/lib/l10n/eo.js
index f936a008bec..0a8215b9a63 100644
--- a/lib/l10n/eo.js
+++ b/lib/l10n/eo.js
@@ -180,19 +180,6 @@ OC.L10N.register(
"Text" : "Teksto",
"Summary" : "Resumo",
"Translate" : "Traduku",
- "Education Edition" : "Eldono por edukado",
- "File name is a reserved word" : "Dosiernomo estas rezervita vorto",
- "File name contains at least one invalid character" : "Dosiernomo enhavas almenaŭ unu nevalidan signon",
- "File name is too long" : "La dosiernomo estas tro longa",
- "Users" : "Uzantoj",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s kunhavigis „%2$s“ kun vi kaj volas aldoni:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s kunhavigis „%2$s“ kun vi kaj volas aldoni",
- "»%s« added a note to a file shared with you" : "„%s“ aldonis noton al dosiero kunhavigita kun vi",
- "Open »%s«" : "Malfermi „%s“",
- "%1$s shared »%2$s« with you" : "%1$s kunhavigis „%2$s“ kun vi",
- "%1$s shared »%2$s« with you." : "%1$s kunhavigis „%2$s“ kun vi.",
- "Click the button below to open it." : "Alklaku la butonon ĉi-sube por malfermi ĝin.",
- "File is currently busy, please try again later" : "La dosiero estas nun okupita, bv. reprovi poste",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Certigu, ke estas dosiero nomata „.ocdata“ en la radiko de la dosierujo de datumoj."
+ "File is currently busy, please try again later" : "La dosiero estas nun okupita, bv. reprovi poste"
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/eo.json b/lib/l10n/eo.json
index 468cc2e49dd..d9b2a1ede87 100644
--- a/lib/l10n/eo.json
+++ b/lib/l10n/eo.json
@@ -178,19 +178,6 @@
"Text" : "Teksto",
"Summary" : "Resumo",
"Translate" : "Traduku",
- "Education Edition" : "Eldono por edukado",
- "File name is a reserved word" : "Dosiernomo estas rezervita vorto",
- "File name contains at least one invalid character" : "Dosiernomo enhavas almenaŭ unu nevalidan signon",
- "File name is too long" : "La dosiernomo estas tro longa",
- "Users" : "Uzantoj",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s kunhavigis „%2$s“ kun vi kaj volas aldoni:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s kunhavigis „%2$s“ kun vi kaj volas aldoni",
- "»%s« added a note to a file shared with you" : "„%s“ aldonis noton al dosiero kunhavigita kun vi",
- "Open »%s«" : "Malfermi „%s“",
- "%1$s shared »%2$s« with you" : "%1$s kunhavigis „%2$s“ kun vi",
- "%1$s shared »%2$s« with you." : "%1$s kunhavigis „%2$s“ kun vi.",
- "Click the button below to open it." : "Alklaku la butonon ĉi-sube por malfermi ĝin.",
- "File is currently busy, please try again later" : "La dosiero estas nun okupita, bv. reprovi poste",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Certigu, ke estas dosiero nomata „.ocdata“ en la radiko de la dosierujo de datumoj."
+ "File is currently busy, please try again later" : "La dosiero estas nun okupita, bv. reprovi poste"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/es.js b/lib/l10n/es.js
index 94e52dbc724..f53ec599a0b 100644
--- a/lib/l10n/es.js
+++ b/lib/l10n/es.js
@@ -93,6 +93,8 @@ OC.L10N.register(
"Destination does not exist" : "El destino no existe",
"Destination is not creatable" : "El destino no se puede crear",
"Dot files are not allowed" : "Los archivos Dot no están permitidos",
+ "%1$s (renamed)" : "%1$s (renombrado)",
+ "renamed file" : "archivo renombrado",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" Es un nombre de archivo o carpeta no permitido.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "%1$s es un prefijo prohibido para nombres de archivo o carpeta.",
"\"%1$s\" is not allowed inside a file or folder name." : "«%1$s» no se permite en el nombre de un archivo o carpeta.",
@@ -273,7 +275,6 @@ OC.L10N.register(
"A valid Login must be provided" : "Se debe proporcionar un usuario válido",
"Login contains whitespace at the beginning or at the end" : "El usuario contiene espacios en blanco al inicio o al final",
"Login must not consist of dots only" : "El usuario no debe consistir sólo de puntos",
- "Login is too long" : "El nombre de inicio de sesión es demasiado largo",
"Login is invalid because files already exist for this user" : "El nombre de inicio de sesión es inválido porque ya existen archivos para este usuario",
"Account disabled" : "Cuenta deshabilitada",
"Login canceled by app" : "Login cancelado por la app",
@@ -364,6 +365,11 @@ OC.L10N.register(
"How many images to generate" : "Cuántas imágenes se generarán",
"Output images" : "Imágenes de salida",
"The generated images" : "Las imágenes generadas",
+ "Generate speech" : "Generar dictado",
+ "Generate speech from a transcript" : "Generar dictado desde una transcripción",
+ "Write transcript that you want the assistant to generate speech from" : "Escriba la transcripción desde la que desea que el asistente genere un dictado",
+ "Output speech" : "Dictado de salida",
+ "The generated speech" : "El dictado generado",
"Free text to text prompt" : "Texto libre a prompt de texto",
"Runs an arbitrary prompt through a language model that returns a reply" : "Ejecuta un prompt arbitrario a través de un modelo de lenguaje que retorna una respuesta",
"Describe a task that you want the assistant to do or ask a question" : "Describa una tarea que quiere que el asistente realice, o, haga una pregunta",
@@ -443,20 +449,8 @@ OC.L10N.register(
"Generate headline" : "Generar titular",
"Summarizes text by reducing its length without losing key information." : "Resume el texto reduciendo su longitud sin perder información clave.",
"Extracts topics from a text and outputs them separated by commas." : "Extrae los tópicos de un texto y genera una salida separada por comas. ",
- "Education Edition" : "Edición Educación",
- "File name is a reserved word" : "El nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un carácter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s ha compartido «%2$s» contigo y quiere añadir:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s ha compartido «%2$s» contigo y quiere añadir",
- "»%s« added a note to a file shared with you" : "«%s» ha añadido una nota a un archivo compartido contigo",
- "Open »%s«" : "Abrir »%s« ",
- "%1$s shared »%2$s« with you" : "%1$s ha compartido «%2$s» contigo",
- "%1$s shared »%2$s« with you." : "%1$s ha compartido «%2$s» contigo.",
- "Click the button below to open it." : "Haz clic en el botón de abajo para abrirlo.",
"File is currently busy, please try again later" : "El archivo se encuentra actualmente ocupado, por favor inténtelo de nuevo más tarde",
"Cannot download file" : "No se puede descargar el archivo",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegúrate de que existe un archivo llamado \".ocdata\" en la raíz del directorio de datos."
+ "Login is too long" : "El nombre de inicio de sesión es demasiado largo"
},
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/lib/l10n/es.json b/lib/l10n/es.json
index 61f519db2a7..a88b6c22513 100644
--- a/lib/l10n/es.json
+++ b/lib/l10n/es.json
@@ -91,6 +91,8 @@
"Destination does not exist" : "El destino no existe",
"Destination is not creatable" : "El destino no se puede crear",
"Dot files are not allowed" : "Los archivos Dot no están permitidos",
+ "%1$s (renamed)" : "%1$s (renombrado)",
+ "renamed file" : "archivo renombrado",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" Es un nombre de archivo o carpeta no permitido.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "%1$s es un prefijo prohibido para nombres de archivo o carpeta.",
"\"%1$s\" is not allowed inside a file or folder name." : "«%1$s» no se permite en el nombre de un archivo o carpeta.",
@@ -271,7 +273,6 @@
"A valid Login must be provided" : "Se debe proporcionar un usuario válido",
"Login contains whitespace at the beginning or at the end" : "El usuario contiene espacios en blanco al inicio o al final",
"Login must not consist of dots only" : "El usuario no debe consistir sólo de puntos",
- "Login is too long" : "El nombre de inicio de sesión es demasiado largo",
"Login is invalid because files already exist for this user" : "El nombre de inicio de sesión es inválido porque ya existen archivos para este usuario",
"Account disabled" : "Cuenta deshabilitada",
"Login canceled by app" : "Login cancelado por la app",
@@ -362,6 +363,11 @@
"How many images to generate" : "Cuántas imágenes se generarán",
"Output images" : "Imágenes de salida",
"The generated images" : "Las imágenes generadas",
+ "Generate speech" : "Generar dictado",
+ "Generate speech from a transcript" : "Generar dictado desde una transcripción",
+ "Write transcript that you want the assistant to generate speech from" : "Escriba la transcripción desde la que desea que el asistente genere un dictado",
+ "Output speech" : "Dictado de salida",
+ "The generated speech" : "El dictado generado",
"Free text to text prompt" : "Texto libre a prompt de texto",
"Runs an arbitrary prompt through a language model that returns a reply" : "Ejecuta un prompt arbitrario a través de un modelo de lenguaje que retorna una respuesta",
"Describe a task that you want the assistant to do or ask a question" : "Describa una tarea que quiere que el asistente realice, o, haga una pregunta",
@@ -441,20 +447,8 @@
"Generate headline" : "Generar titular",
"Summarizes text by reducing its length without losing key information." : "Resume el texto reduciendo su longitud sin perder información clave.",
"Extracts topics from a text and outputs them separated by commas." : "Extrae los tópicos de un texto y genera una salida separada por comas. ",
- "Education Edition" : "Edición Educación",
- "File name is a reserved word" : "El nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un carácter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s ha compartido «%2$s» contigo y quiere añadir:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s ha compartido «%2$s» contigo y quiere añadir",
- "»%s« added a note to a file shared with you" : "«%s» ha añadido una nota a un archivo compartido contigo",
- "Open »%s«" : "Abrir »%s« ",
- "%1$s shared »%2$s« with you" : "%1$s ha compartido «%2$s» contigo",
- "%1$s shared »%2$s« with you." : "%1$s ha compartido «%2$s» contigo.",
- "Click the button below to open it." : "Haz clic en el botón de abajo para abrirlo.",
"File is currently busy, please try again later" : "El archivo se encuentra actualmente ocupado, por favor inténtelo de nuevo más tarde",
"Cannot download file" : "No se puede descargar el archivo",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegúrate de que existe un archivo llamado \".ocdata\" en la raíz del directorio de datos."
+ "Login is too long" : "El nombre de inicio de sesión es demasiado largo"
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
} \ No newline at end of file
diff --git a/lib/l10n/es_419.js b/lib/l10n/es_419.js
index ca3089b5686..b29c699f2a1 100644
--- a/lib/l10n/es_419.js
+++ b/lib/l10n/es_419.js
@@ -148,14 +148,6 @@ OC.L10N.register(
"Summary" : "Resumen",
"Translate" : "Traducir",
"Result" : "Resultado",
- "Education Edition" : "Edición Educativa",
- "File name is a reserved word" : "Nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un caracter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "Open »%s«" : "Abrir »%s«",
- "Click the button below to open it." : "Haz click en el botón inferior para abrirlo. ",
- "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. ",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegurate de que exista una archivo llamado \".ocdata\" en la raíz del directorio de datos. "
+ "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. "
},
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/lib/l10n/es_419.json b/lib/l10n/es_419.json
index 0c7a0693512..63c2392e20c 100644
--- a/lib/l10n/es_419.json
+++ b/lib/l10n/es_419.json
@@ -146,14 +146,6 @@
"Summary" : "Resumen",
"Translate" : "Traducir",
"Result" : "Resultado",
- "Education Edition" : "Edición Educativa",
- "File name is a reserved word" : "Nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un caracter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "Open »%s«" : "Abrir »%s«",
- "Click the button below to open it." : "Haz click en el botón inferior para abrirlo. ",
- "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. ",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegurate de que exista una archivo llamado \".ocdata\" en la raíz del directorio de datos. "
+ "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. "
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
} \ No newline at end of file
diff --git a/lib/l10n/es_AR.js b/lib/l10n/es_AR.js
index c9f76c540a2..665ad506741 100644
--- a/lib/l10n/es_AR.js
+++ b/lib/l10n/es_AR.js
@@ -147,17 +147,6 @@ OC.L10N.register(
"Summary" : "Resumen",
"Translate" : "Traducir",
"Result" : "Resultado",
- "File name is a reserved word" : "Nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un caracter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s compartió »%2$s« contigo y quiere añadir:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s compartió »%2$s« contigo y quiere añadir",
- "»%s« added a note to a file shared with you" : "%s añadió una nota a un archivo compartido con Ud.",
- "Open »%s«" : "Abrir »%s«",
- "%1$s shared »%2$s« with you" : "%1$s compartió »%2$s« contigo",
- "%1$s shared »%2$s« with you." : "%1$s compartió »%2$s« contigo.",
- "Click the button below to open it." : "Haga click en el botón de abajo para abrirlo.",
"File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, favor de intentarlo más tarde. "
},
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/lib/l10n/es_AR.json b/lib/l10n/es_AR.json
index 91e3f4b1757..3cfdd3c7fa1 100644
--- a/lib/l10n/es_AR.json
+++ b/lib/l10n/es_AR.json
@@ -145,17 +145,6 @@
"Summary" : "Resumen",
"Translate" : "Traducir",
"Result" : "Resultado",
- "File name is a reserved word" : "Nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un caracter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s compartió »%2$s« contigo y quiere añadir:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s compartió »%2$s« contigo y quiere añadir",
- "»%s« added a note to a file shared with you" : "%s añadió una nota a un archivo compartido con Ud.",
- "Open »%s«" : "Abrir »%s«",
- "%1$s shared »%2$s« with you" : "%1$s compartió »%2$s« contigo",
- "%1$s shared »%2$s« with you." : "%1$s compartió »%2$s« contigo.",
- "Click the button below to open it." : "Haga click en el botón de abajo para abrirlo.",
"File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, favor de intentarlo más tarde. "
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
} \ No newline at end of file
diff --git a/lib/l10n/es_CL.js b/lib/l10n/es_CL.js
index cf0ebbab064..23370198cbe 100644
--- a/lib/l10n/es_CL.js
+++ b/lib/l10n/es_CL.js
@@ -148,14 +148,6 @@ OC.L10N.register(
"Summary" : "Resumen",
"Translate" : "Traducir",
"Result" : "Resultado",
- "Education Edition" : "Edición Educativa",
- "File name is a reserved word" : "Nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un caracter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "Open »%s«" : "Abrir »%s«",
- "Click the button below to open it." : "Haz click en el botón inferior para abrirlo. ",
- "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. ",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegurate de que exista una archivo llamado \".ocdata\" en la raíz del directorio de datos. "
+ "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. "
},
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/lib/l10n/es_CL.json b/lib/l10n/es_CL.json
index c7a1d610159..b5bffbc72d2 100644
--- a/lib/l10n/es_CL.json
+++ b/lib/l10n/es_CL.json
@@ -146,14 +146,6 @@
"Summary" : "Resumen",
"Translate" : "Traducir",
"Result" : "Resultado",
- "Education Edition" : "Edición Educativa",
- "File name is a reserved word" : "Nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un caracter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "Open »%s«" : "Abrir »%s«",
- "Click the button below to open it." : "Haz click en el botón inferior para abrirlo. ",
- "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. ",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegurate de que exista una archivo llamado \".ocdata\" en la raíz del directorio de datos. "
+ "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. "
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
} \ No newline at end of file
diff --git a/lib/l10n/es_CO.js b/lib/l10n/es_CO.js
index 44e295099ef..b41f82239a5 100644
--- a/lib/l10n/es_CO.js
+++ b/lib/l10n/es_CO.js
@@ -148,14 +148,6 @@ OC.L10N.register(
"Summary" : "Resumen",
"Translate" : "Traducir",
"Result" : "Resultado",
- "Education Edition" : "Edición Educativa",
- "File name is a reserved word" : "Nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un caracter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "Open »%s«" : "Abrir »%s«",
- "Click the button below to open it." : "Haz click en el botón inferior para abrirlo. ",
- "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. ",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegurate de que exista una archivo llamado \".ocdata\" en la raíz del directorio de datos. "
+ "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. "
},
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/lib/l10n/es_CO.json b/lib/l10n/es_CO.json
index dd79f0347a2..c5f85cce0c2 100644
--- a/lib/l10n/es_CO.json
+++ b/lib/l10n/es_CO.json
@@ -146,14 +146,6 @@
"Summary" : "Resumen",
"Translate" : "Traducir",
"Result" : "Resultado",
- "Education Edition" : "Edición Educativa",
- "File name is a reserved word" : "Nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un caracter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "Open »%s«" : "Abrir »%s«",
- "Click the button below to open it." : "Haz click en el botón inferior para abrirlo. ",
- "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. ",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegurate de que exista una archivo llamado \".ocdata\" en la raíz del directorio de datos. "
+ "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. "
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
} \ No newline at end of file
diff --git a/lib/l10n/es_CR.js b/lib/l10n/es_CR.js
index 936df50fabd..ff23d21ef3d 100644
--- a/lib/l10n/es_CR.js
+++ b/lib/l10n/es_CR.js
@@ -148,14 +148,6 @@ OC.L10N.register(
"Summary" : "Resumen",
"Translate" : "Traducir",
"Result" : "Resultado",
- "Education Edition" : "Edición Educativa",
- "File name is a reserved word" : "Nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un caracter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "Open »%s«" : "Abrir »%s«",
- "Click the button below to open it." : "Haz click en el botón inferior para abrirlo. ",
- "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. ",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegurate de que exista una archivo llamado \".ocdata\" en la raíz del directorio de datos. "
+ "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. "
},
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/lib/l10n/es_CR.json b/lib/l10n/es_CR.json
index 5bd9dc539df..f1543683fbd 100644
--- a/lib/l10n/es_CR.json
+++ b/lib/l10n/es_CR.json
@@ -146,14 +146,6 @@
"Summary" : "Resumen",
"Translate" : "Traducir",
"Result" : "Resultado",
- "Education Edition" : "Edición Educativa",
- "File name is a reserved word" : "Nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un caracter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "Open »%s«" : "Abrir »%s«",
- "Click the button below to open it." : "Haz click en el botón inferior para abrirlo. ",
- "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. ",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegurate de que exista una archivo llamado \".ocdata\" en la raíz del directorio de datos. "
+ "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. "
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
} \ No newline at end of file
diff --git a/lib/l10n/es_DO.js b/lib/l10n/es_DO.js
index 7514395b468..d422ddf8f77 100644
--- a/lib/l10n/es_DO.js
+++ b/lib/l10n/es_DO.js
@@ -148,14 +148,6 @@ OC.L10N.register(
"Summary" : "Resumen",
"Translate" : "Traducir",
"Result" : "Resultado",
- "Education Edition" : "Edición Educativa",
- "File name is a reserved word" : "Nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un caracter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "Open »%s«" : "Abrir »%s«",
- "Click the button below to open it." : "Haz click en el botón inferior para abrirlo. ",
- "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. ",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegurate de que exista una archivo llamado \".ocdata\" en la raíz del directorio de datos. "
+ "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. "
},
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/lib/l10n/es_DO.json b/lib/l10n/es_DO.json
index 6d8612b2705..bff8e6ccf95 100644
--- a/lib/l10n/es_DO.json
+++ b/lib/l10n/es_DO.json
@@ -146,14 +146,6 @@
"Summary" : "Resumen",
"Translate" : "Traducir",
"Result" : "Resultado",
- "Education Edition" : "Edición Educativa",
- "File name is a reserved word" : "Nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un caracter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "Open »%s«" : "Abrir »%s«",
- "Click the button below to open it." : "Haz click en el botón inferior para abrirlo. ",
- "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. ",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegurate de que exista una archivo llamado \".ocdata\" en la raíz del directorio de datos. "
+ "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. "
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
} \ No newline at end of file
diff --git a/lib/l10n/es_EC.js b/lib/l10n/es_EC.js
index fde8605a075..79a0c455659 100644
--- a/lib/l10n/es_EC.js
+++ b/lib/l10n/es_EC.js
@@ -233,20 +233,7 @@ OC.L10N.register(
"Translate" : "Traducir",
"Target language" : "Lenguaje de destino",
"Result" : "Resultado",
- "Education Edition" : "Edición Educativa",
- "File name is a reserved word" : "Nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un caracter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s compartió »%2$s« contigo y quiere añadir:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s compartió »%2$s« contigo y quiere añadir",
- "»%s« added a note to a file shared with you" : "»%s« añadió una nota a un archivo compartido contigo",
- "Open »%s«" : "Abrir »%s«",
- "%1$s shared »%2$s« with you" : "%1$s compartió »%2$s« contigo",
- "%1$s shared »%2$s« with you." : "%1$s compartió »%2$s« contigo.",
- "Click the button below to open it." : "Haz click en el botón inferior para abrirlo. ",
"File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. ",
- "Cannot download file" : "No se puede descargar el archivo",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegurate de que exista una archivo llamado \".ocdata\" en la raíz del directorio de datos. "
+ "Cannot download file" : "No se puede descargar el archivo"
},
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/lib/l10n/es_EC.json b/lib/l10n/es_EC.json
index 9baeed701cb..128ee289fa2 100644
--- a/lib/l10n/es_EC.json
+++ b/lib/l10n/es_EC.json
@@ -231,20 +231,7 @@
"Translate" : "Traducir",
"Target language" : "Lenguaje de destino",
"Result" : "Resultado",
- "Education Edition" : "Edición Educativa",
- "File name is a reserved word" : "Nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un caracter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s compartió »%2$s« contigo y quiere añadir:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s compartió »%2$s« contigo y quiere añadir",
- "»%s« added a note to a file shared with you" : "»%s« añadió una nota a un archivo compartido contigo",
- "Open »%s«" : "Abrir »%s«",
- "%1$s shared »%2$s« with you" : "%1$s compartió »%2$s« contigo",
- "%1$s shared »%2$s« with you." : "%1$s compartió »%2$s« contigo.",
- "Click the button below to open it." : "Haz click en el botón inferior para abrirlo. ",
"File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. ",
- "Cannot download file" : "No se puede descargar el archivo",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegurate de que exista una archivo llamado \".ocdata\" en la raíz del directorio de datos. "
+ "Cannot download file" : "No se puede descargar el archivo"
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
} \ No newline at end of file
diff --git a/lib/l10n/es_GT.js b/lib/l10n/es_GT.js
index e2946a83508..c5ddb516258 100644
--- a/lib/l10n/es_GT.js
+++ b/lib/l10n/es_GT.js
@@ -148,14 +148,6 @@ OC.L10N.register(
"Summary" : "Resumen",
"Translate" : "Traducir",
"Result" : "Resultado",
- "Education Edition" : "Edición Educativa",
- "File name is a reserved word" : "Nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un caracter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "Open »%s«" : "Abrir »%s«",
- "Click the button below to open it." : "Haz click en el botón inferior para abrirlo. ",
- "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. ",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegurate de que exista una archivo llamado \".ocdata\" en la raíz del directorio de datos. "
+ "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. "
},
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/lib/l10n/es_GT.json b/lib/l10n/es_GT.json
index bcada807e54..31470583a89 100644
--- a/lib/l10n/es_GT.json
+++ b/lib/l10n/es_GT.json
@@ -146,14 +146,6 @@
"Summary" : "Resumen",
"Translate" : "Traducir",
"Result" : "Resultado",
- "Education Edition" : "Edición Educativa",
- "File name is a reserved word" : "Nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un caracter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "Open »%s«" : "Abrir »%s«",
- "Click the button below to open it." : "Haz click en el botón inferior para abrirlo. ",
- "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. ",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegurate de que exista una archivo llamado \".ocdata\" en la raíz del directorio de datos. "
+ "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. "
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
} \ No newline at end of file
diff --git a/lib/l10n/es_HN.js b/lib/l10n/es_HN.js
index 34d417b4956..72d33d114d4 100644
--- a/lib/l10n/es_HN.js
+++ b/lib/l10n/es_HN.js
@@ -147,14 +147,6 @@ OC.L10N.register(
"Summary" : "Resumen",
"Translate" : "Traducir",
"Result" : "Resultado",
- "Education Edition" : "Edición Educativa",
- "File name is a reserved word" : "Nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un caracter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "Open »%s«" : "Abrir »%s«",
- "Click the button below to open it." : "Haz click en el botón inferior para abrirlo. ",
- "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. ",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegurate de que exista una archivo llamado \".ocdata\" en la raíz del directorio de datos. "
+ "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. "
},
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/lib/l10n/es_HN.json b/lib/l10n/es_HN.json
index a38bec7995e..3968c31b05f 100644
--- a/lib/l10n/es_HN.json
+++ b/lib/l10n/es_HN.json
@@ -145,14 +145,6 @@
"Summary" : "Resumen",
"Translate" : "Traducir",
"Result" : "Resultado",
- "Education Edition" : "Edición Educativa",
- "File name is a reserved word" : "Nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un caracter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "Open »%s«" : "Abrir »%s«",
- "Click the button below to open it." : "Haz click en el botón inferior para abrirlo. ",
- "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. ",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegurate de que exista una archivo llamado \".ocdata\" en la raíz del directorio de datos. "
+ "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. "
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
} \ No newline at end of file
diff --git a/lib/l10n/es_MX.js b/lib/l10n/es_MX.js
index 51e77570f1f..26aeeb55bc0 100644
--- a/lib/l10n/es_MX.js
+++ b/lib/l10n/es_MX.js
@@ -378,20 +378,7 @@ OC.L10N.register(
"Generate headline" : "Generar titular",
"Summarizes text by reducing its length without losing key information." : "Resume el texto reduciendo su longitud sin perder información clave.",
"Extracts topics from a text and outputs them separated by commas." : "Extrae los temas de un texto y genera una salida separada por comas. ",
- "Education Edition" : "Edición Educativa",
- "File name is a reserved word" : "Nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un caracter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s compartió »%2$s« contigo y quiere añadir:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s compartió »%2$s« contigo y quiere añadir",
- "»%s« added a note to a file shared with you" : "»%s« añadió una nota a un archivo compartido contigo",
- "Open »%s«" : "Abrir »%s«",
- "%1$s shared »%2$s« with you" : "%1$s compartió »%2$s« contigo",
- "%1$s shared »%2$s« with you." : "%1$s compartió »%2$s« contigo.",
- "Click the button below to open it." : "Haz click en el botón inferior para abrirlo. ",
"File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. ",
- "Cannot download file" : "No se puede descargar el archivo",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegurate de que exista una archivo llamado \".ocdata\" en la raíz del directorio de datos. "
+ "Cannot download file" : "No se puede descargar el archivo"
},
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/lib/l10n/es_MX.json b/lib/l10n/es_MX.json
index afcbd8e3d20..d6f790fb877 100644
--- a/lib/l10n/es_MX.json
+++ b/lib/l10n/es_MX.json
@@ -376,20 +376,7 @@
"Generate headline" : "Generar titular",
"Summarizes text by reducing its length without losing key information." : "Resume el texto reduciendo su longitud sin perder información clave.",
"Extracts topics from a text and outputs them separated by commas." : "Extrae los temas de un texto y genera una salida separada por comas. ",
- "Education Edition" : "Edición Educativa",
- "File name is a reserved word" : "Nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un caracter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s compartió »%2$s« contigo y quiere añadir:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s compartió »%2$s« contigo y quiere añadir",
- "»%s« added a note to a file shared with you" : "»%s« añadió una nota a un archivo compartido contigo",
- "Open »%s«" : "Abrir »%s«",
- "%1$s shared »%2$s« with you" : "%1$s compartió »%2$s« contigo",
- "%1$s shared »%2$s« with you." : "%1$s compartió »%2$s« contigo.",
- "Click the button below to open it." : "Haz click en el botón inferior para abrirlo. ",
"File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. ",
- "Cannot download file" : "No se puede descargar el archivo",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegurate de que exista una archivo llamado \".ocdata\" en la raíz del directorio de datos. "
+ "Cannot download file" : "No se puede descargar el archivo"
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
} \ No newline at end of file
diff --git a/lib/l10n/es_NI.js b/lib/l10n/es_NI.js
index eb10743d7e5..261bdc35d55 100644
--- a/lib/l10n/es_NI.js
+++ b/lib/l10n/es_NI.js
@@ -147,14 +147,6 @@ OC.L10N.register(
"Summary" : "Resumen",
"Translate" : "Traducir",
"Result" : "Resultado",
- "Education Edition" : "Edición Educativa",
- "File name is a reserved word" : "Nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un caracter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "Open »%s«" : "Abrir »%s«",
- "Click the button below to open it." : "Haz click en el botón inferior para abrirlo. ",
- "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. ",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegurate de que exista una archivo llamado \".ocdata\" en la raíz del directorio de datos. "
+ "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. "
},
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/lib/l10n/es_NI.json b/lib/l10n/es_NI.json
index 9916828ec33..b26aebe5212 100644
--- a/lib/l10n/es_NI.json
+++ b/lib/l10n/es_NI.json
@@ -145,14 +145,6 @@
"Summary" : "Resumen",
"Translate" : "Traducir",
"Result" : "Resultado",
- "Education Edition" : "Edición Educativa",
- "File name is a reserved word" : "Nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un caracter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "Open »%s«" : "Abrir »%s«",
- "Click the button below to open it." : "Haz click en el botón inferior para abrirlo. ",
- "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. ",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegurate de que exista una archivo llamado \".ocdata\" en la raíz del directorio de datos. "
+ "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. "
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
} \ No newline at end of file
diff --git a/lib/l10n/es_PA.js b/lib/l10n/es_PA.js
index 955c8c0a1f0..06f1cc33c5b 100644
--- a/lib/l10n/es_PA.js
+++ b/lib/l10n/es_PA.js
@@ -147,14 +147,6 @@ OC.L10N.register(
"Summary" : "Resumen",
"Translate" : "Traducir",
"Result" : "Resultado",
- "Education Edition" : "Edición Educativa",
- "File name is a reserved word" : "Nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un caracter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "Open »%s«" : "Abrir »%s«",
- "Click the button below to open it." : "Haz click en el botón inferior para abrirlo. ",
- "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. ",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegurate de que exista una archivo llamado \".ocdata\" en la raíz del directorio de datos. "
+ "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. "
},
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/lib/l10n/es_PA.json b/lib/l10n/es_PA.json
index 8e66f47c077..98d2ff2bbf6 100644
--- a/lib/l10n/es_PA.json
+++ b/lib/l10n/es_PA.json
@@ -145,14 +145,6 @@
"Summary" : "Resumen",
"Translate" : "Traducir",
"Result" : "Resultado",
- "Education Edition" : "Edición Educativa",
- "File name is a reserved word" : "Nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un caracter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "Open »%s«" : "Abrir »%s«",
- "Click the button below to open it." : "Haz click en el botón inferior para abrirlo. ",
- "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. ",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegurate de que exista una archivo llamado \".ocdata\" en la raíz del directorio de datos. "
+ "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. "
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
} \ No newline at end of file
diff --git a/lib/l10n/es_PE.js b/lib/l10n/es_PE.js
index dbd07a17cc1..2ac243d2c1d 100644
--- a/lib/l10n/es_PE.js
+++ b/lib/l10n/es_PE.js
@@ -147,14 +147,6 @@ OC.L10N.register(
"Summary" : "Resumen",
"Translate" : "Traducir",
"Result" : "Resultado",
- "Education Edition" : "Edición Educativa",
- "File name is a reserved word" : "Nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un caracter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "Open »%s«" : "Abrir »%s«",
- "Click the button below to open it." : "Haz click en el botón inferior para abrirlo. ",
- "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. ",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegurate de que exista una archivo llamado \".ocdata\" en la raíz del directorio de datos. "
+ "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. "
},
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/lib/l10n/es_PE.json b/lib/l10n/es_PE.json
index b062f3a676f..e362ba23870 100644
--- a/lib/l10n/es_PE.json
+++ b/lib/l10n/es_PE.json
@@ -145,14 +145,6 @@
"Summary" : "Resumen",
"Translate" : "Traducir",
"Result" : "Resultado",
- "Education Edition" : "Edición Educativa",
- "File name is a reserved word" : "Nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un caracter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "Open »%s«" : "Abrir »%s«",
- "Click the button below to open it." : "Haz click en el botón inferior para abrirlo. ",
- "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. ",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegurate de que exista una archivo llamado \".ocdata\" en la raíz del directorio de datos. "
+ "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. "
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
} \ No newline at end of file
diff --git a/lib/l10n/es_PR.js b/lib/l10n/es_PR.js
index 8a116f57e97..a63fb4990b8 100644
--- a/lib/l10n/es_PR.js
+++ b/lib/l10n/es_PR.js
@@ -147,14 +147,6 @@ OC.L10N.register(
"Summary" : "Resumen",
"Translate" : "Traducir",
"Result" : "Resultado",
- "Education Edition" : "Edición Educativa",
- "File name is a reserved word" : "Nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un caracter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "Open »%s«" : "Abrir »%s«",
- "Click the button below to open it." : "Haz click en el botón inferior para abrirlo. ",
- "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. ",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegurate de que exista una archivo llamado \".ocdata\" en la raíz del directorio de datos. "
+ "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. "
},
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/lib/l10n/es_PR.json b/lib/l10n/es_PR.json
index 83e0379e21b..b3769931a30 100644
--- a/lib/l10n/es_PR.json
+++ b/lib/l10n/es_PR.json
@@ -145,14 +145,6 @@
"Summary" : "Resumen",
"Translate" : "Traducir",
"Result" : "Resultado",
- "Education Edition" : "Edición Educativa",
- "File name is a reserved word" : "Nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un caracter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "Open »%s«" : "Abrir »%s«",
- "Click the button below to open it." : "Haz click en el botón inferior para abrirlo. ",
- "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. ",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegurate de que exista una archivo llamado \".ocdata\" en la raíz del directorio de datos. "
+ "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. "
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
} \ No newline at end of file
diff --git a/lib/l10n/es_PY.js b/lib/l10n/es_PY.js
index a8e7e370158..cc842076563 100644
--- a/lib/l10n/es_PY.js
+++ b/lib/l10n/es_PY.js
@@ -147,14 +147,6 @@ OC.L10N.register(
"Summary" : "Resumen",
"Translate" : "Traducir",
"Result" : "Resultado",
- "Education Edition" : "Edición Educativa",
- "File name is a reserved word" : "Nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un caracter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "Open »%s«" : "Abrir »%s«",
- "Click the button below to open it." : "Haz click en el botón inferior para abrirlo. ",
- "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. ",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegurate de que exista una archivo llamado \".ocdata\" en la raíz del directorio de datos. "
+ "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. "
},
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/lib/l10n/es_PY.json b/lib/l10n/es_PY.json
index 1069b7b2165..d180501b432 100644
--- a/lib/l10n/es_PY.json
+++ b/lib/l10n/es_PY.json
@@ -145,14 +145,6 @@
"Summary" : "Resumen",
"Translate" : "Traducir",
"Result" : "Resultado",
- "Education Edition" : "Edición Educativa",
- "File name is a reserved word" : "Nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un caracter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "Open »%s«" : "Abrir »%s«",
- "Click the button below to open it." : "Haz click en el botón inferior para abrirlo. ",
- "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. ",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegurate de que exista una archivo llamado \".ocdata\" en la raíz del directorio de datos. "
+ "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. "
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
} \ No newline at end of file
diff --git a/lib/l10n/es_SV.js b/lib/l10n/es_SV.js
index 4901005509c..f91beddc952 100644
--- a/lib/l10n/es_SV.js
+++ b/lib/l10n/es_SV.js
@@ -148,14 +148,6 @@ OC.L10N.register(
"Summary" : "Resumen",
"Translate" : "Traducir",
"Result" : "Resultado",
- "Education Edition" : "Edición Educativa",
- "File name is a reserved word" : "Nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un caracter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "Open »%s«" : "Abrir »%s«",
- "Click the button below to open it." : "Haz click en el botón inferior para abrirlo. ",
- "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. ",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegurate de que exista una archivo llamado \".ocdata\" en la raíz del directorio de datos. "
+ "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. "
},
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/lib/l10n/es_SV.json b/lib/l10n/es_SV.json
index 7918b2c9aa0..03eb9b91f75 100644
--- a/lib/l10n/es_SV.json
+++ b/lib/l10n/es_SV.json
@@ -146,14 +146,6 @@
"Summary" : "Resumen",
"Translate" : "Traducir",
"Result" : "Resultado",
- "Education Edition" : "Edición Educativa",
- "File name is a reserved word" : "Nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un caracter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "Open »%s«" : "Abrir »%s«",
- "Click the button below to open it." : "Haz click en el botón inferior para abrirlo. ",
- "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. ",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegurate de que exista una archivo llamado \".ocdata\" en la raíz del directorio de datos. "
+ "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. "
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
} \ No newline at end of file
diff --git a/lib/l10n/es_UY.js b/lib/l10n/es_UY.js
index 633e1d2f7d4..beb9e3689f7 100644
--- a/lib/l10n/es_UY.js
+++ b/lib/l10n/es_UY.js
@@ -147,14 +147,6 @@ OC.L10N.register(
"Summary" : "Resumen",
"Translate" : "Traducir",
"Result" : "Resultado",
- "Education Edition" : "Edición Educativa",
- "File name is a reserved word" : "Nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un caracter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "Open »%s«" : "Abrir »%s«",
- "Click the button below to open it." : "Haz click en el botón inferior para abrirlo. ",
- "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. ",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegurate de que exista una archivo llamado \".ocdata\" en la raíz del directorio de datos. "
+ "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. "
},
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/lib/l10n/es_UY.json b/lib/l10n/es_UY.json
index 572adad0cbe..68d50d1e194 100644
--- a/lib/l10n/es_UY.json
+++ b/lib/l10n/es_UY.json
@@ -145,14 +145,6 @@
"Summary" : "Resumen",
"Translate" : "Traducir",
"Result" : "Resultado",
- "Education Edition" : "Edición Educativa",
- "File name is a reserved word" : "Nombre de archivo es una palabra reservada",
- "File name contains at least one invalid character" : "El nombre del archivo contiene al menos un caracter inválido",
- "File name is too long" : "El nombre del archivo es demasiado largo",
- "Users" : "Usuarios",
- "Open »%s«" : "Abrir »%s«",
- "Click the button below to open it." : "Haz click en el botón inferior para abrirlo. ",
- "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. ",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegurate de que exista una archivo llamado \".ocdata\" en la raíz del directorio de datos. "
+ "File is currently busy, please try again later" : "El archivo se encuentra actualmente en uso, por favor intentalo más tarde. "
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
} \ No newline at end of file
diff --git a/lib/l10n/et_EE.js b/lib/l10n/et_EE.js
index 7a32b1cec33..e2092211637 100644
--- a/lib/l10n/et_EE.js
+++ b/lib/l10n/et_EE.js
@@ -2,9 +2,13 @@ OC.L10N.register(
"lib",
{
"Cannot write into \"config\" directory!" : "Ei saa kirjutada „config“ kausta!!",
+ "This can usually be fixed by giving the web server write access to the config directory." : "Tavaliselt saad selle lahendada andes veebiserverile õigused seadistuse kausta kirjutamiseks",
+ "But, if you prefer to keep config.php file read only, set the option \"config_is_read_only\" to true in it." : "Aga kui soovid, et seadistuste fail ei peaks olema veebiserveri poolt muudetav, siis palun määra seadistusvõtme „config_is_read_only“ väärtuseks true.",
"See %s" : "Vaata %s",
+ "Application %1$s is not present or has a non-compatible version with this server. Please check the apps directory." : "Rakendust „%1$s“ pole serverisse paigaldatud või pole tema versioon ühilduv selle serveriga. Palun kontrolli paigaldatud rakendusi.",
"Sample configuration detected" : "Tuvastati näidisseaded",
- "It has been detected that the sample configuration has been copied. This can break your installation and is unsupported. Please read the documentation before performing changes on config.php" : "Tuvastati, et kopeeriti näidisseaded. See võib lõhkuda sinu saidi ja see pole toetatud. Palun loe enne faili config.php muutmist dokumentatsiooni",
+ "It has been detected that the sample configuration has been copied. This can break your installation and is unsupported. Please read the documentation before performing changes on config.php" : "Tuvastasin, et seadistuse faili kopeeritud näidisseaded. See võib lõhkuda sinu saidi ja see pole toetatud. Palun loe enne faili config.php muutmist dokumentatsiooni",
+ "The page could not be found on the server." : "Seda lehte ei õnnestunud serverist leida.",
"%s email verification" : "E-postiaadressi kinnitamine: %s",
"Email verification" : "E-postiaadressi kinnitamine",
"Click the following button to confirm your email." : "Oma e-postiaadressi kinnitamiseks klõpsi järgmisel nupul.",
@@ -15,12 +19,21 @@ OC.L10N.register(
"%1$s, %2$s and %3$s" : "%1$s, %2$s ja %3$s",
"%1$s, %2$s, %3$s and %4$s" : "%1$s, %2$s, %3$s ja %4$s",
"%1$s, %2$s, %3$s, %4$s and %5$s" : "%1$s, %2$s, %3$s, %4$s ja %5$s",
+ "Education bundle" : "Rakenduste komplekt haridusasutustele",
+ "Enterprise bundle" : "Rakenduste komplekt suurorganisatsioonidele",
+ "Groupware bundle" : "Rühmatarkvara rakenduste komplekt",
+ "Hub bundle" : "Rakenduste komplekt Nextcloud Hub",
+ "Public sector bundle" : "Rakenduste komplekt avaliku sektori asutustele",
+ "Social sharing bundle" : "Rakenduste komplekt sotsiaalmeedias jagamiseks",
"PHP %s or higher is required." : "PHP %s või uuem on nõutav.",
"PHP with a version lower than %s is required." : "Nõutud on PHP madalama versiooniga kui %s.",
+ "%sbit or higher PHP required." : "Vajalik on %s-bitine või parem PHP versioon.",
"The following architectures are supported: %s" : "Toetatud on järgnevad arhitektuurid: %s",
"The following databases are supported: %s" : "Toetatud on järgnevad andmebaasid: %s",
"The command line tool %s could not be found" : "Käsurea töövahendit %s ei leitud",
"The library %s is not available." : "Teek %s pole saadaval.",
+ "Library %1$s with a version higher than %2$s is required - available version %3$s." : "Vajalik on „%1$s“ teek suurema versiooniga kui %2$s - hetkel on versioon %3$s.",
+ "Library %1$s with a version lower than %2$s is required - available version %3$s." : "Vajalik on „%1$s“ teek väiksema versiooniga kui %2$s - hetkel on versioon %3$s.",
"The following platforms are supported: %s" : "Toetatud on järgmised platvormid: %s",
"Server version %s or higher is required." : "Nõutav on serveri versioon %s või suurem.",
"Server version %s or lower is required." : "Serveri versioon %s või madalam on nõutav.",
@@ -31,9 +44,11 @@ OC.L10N.register(
"Wiping of device %s has started" : "Andmete kustutamine seadmes „%s“ algas",
"Wiping of device »%s« has started" : "Andmete kustutamine seadmes „%s“ algas",
"»%s« started remote wipe" : "„%s“ alustas kaugseadme andmete kustutamist",
+ "Device or application »%s« has started the remote wipe process. You will receive another email once the process has finished" : "„%s“ seade või rakendus on alustanud kaugkustutamise protsessi. Selle lõppemisel saad veel ühe teavitava e-kirja",
"Wiping of device %s has finished" : "Andmete kustutamine seadmes „%s“ lõppes",
"Wiping of device »%s« has finished" : "Andmete kustutamine seadmes „%s“ lõppes",
"»%s« finished remote wipe" : "„%s“ lõpetas kaugseadme andmete kustutamise",
+ "Device or application »%s« has finished the remote wipe process." : "„%s“ seade või rakendus on lõpetanud kaugkustutamise protsessi.",
"Remote wipe started" : "Kaugkustutamine on alanud",
"A remote wipe was started on device %s" : "„%s“ seadme kaugkustutamine on alanud",
"Remote wipe finished" : "Kaugkustutamine on lõppenud",
@@ -70,6 +85,7 @@ OC.L10N.register(
"in a few seconds" : "mõne sekundi jooksul",
"seconds ago" : "sekundit tagasi",
"Empty file" : "Tühi fail",
+ "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "Moodulit tunnusega „%s“ pole pole olemas. Palun taga see oma rakenduste seadistustest või võta ühendust peakasutajaga.",
"No file conversion providers available" : "Ühtegi teisendusteenuse pakkujat pole saadaval",
"File is too large to convert" : "Fail on teisendamiseks liiga suur",
"Destination does not match conversion extension" : "Sihtmeedia ei vasta teisendamislaiendile",
@@ -77,6 +93,8 @@ OC.L10N.register(
"Destination does not exist" : "Sihtmeediat pole olemas",
"Destination is not creatable" : "Sihtmeedia pole loodav",
"Dot files are not allowed" : "Punktiga failid pole lubatud",
+ "%1$s (renamed)" : "%1$s (nimi on muudetud)",
+ "renamed file" : "muudetud nimega fail",
"\"%1$s\" is a forbidden file or folder name." : "„%1$s“ on keelatud faili- või kaustanimi.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "„%1$s“ on keelatud faili- või kaustanime eesliide.",
"\"%1$s\" is not allowed inside a file or folder name." : "„%1$s“ pole faili- või kaustanimes lubatud.",
@@ -99,6 +117,7 @@ OC.L10N.register(
"Filename contains at least one invalid character" : "Failinimes on vähemalt üks keelatud märk",
"Filename is too long" : "Failinimi on liiga pikk",
"Empty filename is not allowed" : "Tühi failinimi pole lubatud",
+ "App \"%s\" cannot be installed because appinfo file cannot be read." : "Kuna „appinfo“ faili pole võimalik lugeda, siis „%s“ rakendust ei saa paigaldada.",
"App \"%s\" cannot be installed because it is not compatible with this version of the server." : "Kuna ta pole ühilduv selle serveri versiooniga, siis „%s“ rakendust ei saa paigaldada.",
"__language_name__" : "Eesti",
"This is an automatically sent email, please do not reply." : "See on automaatselt saadetud e-kiri, palun ära vasta.",
@@ -130,6 +149,7 @@ OC.L10N.register(
"Pronouns" : "Asesõnad pöördumisel",
"Unknown account" : "Tundmatu kasutajakonto",
"Additional settings" : "Lisaseaded",
+ "Enter the database Login and name for %s" : "Andmebaasi kasutajanimi ning nimi %si jaoks",
"Enter the database Login for %s" : "Sisesta andmebaasi %s kasutajatunnus",
"Enter the database name for %s" : "Sisesta andmebaasi %s nimi",
"You cannot use dots in the database name %s" : "Sa ei tohi kasutada „%s“ andmebaasi nimes punkte",
@@ -153,6 +173,7 @@ OC.L10N.register(
"%1$s shared %2$s with you and wants to add:" : "%1$s jagas sinuga %2$s ning soovib lisada:",
"%1$s shared %2$s with you and wants to add" : "%1$s jagas sinuga %2$s ning soovib lisada",
"%s added a note to a file shared with you" : "%s jagas koos sulle jagatud failiga ka märget",
+ "Passwords are enforced for link and mail shares" : "Linkide ja e-posti teel levitatava jaosmeedia puhul on salasõnade kasutamine nõutav",
"Share recipient is not a valid user" : "Jaosmeedia vastuvõtja pole korrektne kasutaja",
"Share recipient is not a valid group" : "Jaosmeedia vastuvõtja pole korrektne grupp",
"Share recipient should be empty" : "Jaosmeedia vastuvõtja peaks jääma tühjaks",
@@ -173,9 +194,11 @@ OC.L10N.register(
"Files cannot be shared with create permissions" : "Loomisõigustega faile ei saa jagada",
"Expiration date is in the past" : "Aegumise kuupäev on minevikus",
"Expiration date is enforced" : "Aegumiskuupäev on kasutusel",
+ "_Cannot set expiration date more than %n day in the future_::_Cannot set expiration date more than %n days in the future_" : ["Aegumist ei saa lisada kaugemale, kui %n päev tulevikus.","Aegumist ei saa lisada kaugemale, kui %n päeva tulevikus."],
"Sharing is only allowed with group members" : "Jagamine on lubatud vaid grupi liikmetega",
- "Sharing %s failed, because this item is already shared with the account %s" : "%s jagamine ebaõnnestus, kuna seda üksust on juba jagatud kontoga %s",
+ "Sharing %s failed, because this item is already shared with the account %s" : "%s jagamine ei õnnestunud, kuna seda objekti on juba jagatud kontoga %s",
"Group sharing is now allowed" : "Grupile jagamine on nüüd lubatud",
+ "Sharing is only allowed within your own groups" : "Jagamine on lubatud vaid sinu oma grupi liikmetega",
"Path is already shared with this group" : "Asukoht on selle grupiga juba jagatud",
"Link sharing is not allowed" : "Lingi jagamine pole lubatud",
"Public upload is not allowed" : "Avalik üleslaadimine pole lubatud",
@@ -183,11 +206,14 @@ OC.L10N.register(
"Sharing is disabled" : "Jagamine pole kasutusel",
"Sharing is disabled for you" : "Jagamine pole sinu jaoks kasutusel",
"Cannot share with the share owner" : "Sa ei saa jagada jaosmeedia omanikule",
+ "Share does not have a full ID" : "Jaosmeedial on täismahuline tunnus puudu",
"Cannot change share type" : "Sa ei saa muuta jaosmeedia tüüpi",
+ "Can only update recipient on user shares" : "Kasutaja jaosmeedia saajat ei õnnestu uuendada",
"Invalid share recipient" : "Vigane jaosmeedia vastuvõtja",
"Group \"%s\" does not exist" : "„%s“ gruppi pole olemas",
"The requested share does not exist anymore" : "Soovitud jagamist enam ei eksisteeri",
- "Could not find category \"%s\"" : "Ei leia kategooriat \"%s\"",
+ "The requested share comes from a disabled user" : "Soovitud jaosmeedia on loonud blokeeritud kasutaja",
+ "Could not find category \"%s\"" : "Ei leia kategooriat „%s“",
"Input text" : "Sisendtekst",
"The input text" : "Sisendtekst",
"Sunday" : "Pühapäev",
@@ -235,10 +261,16 @@ OC.L10N.register(
"Oct." : "Okt.",
"Nov." : "Nov.",
"Dec." : "Dets.",
- "A valid password must be provided" : "Sisesta nõuetele vastav parool",
+ "A valid password must be provided" : "Sisesta nõuetele vastav salasõna",
"The Login is already being used" : "See kasutajanimi on juba kasutusel",
"Could not create account" : "Kasutajakonto loomine ei õnnestunud",
- "Login is too long" : "Kasutajanimi on liiga pikk",
+ "Only the following characters are allowed in an Login: \"a-z\", \"A-Z\", \"0-9\", spaces and \"_.@-'\"" : "Kasutajanimes on lubatud ainult järgmised tähemärgid: „a-z“, „A-Z“, „0-9“, ja „_.@-'“",
+ "A valid Login must be provided" : "Palun sisesta korrektne kasutajanimi",
+ "Login contains whitespace at the beginning or at the end" : "Kasutajanime alguses või lõpus on tühik",
+ "Login must not consist of dots only" : "Kasutajanimi ei tohi koosneda ainult punktidest",
+ "Username is too long" : "Kasutajanimi on liiga pikk",
+ "Login is invalid because files already exist for this user" : "See kasutajanimi ei sobi, kuna sellise kasutaja faile on juba olemas",
+ "Account disabled" : "Konto pole kasutusel",
"Login canceled by app" : "Rakendus katkestas sisselogimise",
"App \"%1$s\" cannot be installed because the following dependencies are not fulfilled: %2$s" : "„%1$s“ rakendust ei saa paigaldada, sest järgnev sõltuvus on puudu: %2$s",
"a safe home for all your data" : "turvaline koht sinu andmetele",
@@ -246,21 +278,39 @@ OC.L10N.register(
"Authentication error" : "Autentimise viga",
"Token expired. Please reload page." : "Kontrollkood aegus. Paelun laadi leht uuesti.",
"No database drivers (sqlite, mysql, or postgresql) installed." : "Ühtegi andmebaasi (sqlite, mysql või postgresql) draiverit pole paigaldatud.",
+ "Cannot write into \"config\" directory." : "Pole õigust kirjutada „config“ kausta.",
+ "This can usually be fixed by giving the web server write access to the config directory. See %s" : "Tavaliselt saad selle lahendada andes veebiserverile õigused seadistuse kausta kirjutamiseks. Vaata siia: %s",
+ "Or, if you prefer to keep config.php file read only, set the option \"config_is_read_only\" to true in it. See %s" : "Aga kui soovid, et config.pho seadistuste fail ei peaks olema veebiserveri poolt muudetav, siis palun määra seadistusvõtme „config_is_read_only“ väärtuseks true. Lisateavet leiad: %s",
+ "Cannot write into \"apps\" directory." : "Pole õigust kirjutada „apps“ kausta.",
+ "This can usually be fixed by giving the web server write access to the apps directory or disabling the App Store in the config file." : "Tavaliselt saad selle lahendada andes veebiserverile õigused rakenduste kausta kirjutamiseks. Alternatiivina võid ka Nextcloudi rakendustepoe kasutamise keelata.",
"Cannot create \"data\" directory." : "„data“ kausta loomine ei õnnestunud.",
+ "This can usually be fixed by giving the web server write access to the root directory. See %s" : "Tavaliselt saad selle lahendada andes veebiserverile õigused juurkausta kirjutamiseks. Vaata siia: %s",
+ "Permissions can usually be fixed by giving the web server write access to the root directory. See %s." : "Tavaliselt saad õiguste vea lahendada andes veebiserverile õigused juurkausta kirjutamiseks. Vaata siia: %s",
"Your data directory is not writable." : "Sinu serveri andmekaust pole kirjutatav.",
"Setting locale to %s failed." : "Ei õnnestunud määrata lokaadi väärtuseks „%s“.",
"Please install one of these locales on your system and restart your web server." : "Palun paigalda mõni neist lokaatidest oma serverisse ning taaskäivita veebiserver.",
"PHP module %s not installed." : "PHP moodulit %s pole paigaldatud.",
"Please ask your server administrator to install the module." : "Palu oma serveri haldajal moodul paigadalda.",
- "PHP setting \"%s\" is not set to \"%s\"." : "PHP seade \"%s\" ei ole \"%s\".",
+ "PHP setting \"%s\" is not set to \"%s\"." : "PHP seadistuse „%s“ väärtuseks ei ole „%s“.",
"Adjusting this setting in php.ini will make Nextcloud run again" : "Selle seadistuse kohendamine php.ini failis võimaldab sul Nextcloudi uuesti tööle saada",
+ "<code>mbstring.func_overload</code> is set to <code>%s</code> instead of the expected value <code>0</code>." : "<code>mbstring.func_overload</code> muutuja väärtus on hetkel <code>%s</code>, pigem eeldaks väärtust <code>0</code>.",
+ "To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini." : "Vea parandamiseks muuda oma veebiserveri php.ini failis <code>mbstring.func_overload</code> väärtuseks <code>0</code>.",
+ "PHP is apparently set up to strip inline doc blocks. This will make several core apps inaccessible." : "PHP on seadistatud eemaldama „inline“ dokumendi blokke. See muudab mõned tuumikrakendused kasutamatuteks.",
"This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "See on tõenäoliselt põhjustatud puhver/kiirendist nagu Zend OPcache või eAccelerator.",
"PHP modules have been installed, but they are still listed as missing?" : "PHP moodulid on paigaldatud, kuid neid näitatakse endiselt kui puuduolevad?",
"Please ask your server administrator to restart the web server." : "Palu oma serveri haldajal veebiserver taaskäivitada.",
+ "The required %s config variable is not configured in the config.php file." : "Nõutav seadistuste muutuja „%s“ puudub sonfig.php failist.",
+ "Please ask your server administrator to check the Nextcloud configuration." : "Palu oma serveri haldajal Nextcloudi seadistusi kontrollida.",
+ "Your data directory is readable by other people." : "Sinu andmete kaust on loetav teiste kasutajate poolt.",
+ "Please change the permissions to 0770 so that the directory cannot be listed by other people." : "Palun muuda kausta õigused 0770-ks, et kausta sisu poleks teistele kasutajatele nähtav.",
"Your data directory must be an absolute path." : "Andmekausta asukoht peab olema absoluutne aadress.",
- "Your data directory is invalid." : "Sinu andmekataloog on vigane",
+ "Check the value of \"datadirectory\" in your configuration." : "Palun kontrolli „datadirectory“ väärtust selle paigalduse seadistustes.",
+ "Your data directory is invalid." : "Sinu andmekaust on vigane.",
+ "Ensure there is a file called \"%1$s\" in the root of the data directory. It should have the content: \"%2$s\"" : "Palun taga, et andmete juurkaustas leidub fail „%1$s“, mille sisuks on „%2$s“",
"Action \"%s\" not supported or implemented." : "„%s“ tegevus pole toetatud või implementeeritud.",
- "Parameters missing in order to complete the request. Missing Parameters: \"%s\"" : "Päringu lõpetamiseks on puudu järgmised parameetrid; „%s“",
+ "Authentication failed, wrong token or provider ID given" : "Autentimine ei õnnestunud - kas tunnusluba või teenusepakkuja tunnus on vale",
+ "Parameters missing in order to complete the request. Missing Parameters: \"%s\"" : "Päringu lõpetamiseks on puudu järgmised parameetrid: „%s“",
+ "ID \"%1$s\" already used by cloud federation provider \"%2$s\"" : "„%1$s“ tunnus on juba kasutusel liitpilve serveris „%2$s“",
"Cloud Federation Provider with ID: \"%s\" does not exist." : "Liitpilve teenusepakkujat tunnusega „%s“ pole olemas.",
"Could not obtain lock type %d on \"%s\"." : "Ei suutnud hankida %d tüüpi lukustust asukohas „%s“.",
"Storage unauthorized. %s" : "Andmeruum on autoriseerimata. %s",
@@ -268,7 +318,39 @@ OC.L10N.register(
"Storage connection error. %s" : "Viga andmeruumi ühenduse loomisel. %s",
"Storage is temporarily not available" : "Salvestusruum pole ajutiselt kättesaadav",
"Storage connection timeout. %s" : "Aegumine andmeruumi ühenduse loomisel. %s",
- "Generate image" : "Piltide loomine",
+ "Transcribe audio" : "Kirjuta heli üles",
+ "Transcribe the things said in an audio" : "Kirjuta üles helifailis kuuldav jutt",
+ "Audio input" : "Helisisend",
+ "The audio to transcribe" : "Üleskirjutatav helifail",
+ "Transcription" : "Üleskirjutus",
+ "The transcribed text" : "Üleskirjutatud tekst",
+ "Chat with an agent" : "Vestle robotagendiga",
+ "Chat message" : "Vestluse sõnum",
+ "A chat message to send to the agent." : "Robotagendile saadetav sõnum.",
+ "Confirmation" : "Kinnitus",
+ "Whether to confirm previously requested actions: 0 for denial and 1 for confirmation." : "Kas peaksime eelmised tegevuse kinnitama: keeldumist märgib 0 ja nõustumist 1.",
+ "Conversation token" : "Vestluse tunnusluba",
+ "A token representing the conversation." : "Tunnusluba vestluse tuvastamiseks.",
+ "Generated response" : "Loodud vastus",
+ "The response from the chat model." : "Vastus tehisarupõhise vestluse mudelilt.",
+ "The new conversation token" : "Vestluse uus tunnusluba",
+ "Send this along with the next interaction." : "Saada see kaasa järgmise päringuga.",
+ "Requested actions by the agent" : "Ülesanded tehisaru agendile",
+ "Actions that the agent would like to carry out in JSON format." : "Tehisaru agendile antavad ülesanded JSON-vormingus.",
+ "Context write" : "Kontekstuaalne kirjutamine",
+ "Writes text in a given style based on the provided source material." : "Kirjutab etteantud lähtematerjali lausel teksti üles.",
+ "Writing style" : "Kirjutamisstiil",
+ "Demonstrate a writing style that you would like to immitate" : "Näita sellist kirjutamisstiili, mida tahad jäljendada",
+ "Source material" : "Lähtematerjal",
+ "The content that would like to be rewritten in the new writing style" : "Sisu, mida tahaksid uues stiilis ümber kirjutada",
+ "Generated text" : "Koostatud tekst",
+ "The generated text with content from the source material in the given style" : "Antud stiilis lähtematerjali alusel koostatud tekst",
+ "Emoji generator" : "Emojide looja",
+ "Takes text and generates a representative emoji for it." : "Võtab aluseks teksti ja lood selle alusel emoji.",
+ "The text to generate an emoji for" : "Lähtetekst, millest lood emoji",
+ "Generated emoji" : "Loodud emoji",
+ "The generated emoji based on the input text" : "Sisestatud teksti alusel loodud emoji",
+ "Generate image" : "Pildiloome",
"Generate an image from a text prompt" : "Loo tekstisisendist pilt",
"Prompt" : "Sisendvorm",
"Describe the image you want to generate" : "Kirjelda loodavat pilti",
@@ -276,6 +358,26 @@ OC.L10N.register(
"How many images to generate" : "Mitu pilti peaksime tekitama",
"Output images" : "Väljundpildid",
"The generated images" : "Loodud pildid",
+ "Generate speech" : "Koosta kõne",
+ "Generate speech from a transcript" : "Koosta üleskirjutusest kõne",
+ "Write transcript that you want the assistant to generate speech from" : "Kirjuta üles see, mille alusel tahad Abilisel lasta koostada kõne",
+ "Output speech" : "Kõneväljund",
+ "The generated speech" : "Koostatud kõne",
+ "Change Tone" : "Teksti tooni muutmine",
+ "Change the tone of a piece of text." : "Muuda antud teksti tonaalsust.",
+ "Write a text that you want the assistant to rewrite in another tone." : "Kirjuta üles see, mille tonaalsust tahad Abilisel lasta ümber kirjutada.",
+ "Desired tone" : "Soovitud toon",
+ "In which tone should your text be rewritten?" : "Mis toonis peaks tekst olema ümberkirjutatud?",
+ "The rewritten text in the desired tone, written by the assistant:" : "Abilise poolt soovitud toonis ümberkirjutatud tekst:",
+ "Chat" : "Vestle",
+ "Chat with the assistant" : "Vestle Abilisega",
+ "System prompt" : "Süsteemi viip",
+ "Chat history" : "Vestluse ajalugu",
+ "The history of chat messages before the current message, starting with a message by the user" : "Kasutaja sõnumiga algav vestluse ajalugu enne praegust sõnumit",
+ "Response message" : "Sõnumi vastus",
+ "The generated response as part of the conversation" : "Loodud vastus vestluse osana",
+ "Formalize text" : "Muuda tekst ametlikuks",
+ "Takes a text and makes it sound more formal" : "Sisestatud teksti vormistamine ametlikuna",
"Generate a headline" : "Alapealkirja loomine",
"Generates a possible headline for a text." : "Võimaldab luua teksti põhjal kokkuvõtliku alapealkirja.",
"Original text" : "Lähtetekst",
@@ -298,17 +400,8 @@ OC.L10N.register(
"The desired language to translate the origin text in" : "Keel, millesse lähteteksti tõlgime",
"Result" : "Tulemus",
"The translated text" : "Tõlgitud tekst",
- "File name is a reserved word" : "Failinimi sisaldab keelatud sõna",
- "File name contains at least one invalid character" : "Failinimes on vähemalt üks keelatud tähemärk",
- "File name is too long" : "Failinimi on liiga pikk",
- "Users" : "Kasutajad",
- "%1$s shared »%2$s« with you and wants to add:" : "„%1$s“ jagas sinuga „%2$s“ ning soovib lisada:",
- "%1$s shared »%2$s« with you and wants to add" : "„%1$s“ jagas sinuga „%2$s“ ning soovib lisada",
- "»%s« added a note to a file shared with you" : "„%s“ jagas koos sulle jagatud failiga ka märget",
- "Open »%s«" : "Ava »%s«",
- "%1$s shared »%2$s« with you" : "„%1$s“ jagas sinuga „%2$s“",
- "%1$s shared »%2$s« with you." : "%1$s jagas sinuga „%2$s“ faili.",
- "Click the button below to open it." : "Vajuta allolevat nuppu, et see avada.",
- "File is currently busy, please try again later" : "Fail on hetkel kasutuses, proovi hiljem uuesti"
+ "File is currently busy, please try again later" : "Fail on hetkel kasutuses, proovi hiljem uuesti",
+ "Cannot download file" : "Faili pole võimalik alla laadida",
+ "Login is too long" : "Kasutajanimi on liiga pikk"
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/et_EE.json b/lib/l10n/et_EE.json
index e8db1891012..78bbd2a7591 100644
--- a/lib/l10n/et_EE.json
+++ b/lib/l10n/et_EE.json
@@ -1,8 +1,12 @@
{ "translations": {
"Cannot write into \"config\" directory!" : "Ei saa kirjutada „config“ kausta!!",
+ "This can usually be fixed by giving the web server write access to the config directory." : "Tavaliselt saad selle lahendada andes veebiserverile õigused seadistuse kausta kirjutamiseks",
+ "But, if you prefer to keep config.php file read only, set the option \"config_is_read_only\" to true in it." : "Aga kui soovid, et seadistuste fail ei peaks olema veebiserveri poolt muudetav, siis palun määra seadistusvõtme „config_is_read_only“ väärtuseks true.",
"See %s" : "Vaata %s",
+ "Application %1$s is not present or has a non-compatible version with this server. Please check the apps directory." : "Rakendust „%1$s“ pole serverisse paigaldatud või pole tema versioon ühilduv selle serveriga. Palun kontrolli paigaldatud rakendusi.",
"Sample configuration detected" : "Tuvastati näidisseaded",
- "It has been detected that the sample configuration has been copied. This can break your installation and is unsupported. Please read the documentation before performing changes on config.php" : "Tuvastati, et kopeeriti näidisseaded. See võib lõhkuda sinu saidi ja see pole toetatud. Palun loe enne faili config.php muutmist dokumentatsiooni",
+ "It has been detected that the sample configuration has been copied. This can break your installation and is unsupported. Please read the documentation before performing changes on config.php" : "Tuvastasin, et seadistuse faili kopeeritud näidisseaded. See võib lõhkuda sinu saidi ja see pole toetatud. Palun loe enne faili config.php muutmist dokumentatsiooni",
+ "The page could not be found on the server." : "Seda lehte ei õnnestunud serverist leida.",
"%s email verification" : "E-postiaadressi kinnitamine: %s",
"Email verification" : "E-postiaadressi kinnitamine",
"Click the following button to confirm your email." : "Oma e-postiaadressi kinnitamiseks klõpsi järgmisel nupul.",
@@ -13,12 +17,21 @@
"%1$s, %2$s and %3$s" : "%1$s, %2$s ja %3$s",
"%1$s, %2$s, %3$s and %4$s" : "%1$s, %2$s, %3$s ja %4$s",
"%1$s, %2$s, %3$s, %4$s and %5$s" : "%1$s, %2$s, %3$s, %4$s ja %5$s",
+ "Education bundle" : "Rakenduste komplekt haridusasutustele",
+ "Enterprise bundle" : "Rakenduste komplekt suurorganisatsioonidele",
+ "Groupware bundle" : "Rühmatarkvara rakenduste komplekt",
+ "Hub bundle" : "Rakenduste komplekt Nextcloud Hub",
+ "Public sector bundle" : "Rakenduste komplekt avaliku sektori asutustele",
+ "Social sharing bundle" : "Rakenduste komplekt sotsiaalmeedias jagamiseks",
"PHP %s or higher is required." : "PHP %s või uuem on nõutav.",
"PHP with a version lower than %s is required." : "Nõutud on PHP madalama versiooniga kui %s.",
+ "%sbit or higher PHP required." : "Vajalik on %s-bitine või parem PHP versioon.",
"The following architectures are supported: %s" : "Toetatud on järgnevad arhitektuurid: %s",
"The following databases are supported: %s" : "Toetatud on järgnevad andmebaasid: %s",
"The command line tool %s could not be found" : "Käsurea töövahendit %s ei leitud",
"The library %s is not available." : "Teek %s pole saadaval.",
+ "Library %1$s with a version higher than %2$s is required - available version %3$s." : "Vajalik on „%1$s“ teek suurema versiooniga kui %2$s - hetkel on versioon %3$s.",
+ "Library %1$s with a version lower than %2$s is required - available version %3$s." : "Vajalik on „%1$s“ teek väiksema versiooniga kui %2$s - hetkel on versioon %3$s.",
"The following platforms are supported: %s" : "Toetatud on järgmised platvormid: %s",
"Server version %s or higher is required." : "Nõutav on serveri versioon %s või suurem.",
"Server version %s or lower is required." : "Serveri versioon %s või madalam on nõutav.",
@@ -29,9 +42,11 @@
"Wiping of device %s has started" : "Andmete kustutamine seadmes „%s“ algas",
"Wiping of device »%s« has started" : "Andmete kustutamine seadmes „%s“ algas",
"»%s« started remote wipe" : "„%s“ alustas kaugseadme andmete kustutamist",
+ "Device or application »%s« has started the remote wipe process. You will receive another email once the process has finished" : "„%s“ seade või rakendus on alustanud kaugkustutamise protsessi. Selle lõppemisel saad veel ühe teavitava e-kirja",
"Wiping of device %s has finished" : "Andmete kustutamine seadmes „%s“ lõppes",
"Wiping of device »%s« has finished" : "Andmete kustutamine seadmes „%s“ lõppes",
"»%s« finished remote wipe" : "„%s“ lõpetas kaugseadme andmete kustutamise",
+ "Device or application »%s« has finished the remote wipe process." : "„%s“ seade või rakendus on lõpetanud kaugkustutamise protsessi.",
"Remote wipe started" : "Kaugkustutamine on alanud",
"A remote wipe was started on device %s" : "„%s“ seadme kaugkustutamine on alanud",
"Remote wipe finished" : "Kaugkustutamine on lõppenud",
@@ -68,6 +83,7 @@
"in a few seconds" : "mõne sekundi jooksul",
"seconds ago" : "sekundit tagasi",
"Empty file" : "Tühi fail",
+ "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "Moodulit tunnusega „%s“ pole pole olemas. Palun taga see oma rakenduste seadistustest või võta ühendust peakasutajaga.",
"No file conversion providers available" : "Ühtegi teisendusteenuse pakkujat pole saadaval",
"File is too large to convert" : "Fail on teisendamiseks liiga suur",
"Destination does not match conversion extension" : "Sihtmeedia ei vasta teisendamislaiendile",
@@ -75,6 +91,8 @@
"Destination does not exist" : "Sihtmeediat pole olemas",
"Destination is not creatable" : "Sihtmeedia pole loodav",
"Dot files are not allowed" : "Punktiga failid pole lubatud",
+ "%1$s (renamed)" : "%1$s (nimi on muudetud)",
+ "renamed file" : "muudetud nimega fail",
"\"%1$s\" is a forbidden file or folder name." : "„%1$s“ on keelatud faili- või kaustanimi.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "„%1$s“ on keelatud faili- või kaustanime eesliide.",
"\"%1$s\" is not allowed inside a file or folder name." : "„%1$s“ pole faili- või kaustanimes lubatud.",
@@ -97,6 +115,7 @@
"Filename contains at least one invalid character" : "Failinimes on vähemalt üks keelatud märk",
"Filename is too long" : "Failinimi on liiga pikk",
"Empty filename is not allowed" : "Tühi failinimi pole lubatud",
+ "App \"%s\" cannot be installed because appinfo file cannot be read." : "Kuna „appinfo“ faili pole võimalik lugeda, siis „%s“ rakendust ei saa paigaldada.",
"App \"%s\" cannot be installed because it is not compatible with this version of the server." : "Kuna ta pole ühilduv selle serveri versiooniga, siis „%s“ rakendust ei saa paigaldada.",
"__language_name__" : "Eesti",
"This is an automatically sent email, please do not reply." : "See on automaatselt saadetud e-kiri, palun ära vasta.",
@@ -128,6 +147,7 @@
"Pronouns" : "Asesõnad pöördumisel",
"Unknown account" : "Tundmatu kasutajakonto",
"Additional settings" : "Lisaseaded",
+ "Enter the database Login and name for %s" : "Andmebaasi kasutajanimi ning nimi %si jaoks",
"Enter the database Login for %s" : "Sisesta andmebaasi %s kasutajatunnus",
"Enter the database name for %s" : "Sisesta andmebaasi %s nimi",
"You cannot use dots in the database name %s" : "Sa ei tohi kasutada „%s“ andmebaasi nimes punkte",
@@ -151,6 +171,7 @@
"%1$s shared %2$s with you and wants to add:" : "%1$s jagas sinuga %2$s ning soovib lisada:",
"%1$s shared %2$s with you and wants to add" : "%1$s jagas sinuga %2$s ning soovib lisada",
"%s added a note to a file shared with you" : "%s jagas koos sulle jagatud failiga ka märget",
+ "Passwords are enforced for link and mail shares" : "Linkide ja e-posti teel levitatava jaosmeedia puhul on salasõnade kasutamine nõutav",
"Share recipient is not a valid user" : "Jaosmeedia vastuvõtja pole korrektne kasutaja",
"Share recipient is not a valid group" : "Jaosmeedia vastuvõtja pole korrektne grupp",
"Share recipient should be empty" : "Jaosmeedia vastuvõtja peaks jääma tühjaks",
@@ -171,9 +192,11 @@
"Files cannot be shared with create permissions" : "Loomisõigustega faile ei saa jagada",
"Expiration date is in the past" : "Aegumise kuupäev on minevikus",
"Expiration date is enforced" : "Aegumiskuupäev on kasutusel",
+ "_Cannot set expiration date more than %n day in the future_::_Cannot set expiration date more than %n days in the future_" : ["Aegumist ei saa lisada kaugemale, kui %n päev tulevikus.","Aegumist ei saa lisada kaugemale, kui %n päeva tulevikus."],
"Sharing is only allowed with group members" : "Jagamine on lubatud vaid grupi liikmetega",
- "Sharing %s failed, because this item is already shared with the account %s" : "%s jagamine ebaõnnestus, kuna seda üksust on juba jagatud kontoga %s",
+ "Sharing %s failed, because this item is already shared with the account %s" : "%s jagamine ei õnnestunud, kuna seda objekti on juba jagatud kontoga %s",
"Group sharing is now allowed" : "Grupile jagamine on nüüd lubatud",
+ "Sharing is only allowed within your own groups" : "Jagamine on lubatud vaid sinu oma grupi liikmetega",
"Path is already shared with this group" : "Asukoht on selle grupiga juba jagatud",
"Link sharing is not allowed" : "Lingi jagamine pole lubatud",
"Public upload is not allowed" : "Avalik üleslaadimine pole lubatud",
@@ -181,11 +204,14 @@
"Sharing is disabled" : "Jagamine pole kasutusel",
"Sharing is disabled for you" : "Jagamine pole sinu jaoks kasutusel",
"Cannot share with the share owner" : "Sa ei saa jagada jaosmeedia omanikule",
+ "Share does not have a full ID" : "Jaosmeedial on täismahuline tunnus puudu",
"Cannot change share type" : "Sa ei saa muuta jaosmeedia tüüpi",
+ "Can only update recipient on user shares" : "Kasutaja jaosmeedia saajat ei õnnestu uuendada",
"Invalid share recipient" : "Vigane jaosmeedia vastuvõtja",
"Group \"%s\" does not exist" : "„%s“ gruppi pole olemas",
"The requested share does not exist anymore" : "Soovitud jagamist enam ei eksisteeri",
- "Could not find category \"%s\"" : "Ei leia kategooriat \"%s\"",
+ "The requested share comes from a disabled user" : "Soovitud jaosmeedia on loonud blokeeritud kasutaja",
+ "Could not find category \"%s\"" : "Ei leia kategooriat „%s“",
"Input text" : "Sisendtekst",
"The input text" : "Sisendtekst",
"Sunday" : "Pühapäev",
@@ -233,10 +259,16 @@
"Oct." : "Okt.",
"Nov." : "Nov.",
"Dec." : "Dets.",
- "A valid password must be provided" : "Sisesta nõuetele vastav parool",
+ "A valid password must be provided" : "Sisesta nõuetele vastav salasõna",
"The Login is already being used" : "See kasutajanimi on juba kasutusel",
"Could not create account" : "Kasutajakonto loomine ei õnnestunud",
- "Login is too long" : "Kasutajanimi on liiga pikk",
+ "Only the following characters are allowed in an Login: \"a-z\", \"A-Z\", \"0-9\", spaces and \"_.@-'\"" : "Kasutajanimes on lubatud ainult järgmised tähemärgid: „a-z“, „A-Z“, „0-9“, ja „_.@-'“",
+ "A valid Login must be provided" : "Palun sisesta korrektne kasutajanimi",
+ "Login contains whitespace at the beginning or at the end" : "Kasutajanime alguses või lõpus on tühik",
+ "Login must not consist of dots only" : "Kasutajanimi ei tohi koosneda ainult punktidest",
+ "Username is too long" : "Kasutajanimi on liiga pikk",
+ "Login is invalid because files already exist for this user" : "See kasutajanimi ei sobi, kuna sellise kasutaja faile on juba olemas",
+ "Account disabled" : "Konto pole kasutusel",
"Login canceled by app" : "Rakendus katkestas sisselogimise",
"App \"%1$s\" cannot be installed because the following dependencies are not fulfilled: %2$s" : "„%1$s“ rakendust ei saa paigaldada, sest järgnev sõltuvus on puudu: %2$s",
"a safe home for all your data" : "turvaline koht sinu andmetele",
@@ -244,21 +276,39 @@
"Authentication error" : "Autentimise viga",
"Token expired. Please reload page." : "Kontrollkood aegus. Paelun laadi leht uuesti.",
"No database drivers (sqlite, mysql, or postgresql) installed." : "Ühtegi andmebaasi (sqlite, mysql või postgresql) draiverit pole paigaldatud.",
+ "Cannot write into \"config\" directory." : "Pole õigust kirjutada „config“ kausta.",
+ "This can usually be fixed by giving the web server write access to the config directory. See %s" : "Tavaliselt saad selle lahendada andes veebiserverile õigused seadistuse kausta kirjutamiseks. Vaata siia: %s",
+ "Or, if you prefer to keep config.php file read only, set the option \"config_is_read_only\" to true in it. See %s" : "Aga kui soovid, et config.pho seadistuste fail ei peaks olema veebiserveri poolt muudetav, siis palun määra seadistusvõtme „config_is_read_only“ väärtuseks true. Lisateavet leiad: %s",
+ "Cannot write into \"apps\" directory." : "Pole õigust kirjutada „apps“ kausta.",
+ "This can usually be fixed by giving the web server write access to the apps directory or disabling the App Store in the config file." : "Tavaliselt saad selle lahendada andes veebiserverile õigused rakenduste kausta kirjutamiseks. Alternatiivina võid ka Nextcloudi rakendustepoe kasutamise keelata.",
"Cannot create \"data\" directory." : "„data“ kausta loomine ei õnnestunud.",
+ "This can usually be fixed by giving the web server write access to the root directory. See %s" : "Tavaliselt saad selle lahendada andes veebiserverile õigused juurkausta kirjutamiseks. Vaata siia: %s",
+ "Permissions can usually be fixed by giving the web server write access to the root directory. See %s." : "Tavaliselt saad õiguste vea lahendada andes veebiserverile õigused juurkausta kirjutamiseks. Vaata siia: %s",
"Your data directory is not writable." : "Sinu serveri andmekaust pole kirjutatav.",
"Setting locale to %s failed." : "Ei õnnestunud määrata lokaadi väärtuseks „%s“.",
"Please install one of these locales on your system and restart your web server." : "Palun paigalda mõni neist lokaatidest oma serverisse ning taaskäivita veebiserver.",
"PHP module %s not installed." : "PHP moodulit %s pole paigaldatud.",
"Please ask your server administrator to install the module." : "Palu oma serveri haldajal moodul paigadalda.",
- "PHP setting \"%s\" is not set to \"%s\"." : "PHP seade \"%s\" ei ole \"%s\".",
+ "PHP setting \"%s\" is not set to \"%s\"." : "PHP seadistuse „%s“ väärtuseks ei ole „%s“.",
"Adjusting this setting in php.ini will make Nextcloud run again" : "Selle seadistuse kohendamine php.ini failis võimaldab sul Nextcloudi uuesti tööle saada",
+ "<code>mbstring.func_overload</code> is set to <code>%s</code> instead of the expected value <code>0</code>." : "<code>mbstring.func_overload</code> muutuja väärtus on hetkel <code>%s</code>, pigem eeldaks väärtust <code>0</code>.",
+ "To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini." : "Vea parandamiseks muuda oma veebiserveri php.ini failis <code>mbstring.func_overload</code> väärtuseks <code>0</code>.",
+ "PHP is apparently set up to strip inline doc blocks. This will make several core apps inaccessible." : "PHP on seadistatud eemaldama „inline“ dokumendi blokke. See muudab mõned tuumikrakendused kasutamatuteks.",
"This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "See on tõenäoliselt põhjustatud puhver/kiirendist nagu Zend OPcache või eAccelerator.",
"PHP modules have been installed, but they are still listed as missing?" : "PHP moodulid on paigaldatud, kuid neid näitatakse endiselt kui puuduolevad?",
"Please ask your server administrator to restart the web server." : "Palu oma serveri haldajal veebiserver taaskäivitada.",
+ "The required %s config variable is not configured in the config.php file." : "Nõutav seadistuste muutuja „%s“ puudub sonfig.php failist.",
+ "Please ask your server administrator to check the Nextcloud configuration." : "Palu oma serveri haldajal Nextcloudi seadistusi kontrollida.",
+ "Your data directory is readable by other people." : "Sinu andmete kaust on loetav teiste kasutajate poolt.",
+ "Please change the permissions to 0770 so that the directory cannot be listed by other people." : "Palun muuda kausta õigused 0770-ks, et kausta sisu poleks teistele kasutajatele nähtav.",
"Your data directory must be an absolute path." : "Andmekausta asukoht peab olema absoluutne aadress.",
- "Your data directory is invalid." : "Sinu andmekataloog on vigane",
+ "Check the value of \"datadirectory\" in your configuration." : "Palun kontrolli „datadirectory“ väärtust selle paigalduse seadistustes.",
+ "Your data directory is invalid." : "Sinu andmekaust on vigane.",
+ "Ensure there is a file called \"%1$s\" in the root of the data directory. It should have the content: \"%2$s\"" : "Palun taga, et andmete juurkaustas leidub fail „%1$s“, mille sisuks on „%2$s“",
"Action \"%s\" not supported or implemented." : "„%s“ tegevus pole toetatud või implementeeritud.",
- "Parameters missing in order to complete the request. Missing Parameters: \"%s\"" : "Päringu lõpetamiseks on puudu järgmised parameetrid; „%s“",
+ "Authentication failed, wrong token or provider ID given" : "Autentimine ei õnnestunud - kas tunnusluba või teenusepakkuja tunnus on vale",
+ "Parameters missing in order to complete the request. Missing Parameters: \"%s\"" : "Päringu lõpetamiseks on puudu järgmised parameetrid: „%s“",
+ "ID \"%1$s\" already used by cloud federation provider \"%2$s\"" : "„%1$s“ tunnus on juba kasutusel liitpilve serveris „%2$s“",
"Cloud Federation Provider with ID: \"%s\" does not exist." : "Liitpilve teenusepakkujat tunnusega „%s“ pole olemas.",
"Could not obtain lock type %d on \"%s\"." : "Ei suutnud hankida %d tüüpi lukustust asukohas „%s“.",
"Storage unauthorized. %s" : "Andmeruum on autoriseerimata. %s",
@@ -266,7 +316,39 @@
"Storage connection error. %s" : "Viga andmeruumi ühenduse loomisel. %s",
"Storage is temporarily not available" : "Salvestusruum pole ajutiselt kättesaadav",
"Storage connection timeout. %s" : "Aegumine andmeruumi ühenduse loomisel. %s",
- "Generate image" : "Piltide loomine",
+ "Transcribe audio" : "Kirjuta heli üles",
+ "Transcribe the things said in an audio" : "Kirjuta üles helifailis kuuldav jutt",
+ "Audio input" : "Helisisend",
+ "The audio to transcribe" : "Üleskirjutatav helifail",
+ "Transcription" : "Üleskirjutus",
+ "The transcribed text" : "Üleskirjutatud tekst",
+ "Chat with an agent" : "Vestle robotagendiga",
+ "Chat message" : "Vestluse sõnum",
+ "A chat message to send to the agent." : "Robotagendile saadetav sõnum.",
+ "Confirmation" : "Kinnitus",
+ "Whether to confirm previously requested actions: 0 for denial and 1 for confirmation." : "Kas peaksime eelmised tegevuse kinnitama: keeldumist märgib 0 ja nõustumist 1.",
+ "Conversation token" : "Vestluse tunnusluba",
+ "A token representing the conversation." : "Tunnusluba vestluse tuvastamiseks.",
+ "Generated response" : "Loodud vastus",
+ "The response from the chat model." : "Vastus tehisarupõhise vestluse mudelilt.",
+ "The new conversation token" : "Vestluse uus tunnusluba",
+ "Send this along with the next interaction." : "Saada see kaasa järgmise päringuga.",
+ "Requested actions by the agent" : "Ülesanded tehisaru agendile",
+ "Actions that the agent would like to carry out in JSON format." : "Tehisaru agendile antavad ülesanded JSON-vormingus.",
+ "Context write" : "Kontekstuaalne kirjutamine",
+ "Writes text in a given style based on the provided source material." : "Kirjutab etteantud lähtematerjali lausel teksti üles.",
+ "Writing style" : "Kirjutamisstiil",
+ "Demonstrate a writing style that you would like to immitate" : "Näita sellist kirjutamisstiili, mida tahad jäljendada",
+ "Source material" : "Lähtematerjal",
+ "The content that would like to be rewritten in the new writing style" : "Sisu, mida tahaksid uues stiilis ümber kirjutada",
+ "Generated text" : "Koostatud tekst",
+ "The generated text with content from the source material in the given style" : "Antud stiilis lähtematerjali alusel koostatud tekst",
+ "Emoji generator" : "Emojide looja",
+ "Takes text and generates a representative emoji for it." : "Võtab aluseks teksti ja lood selle alusel emoji.",
+ "The text to generate an emoji for" : "Lähtetekst, millest lood emoji",
+ "Generated emoji" : "Loodud emoji",
+ "The generated emoji based on the input text" : "Sisestatud teksti alusel loodud emoji",
+ "Generate image" : "Pildiloome",
"Generate an image from a text prompt" : "Loo tekstisisendist pilt",
"Prompt" : "Sisendvorm",
"Describe the image you want to generate" : "Kirjelda loodavat pilti",
@@ -274,6 +356,26 @@
"How many images to generate" : "Mitu pilti peaksime tekitama",
"Output images" : "Väljundpildid",
"The generated images" : "Loodud pildid",
+ "Generate speech" : "Koosta kõne",
+ "Generate speech from a transcript" : "Koosta üleskirjutusest kõne",
+ "Write transcript that you want the assistant to generate speech from" : "Kirjuta üles see, mille alusel tahad Abilisel lasta koostada kõne",
+ "Output speech" : "Kõneväljund",
+ "The generated speech" : "Koostatud kõne",
+ "Change Tone" : "Teksti tooni muutmine",
+ "Change the tone of a piece of text." : "Muuda antud teksti tonaalsust.",
+ "Write a text that you want the assistant to rewrite in another tone." : "Kirjuta üles see, mille tonaalsust tahad Abilisel lasta ümber kirjutada.",
+ "Desired tone" : "Soovitud toon",
+ "In which tone should your text be rewritten?" : "Mis toonis peaks tekst olema ümberkirjutatud?",
+ "The rewritten text in the desired tone, written by the assistant:" : "Abilise poolt soovitud toonis ümberkirjutatud tekst:",
+ "Chat" : "Vestle",
+ "Chat with the assistant" : "Vestle Abilisega",
+ "System prompt" : "Süsteemi viip",
+ "Chat history" : "Vestluse ajalugu",
+ "The history of chat messages before the current message, starting with a message by the user" : "Kasutaja sõnumiga algav vestluse ajalugu enne praegust sõnumit",
+ "Response message" : "Sõnumi vastus",
+ "The generated response as part of the conversation" : "Loodud vastus vestluse osana",
+ "Formalize text" : "Muuda tekst ametlikuks",
+ "Takes a text and makes it sound more formal" : "Sisestatud teksti vormistamine ametlikuna",
"Generate a headline" : "Alapealkirja loomine",
"Generates a possible headline for a text." : "Võimaldab luua teksti põhjal kokkuvõtliku alapealkirja.",
"Original text" : "Lähtetekst",
@@ -296,17 +398,8 @@
"The desired language to translate the origin text in" : "Keel, millesse lähteteksti tõlgime",
"Result" : "Tulemus",
"The translated text" : "Tõlgitud tekst",
- "File name is a reserved word" : "Failinimi sisaldab keelatud sõna",
- "File name contains at least one invalid character" : "Failinimes on vähemalt üks keelatud tähemärk",
- "File name is too long" : "Failinimi on liiga pikk",
- "Users" : "Kasutajad",
- "%1$s shared »%2$s« with you and wants to add:" : "„%1$s“ jagas sinuga „%2$s“ ning soovib lisada:",
- "%1$s shared »%2$s« with you and wants to add" : "„%1$s“ jagas sinuga „%2$s“ ning soovib lisada",
- "»%s« added a note to a file shared with you" : "„%s“ jagas koos sulle jagatud failiga ka märget",
- "Open »%s«" : "Ava »%s«",
- "%1$s shared »%2$s« with you" : "„%1$s“ jagas sinuga „%2$s“",
- "%1$s shared »%2$s« with you." : "%1$s jagas sinuga „%2$s“ faili.",
- "Click the button below to open it." : "Vajuta allolevat nuppu, et see avada.",
- "File is currently busy, please try again later" : "Fail on hetkel kasutuses, proovi hiljem uuesti"
+ "File is currently busy, please try again later" : "Fail on hetkel kasutuses, proovi hiljem uuesti",
+ "Cannot download file" : "Faili pole võimalik alla laadida",
+ "Login is too long" : "Kasutajanimi on liiga pikk"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/eu.js b/lib/l10n/eu.js
index 79bf334e3c1..353f9e8ab5d 100644
--- a/lib/l10n/eu.js
+++ b/lib/l10n/eu.js
@@ -428,20 +428,7 @@ OC.L10N.register(
"Generate headline" : "Sortu izenburua",
"Summarizes text by reducing its length without losing key information." : "Testua laburtzen du bere luzera murrizten informazio baliotsua galdu gabe.",
"Extracts topics from a text and outputs them separated by commas." : "Gaiak ateratzen ditu testu batetik eta komaz banatuta erakusten ditu.",
- "Education Edition" : "Hezkuntza edizioa",
- "File name is a reserved word" : "Fitxategi izena hitz erreserbatua da",
- "File name contains at least one invalid character" : "Fitxategi izenak karaktere baliogabe bat du gutxienez ",
- "File name is too long" : "Fitxategi-izena luzeegia da",
- "Users" : "Erabiltzaileak",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$serabiltzaileak »%2$s« partekatu du zurekin eta hau gehitu nahi du:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$serabiltzaileak »%2$s« partekatu du zurekin eta hau gehitu nahi du",
- "»%s« added a note to a file shared with you" : "»%s« erabiltzaileak ohar bat gehitu du partekatu dizun fitxategi batean",
- "Open »%s«" : "Ireki »%s«",
- "%1$s shared »%2$s« with you" : "%1$serabiltzaileak »%2$s« partekatu du zurekin",
- "%1$s shared »%2$s« with you." : "%1$serabiltzaileak »%2$s« partekatu du zurekin.",
- "Click the button below to open it." : "Egin klik beheko botoian hura irekitzeko.",
"File is currently busy, please try again later" : "Fitxategia lanpetuta dago, saiatu berriro geroago",
- "Cannot download file" : "Ezin da fitxategia deskargatu",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Ziurtatu datu direktorioaren erroan \".ocdata\" izeneko fitxategia dagoela."
+ "Cannot download file" : "Ezin da fitxategia deskargatu"
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/eu.json b/lib/l10n/eu.json
index 48b53840098..1851e22e179 100644
--- a/lib/l10n/eu.json
+++ b/lib/l10n/eu.json
@@ -426,20 +426,7 @@
"Generate headline" : "Sortu izenburua",
"Summarizes text by reducing its length without losing key information." : "Testua laburtzen du bere luzera murrizten informazio baliotsua galdu gabe.",
"Extracts topics from a text and outputs them separated by commas." : "Gaiak ateratzen ditu testu batetik eta komaz banatuta erakusten ditu.",
- "Education Edition" : "Hezkuntza edizioa",
- "File name is a reserved word" : "Fitxategi izena hitz erreserbatua da",
- "File name contains at least one invalid character" : "Fitxategi izenak karaktere baliogabe bat du gutxienez ",
- "File name is too long" : "Fitxategi-izena luzeegia da",
- "Users" : "Erabiltzaileak",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$serabiltzaileak »%2$s« partekatu du zurekin eta hau gehitu nahi du:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$serabiltzaileak »%2$s« partekatu du zurekin eta hau gehitu nahi du",
- "»%s« added a note to a file shared with you" : "»%s« erabiltzaileak ohar bat gehitu du partekatu dizun fitxategi batean",
- "Open »%s«" : "Ireki »%s«",
- "%1$s shared »%2$s« with you" : "%1$serabiltzaileak »%2$s« partekatu du zurekin",
- "%1$s shared »%2$s« with you." : "%1$serabiltzaileak »%2$s« partekatu du zurekin.",
- "Click the button below to open it." : "Egin klik beheko botoian hura irekitzeko.",
"File is currently busy, please try again later" : "Fitxategia lanpetuta dago, saiatu berriro geroago",
- "Cannot download file" : "Ezin da fitxategia deskargatu",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Ziurtatu datu direktorioaren erroan \".ocdata\" izeneko fitxategia dagoela."
+ "Cannot download file" : "Ezin da fitxategia deskargatu"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/fa.js b/lib/l10n/fa.js
index 01e145ad8dc..da77202e434 100644
--- a/lib/l10n/fa.js
+++ b/lib/l10n/fa.js
@@ -2,26 +2,28 @@ OC.L10N.register(
"lib",
{
"Cannot write into \"config\" directory!" : "نمیتوانید داخل دایرکتوری \"config\" تغییراتی ایجاد کنید",
- "This can usually be fixed by giving the web server write access to the config directory." : "This can usually be fixed by giving the web server write access to the config directory.",
- "But, if you prefer to keep config.php file read only, set the option \"config_is_read_only\" to true in it." : "But, if you prefer to keep config.php file read only, set the option \"config_is_read_only\" to true in it.",
+ "This can usually be fixed by giving the web server write access to the config directory." : "این مشکل معمولاً با دادن دسترسی نوشتن به وب‌سرور در دایرکتوری پیکربندی قابل رفع است.",
+ "But, if you prefer to keep config.php file read only, set the option \"config_is_read_only\" to true in it." : "اما، اگر ترجیح می‌دهید فایل config.php فقط خواندنی باشد، گزینه \"config_is_read_only\" را در آن به true تنظیم کنید.",
"See %s" : "مشاهده %s",
- "Application %1$s is not present or has a non-compatible version with this server. Please check the apps directory." : "Application %1$s is not present or has a non-compatible version with this server. Please check the apps directory.",
+ "Application %1$s is not present or has a non-compatible version with this server. Please check the apps directory." : "برنامه %1$s موجود نیست یا نسخه‌ای ناسازگار با این سرور دارد. لطفاً دایرکتوری برنامه‌ها را بررسی کنید.",
"Sample configuration detected" : "فایل پیکربندی نمونه پیدا شد",
"It has been detected that the sample configuration has been copied. This can break your installation and is unsupported. Please read the documentation before performing changes on config.php" : "تشخیص داده شده است که پیکربندی نمونه کپی شده است. این می تواند نصب شما را خراب کند و پشتیبانی نمی شود. لطفاً قبل از انجام تغییرات در config.php ، اسناد را بخوانید",
- "The page could not be found on the server." : "The page could not be found on the server.",
- "%s email verification" : "%s email verification",
- "Email verification" : "Email verification",
- "Click the following button to confirm your email." : "Click the following button to confirm your email.",
- "Click the following link to confirm your email." : "Click the following link to confirm your email.",
- "Confirm your email" : "Confirm your email",
+ "The page could not be found on the server." : "صفحه در سرور یافت نشد.",
+ "%s email verification" : "تأیید ایمیل %s",
+ "Email verification" : "تأیید ایمیل",
+ "Click the following button to confirm your email." : "برای تأیید ایمیل خود روی دکمه زیر کلیک کنید.",
+ "Click the following link to confirm your email." : "برای تأیید ایمیل خود روی لینک زیر کلیک کنید.",
+ "Confirm your email" : "ایمیل خود را تأیید کنید",
"Other activities" : "سایر فعالیت ها",
- "%1$s and %2$s" : "%1$sو%2$s",
- "%1$s, %2$s and %3$s" : "%1$s،%2$sو%3$s",
- "%1$s, %2$s, %3$s and %4$s" : "%1$s،%2$s،%3$sو%4$s",
- "%1$s, %2$s, %3$s, %4$s and %5$s" : "%1$s،%2$s،%3$s،%4$sو%5$s",
+ "%1$s and %2$s" : "%1$s و %2$s",
+ "%1$s, %2$s and %3$s" : "%1$s، %2$s و %3$s",
+ "%1$s, %2$s, %3$s and %4$s" : "%1$s، %2$s، %3$s و %4$s",
+ "%1$s, %2$s, %3$s, %4$s and %5$s" : "%1$s، %2$s، %3$s، %4$s و %5$s",
+ "Education bundle" : "بسته آموزشی",
"Enterprise bundle" : "بستهٔ سازمانی",
"Groupware bundle" : "بستهٔ کار گروهی",
"Hub bundle" : "بستهٔ هسته‌ای",
+ "Public sector bundle" : "بسته بخش عمومی",
"Social sharing bundle" : "بستهٔ هم‌رسانی اجتماعی",
"PHP %s or higher is required." : "PHP نسخه‌ی %s یا بالاتر نیاز است.",
"PHP with a version lower than %s is required." : "نیاز به نگارش پایین‌تر از %s پی‌اچ‌پی.",
@@ -35,26 +37,34 @@ OC.L10N.register(
"The following platforms are supported: %s" : "بن‌سازه‌های زیر پشتیبانی می‌شوند: %s",
"Server version %s or higher is required." : "نیاز به کارساز با نگارش %s یا بالاتر.",
"Server version %s or lower is required." : "نیاز به کارساز با نگارش %s یا پایین‌تر.",
- "Wiping of device %s has started" : "پاک کردن دستگاه%s شروع شده است",
- "Wiping of device »%s« has started" : "پاک کردن دستگاه%s شروع شده است",
- "»%s« started remote wipe" : "%sپاک کردن از راه دور",
- "Device or application »%s« has started the remote wipe process. You will receive another email once the process has finished" : "دستگاه یا برنامه%s فرآیند پاک کردن از راه دور را آغاز کرده است. پس از اتمام مراحل ، ایمیل دیگری دریافت خواهید کرد",
- "Wiping of device %s has finished" : "پاک کردن دستگاه %sبه پایان رسیده است",
- "Wiping of device »%s« has finished" : "پاک کردن دستگاه %sبه پایان رسیده است",
- "»%s« finished remote wipe" : "%sپاک کردن از راه دور",
- "Device or application »%s« has finished the remote wipe process." : "دستگاه یا برنامه %sفرآیند پاک کردن از راه دور را به پایان رسانده است.",
+ "Logged in account must be an admin, a sub admin or gotten special right to access this setting" : "حساب وارد شده باید یک مدیر، یک مدیر فرعی یا دارای حق دسترسی ویژه برای دسترسی به این تنظیم باشد",
+ "Your current IP address doesn't allow you to perform admin actions" : "آدرس IP فعلی شما اجازه انجام اقدامات مدیریتی را به شما نمی‌دهد",
+ "Logged in account must be an admin or sub admin" : "حساب وارد شده باید یک مدیر یا مدیر فرعی باشد",
+ "Logged in account must be an admin" : "حساب وارد شده باید یک مدیر باشد",
+ "Wiping of device %s has started" : "پاک کردن دستگاه %s آغاز شد",
+ "Wiping of device »%s« has started" : "پاک کردن دستگاه «%s» آغاز شد",
+ "»%s« started remote wipe" : "«%s» پاک کردن از راه دور را آغاز کرد",
+ "Device or application »%s« has started the remote wipe process. You will receive another email once the process has finished" : "دستگاه یا برنامه «%s» فرآیند پاک کردن از راه دور را آغاز کرده است. پس از اتمام مراحل، ایمیل دیگری دریافت خواهید کرد.",
+ "Wiping of device %s has finished" : "پاک کردن دستگاه %s به پایان رسید",
+ "Wiping of device »%s« has finished" : "پاک کردن دستگاه «%s» به پایان رسید",
+ "»%s« finished remote wipe" : "«%s» پاک کردن از راه دور را به پایان رساند",
+ "Device or application »%s« has finished the remote wipe process." : "دستگاه یا برنامه «%s» فرآیند پاک کردن از راه دور را به پایان رسانده است.",
"Remote wipe started" : "پاک کردن از راه دور شروع شد",
- "A remote wipe was started on device %s" : "پاک کردن از راه دور روی دستگاه شروع شد%s",
+ "A remote wipe was started on device %s" : "پاک کردن از راه دور روی دستگاه %s شروع شد",
"Remote wipe finished" : "پاک کردن از راه دور به پایان رسید",
- "The remote wipe on %s has finished" : "پاک کردن از راه دور روی%s کار تمام شد",
+ "The remote wipe on %s has finished" : "پاک کردن از راه دور روی %s کار تمام شد",
"Authentication" : "احراز هویت",
"Unknown filetype" : "نوع فایل ناشناخته",
"Invalid image" : "عکس نامعتبر",
"Avatar image is not square" : "تصویر آواتار مربع نیست",
"Files" : "پوشه‌ها",
"View profile" : "مشاهدهٔ نمایه",
- "_%nh_::_%nh_" : ["%nh","%nh"],
- "Local time: %s" : "Local time: %s",
+ "same time" : "همزمان",
+ "_%nh_::_%nh_" : ["%n ساعت","%n ساعت"],
+ "_%nm_::_%nm_" : ["%n دقیقه","%n دقیقه"],
+ "%s ahead" : "%s جلوتر",
+ "%s behind" : "%s عقب‌تر",
+ "Local time: %s" : "زمان محلی: %s",
"today" : "امروز",
"tomorrow" : "فردا",
"yesterday" : "دیروز",
@@ -75,13 +85,37 @@ OC.L10N.register(
"in a few seconds" : "در چند ثانیه",
"seconds ago" : "ثانیه‌ها پیش",
"Empty file" : "پروندهٔ خالی",
- "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "ماژول با شناسه:%s وجود ندارد. لطفاً آن را در تنظیمات برنامه خود فعال کنید یا با سرپرست خود تماس بگیرید",
+ "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "ماژول با شناسه: %s وجود ندارد. لطفاً آن را در تنظیمات برنامه خود فعال کنید یا با سرپرست خود تماس بگیرید.",
+ "No file conversion providers available" : "ارائه‌دهنده تبدیل فایل در دسترس نیست",
+ "File is too large to convert" : "فایل برای تبدیل خیلی بزرگ است",
+ "Destination does not match conversion extension" : "مقصد با پسوند تبدیل مطابقت ندارد",
+ "Could not convert file" : "فایل قابل تبدیل نبود",
+ "Destination does not exist" : "مقصد وجود ندارد",
+ "Destination is not creatable" : "مقصد قابل ایجاد نیست",
"Dot files are not allowed" : "پرونده‌های نقطه‌دار مجاز نیستند",
+ "%1$s (renamed)" : "%1$s (تغییر نام داده شد)",
+ "renamed file" : "فایل تغییر نام داده شد",
+ "\"%1$s\" is a forbidden file or folder name." : "«%1$s» یک نام فایل یا پوشه ممنوع است.",
+ "\"%1$s\" is a forbidden prefix for file or folder names." : "«%1$s» یک پیشوند ممنوع برای نام فایل یا پوشه است.",
+ "\"%1$s\" is not allowed inside a file or folder name." : "«%1$s» در نام فایل یا پوشه مجاز نیست.",
+ "\"%1$s\" is a forbidden file type." : "«%1$s» یک نوع فایل ممنوع است.",
+ "Filenames must not end with \"%1$s\"." : "نام فایل‌ها نباید با «%1$s» به پایان برسند.",
+ "Invalid parent path" : "مسیر والد نامعتبر",
"File already exists" : "پرونده از پیش موجود است",
"Invalid path" : "مسیر نامعتبر",
"Failed to create file from template" : "شکست در ایجاد پرونده از قالب",
"Templates" : "قالب‌ها",
+ "Storage %s cannot be moved" : "حافظه %s قابل جابجایی نیست",
+ "Moving a share (%s) into a shared folder is not allowed" : "انتقال یک اشتراک (%s) به یک پوشه مشترک مجاز نیست",
+ "Moving a storage (%s) into a shared folder is not allowed" : "انتقال یک حافظه (%s) به یک پوشه مشترک مجاز نیست",
+ "Moving a share (%s) into another share (%s) is not allowed" : "انتقال یک اشتراک (%s) به اشتراک دیگر (%s) مجاز نیست",
+ "Moving a share (%s) into another storage (%s) is not allowed" : "انتقال یک اشتراک (%s) به حافظه دیگر (%s) مجاز نیست",
+ "Moving a storage (%s) into a share (%s) is not allowed" : "انتقال یک حافظه (%s) به یک اشتراک (%s) مجاز نیست",
+ "Moving a storage (%s) into another storage (%s) is not allowed" : "انتقال یک حافظه (%s) به حافظه دیگر (%s) مجاز نیست",
+ "Path contains invalid segments" : "مسیر شامل بخش‌های نامعتبر است",
+ "Filename is a reserved word" : "نام فایل یک کلمه رزرو شده است",
"Filename contains at least one invalid character" : "نام فایل حداقل دارای یک کاراکتر نامعتبر است",
+ "Filename is too long" : "نام فایل بیش از حد طولانی است",
"Empty filename is not allowed" : "نام فایل نمی‌تواند خالی باشد",
"App \"%s\" cannot be installed because appinfo file cannot be read." : "کارهٔ «%s» به دلیل ناتوانی در خواندن پروندهٔ appinfo نمی‌تواند نصب شود.",
"App \"%s\" cannot be installed because it is not compatible with this version of the server." : "کارهٔ «%s» به دلیل سازگار نبودن با این نگارش از کارساز نمی‌تواند نصب شود.",
@@ -97,8 +131,8 @@ OC.L10N.register(
"Accounts" : "حساب‌ها",
"Email" : "رایانامه",
"Mail %s" : "نامه به %s",
- "Fediverse" : "Fediverse",
- "View %s on the fediverse" : "View %s on the fediverse",
+ "Fediverse" : "فدیورس",
+ "View %s on the fediverse" : "مشاهده %s در فدیورس",
"Phone" : "تلفن",
"Call %s" : "تماس با %s",
"Twitter" : "توییتر",
@@ -108,35 +142,87 @@ OC.L10N.register(
"Address" : "نشانی",
"Profile picture" : "تصویر نمایه",
"About" : "درباره",
- "Display name" : "Display name",
+ "Display name" : "نام نمایشی",
"Headline" : "عنوان",
"Organisation" : "سازمان",
"Role" : "نقش",
+ "Pronouns" : "ضمایر",
+ "Unknown account" : "حساب ناشناخته",
"Additional settings" : "تنظیمات اضافی",
+ "Enter the database Login and name for %s" : "نام کاربری و نام پایگاه داده را برای %s وارد کنید",
+ "Enter the database Login for %s" : "نام کاربری پایگاه داده را برای %s وارد کنید",
"Enter the database name for %s" : "ورود نام پایگاه داده برای %s",
"You cannot use dots in the database name %s" : "نمی‌توانید در در نام پایگاه دادهٔ %s از نقطه استفاده کنید",
+ "MySQL Login and/or password not valid" : "نام کاربری و/یا رمز عبور MySQL نامعتبر است",
"You need to enter details of an existing account." : "لازم است جزییات یک حساب موحود را وارد کنید.",
"Oracle connection could not be established" : "ارتباط اراکل نمیتواند برقرار باشد.",
+ "Oracle Login and/or password not valid" : "نام کاربری و/یا رمز عبور Oracle نامعتبر است",
+ "PostgreSQL Login and/or password not valid" : "نام کاربری و/یا رمز عبور PostgreSQL نامعتبر است",
+ "Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk!" : "Mac OS X پشتیبانی نمی‌شود و %s روی این پلتفرم به درستی کار نخواهد کرد. با مسئولیت خودتان از آن استفاده کنید!",
"For the best results, please consider using a GNU/Linux server instead." : "برای بهترین نتیجه، استفاده از یک کارساز گنو/لینوکسی را در نظر داشته باشید.",
- "It seems that this %s instance is running on a 32-bit PHP environment and the open_basedir has been configured in php.ini. This will lead to problems with files over 4 GB and is highly discouraged." : "به نظر می رسد%s که این نمونه در یک محیط PHP 32 بیتی در حال اجرا است و open_baseir در php.ini پیکربندی شده است. این مسئله به پرونده هایی با بیش از 4 گیگ منجر می شود و بسیار دلسرد می شود",
- "Please remove the open_basedir setting within your php.ini or switch to 64-bit PHP." : "لطفاً تنظیمات open_baseir را درون php.ini خود حذف کنید یا به PHP 64 بیتی تغییر دهید.",
+ "It seems that this %s instance is running on a 32-bit PHP environment and the open_basedir has been configured in php.ini. This will lead to problems with files over 4 GB and is highly discouraged." : "به نظر می رسد %s که این نمونه در یک محیط PHP 32 بیتی در حال اجرا است و open_basedir در php.ini پیکربندی شده است. این مسئله به پرونده هایی با بیش از 4 گیگ منجر می شود و بسیار دلسرد می شود.",
+ "Please remove the open_basedir setting within your php.ini or switch to 64-bit PHP." : "لطفاً تنظیمات open_basedir را درون php.ini خود حذف کنید یا به PHP 64 بیتی تغییر دهید.",
+ "Set an admin Login." : "یک نام کاربری برای مدیر تنظیم کنید.",
"Set an admin password." : "یک رمزعبور برای مدیر تنظیم نمایید.",
- "Cannot create or write into the data directory %s" : "Cannot create or write into the data directory %s",
- "Sharing backend %s must implement the interface OCP\\Share_Backend" : "به اشتراک گذاشتن باطن باید رابط OCP \\ Share_Backend %sرا پیاده سازی کند",
- "Sharing backend %s not found" : "به اشتراک گذاشتن باطن%s یافت نشد",
- "Sharing backend for %s not found" : "به اشتراک گذاشتن باطن برای%s یافت نشد",
+ "Cannot create or write into the data directory %s" : "نمی‌توان در دایرکتوری داده %s ایجاد یا نوشت",
+ "Sharing backend %s must implement the interface OCP\\Share_Backend" : "بک‌اند اشتراک‌گذاری %s باید رابط OCP\\Share_Backend را پیاده‌سازی کند",
+ "Sharing backend %s not found" : "بک‌اند اشتراک‌گذاری %s یافت نشد",
+ "Sharing backend for %s not found" : "بک‌اند اشتراک‌گذاری برای %s یافت نشد",
+ "%1$s shared %2$s with you" : "%1$s %2$s را با شما به اشتراک گذاشت",
+ "Open %s" : "باز کردن %s",
"%1$s via %2$s" : "%1$s از طریق %2$s",
+ "%1$s shared %2$s with you and wants to add:" : "%1$s %2$s را با شما به اشتراک گذاشت و می‌خواهد اضافه کند:",
+ "%1$s shared %2$s with you and wants to add" : "%1$s %2$s را با شما به اشتراک گذاشت و می‌خواهد اضافه کند",
+ "%s added a note to a file shared with you" : "%s یک یادداشت به فایلی که با شما به اشتراک گذاشته شده است اضافه کرد",
+ "Passwords are enforced for link and mail shares" : "رمزهای عبور برای اشتراک‌گذاری لینک و ایمیل اجباری هستند",
+ "Share recipient is not a valid user" : "گیرنده اشتراک یک کاربر معتبر نیست",
+ "Share recipient is not a valid group" : "گیرنده اشتراک یک گروه معتبر نیست",
+ "Share recipient should be empty" : "گیرنده اشتراک باید خالی باشد",
+ "Share recipient should not be empty" : "گیرنده اشتراک نباید خالی باشد",
+ "Share recipient is not a valid circle" : "گیرنده اشتراک یک دایره معتبر نیست",
"Unknown share type" : "نوع اشتراک ناشناخته",
- "You are not allowed to share %s" : "شما مجاز به اشتراک گذاری نیستید%s",
- "Cannot increase permissions of %s" : "Cannot increase permissions of %s",
- "Files cannot be shared with delete permissions" : "Files cannot be shared with delete permissions",
- "Files cannot be shared with create permissions" : "Files cannot be shared with create permissions",
+ "Share initiator must be set" : "شروع‌کننده اشتراک باید تنظیم شود",
+ "Cannot share with yourself" : "نمی‌توانید با خودتان به اشتراک بگذارید",
+ "Shared path must be set" : "مسیر مشترک باید تنظیم شود",
+ "Shared path must be either a file or a folder" : "مسیر مشترک باید یک فایل یا یک پوشه باشد",
+ "You cannot share your root folder" : "نمی‌توانید پوشه ریشه خود را به اشتراک بگذارید",
+ "You are not allowed to share %s" : "شما مجاز به اشتراک گذاری %s نیستید",
+ "Valid permissions are required for sharing" : "مجوزهای معتبر برای اشتراک‌گذاری لازم است",
+ "File shares cannot have create or delete permissions" : "اشتراک‌گذاری فایل‌ها نمی‌تواند مجوزهای ایجاد یا حذف داشته باشد",
+ "Cannot increase permissions of %s" : "نمی‌توان مجوزهای %s را افزایش داد",
+ "Shares need at least read permissions" : "اشتراک‌گذاری‌ها حداقل به مجوزهای خواندن نیاز دارند",
+ "Files cannot be shared with delete permissions" : "فایل‌ها را نمی‌توان با مجوزهای حذف به اشتراک گذاشت",
+ "Files cannot be shared with create permissions" : "فایل‌ها را نمی‌توان با مجوزهای ایجاد به اشتراک گذاشت",
"Expiration date is in the past" : "تاریخ انقضا در گذشته است",
- "_Cannot set expiration date more than %n day in the future_::_Cannot set expiration date more than %n days in the future_" : ["Cannot set expiration date more than %n day in the future","Cannot set expiration date more than %n days in the future"],
- "Sharing is only allowed with group members" : "Sharing is only allowed with group members",
+ "Expiration date is enforced" : "تاریخ انقضا اجباری است",
+ "_Cannot set expiration date more than %n day in the future_::_Cannot set expiration date more than %n days in the future_" : ["نمی‌توان تاریخ انقضا را بیش از %n روز در آینده تنظیم کرد","نمی‌توان تاریخ انقضا را بیش از %n روز در آینده تنظیم کرد"],
+ "Sharing is only allowed with group members" : "اشتراک‌گذاری فقط با اعضای گروه مجاز است",
+ "Sharing %s failed, because this item is already shared with the account %s" : "اشتراک‌گذاری %s ناموفق بود، زیرا این مورد قبلاً با حساب %s به اشتراک گذاشته شده است",
+ "Group sharing is now allowed" : "اشتراک‌گذاری گروهی اکنون مجاز است",
+ "Sharing is only allowed within your own groups" : "اشتراک‌گذاری فقط در گروه‌های خودتان مجاز است",
+ "Path is already shared with this group" : "این مسیر قبلاً با این گروه به اشتراک گذاشته شده است",
+ "Link sharing is not allowed" : "اشتراک‌گذاری لینک مجاز نیست",
+ "Public upload is not allowed" : "بارگذاری عمومی مجاز نیست",
+ "You cannot share a folder that contains other shares" : "نمی‌توانید پوشه‌ای را به اشتراک بگذارید که حاوی اشتراک‌های دیگر است",
+ "Sharing is disabled" : "اشتراک‌گذاری غیرفعال است",
+ "Sharing is disabled for you" : "اشتراک‌گذاری برای شما غیرفعال است",
+ "Cannot share with the share owner" : "نمی‌توان با صاحب اشتراک به اشتراک گذاشت",
+ "Share does not have a full ID" : "اشتراک شناسه کامل ندارد",
+ "Cannot change share type" : "نمی‌توان نوع اشتراک را تغییر داد",
+ "Can only update recipient on user shares" : "فقط می‌توان گیرنده را در اشتراک‌های کاربر به‌روزرسانی کرد",
+ "Cannot enable sending the password by Talk with an empty password" : "نمی‌توان ارسال رمز عبور از طریق Talk را با رمز عبور خالی فعال کرد",
+ "Cannot enable sending the password by Talk without setting a new password" : "نمی‌توان ارسال رمز عبور از طریق Talk را بدون تنظیم رمز عبور جدید فعال کرد",
+ "Cannot disable sending the password by Talk without setting a new password" : "نمی‌توان ارسال رمز عبور از طریق Talk را بدون تنظیم رمز عبور جدید غیرفعال کرد",
+ "Share provider does not support accepting" : "ارائه‌دهنده اشتراک از پذیرش پشتیبانی نمی‌کند",
+ "Cannot change target of link share" : "نمی‌توان مقصد اشتراک لینک را تغییر داد",
+ "Invalid share recipient" : "گیرنده اشتراک نامعتبر است",
+ "Group \"%s\" does not exist" : "گروه «%s» وجود ندارد",
"The requested share does not exist anymore" : "سهم درخواست شده دیگر وجود ندارد",
- "The user was not created because the user limit has been reached. Check your notifications to learn more." : "The user was not created because the user limit has been reached. Check your notifications to learn more.",
+ "The requested share comes from a disabled user" : "اشتراک درخواستی از یک کاربر غیرفعال است",
+ "The user was not created because the user limit has been reached. Check your notifications to learn more." : "کاربر ایجاد نشد زیرا محدودیت کاربر به پایان رسیده است. برای اطلاعات بیشتر اعلان‌های خود را بررسی کنید.",
"Could not find category \"%s\"" : "دسته بندی %s یافت نشد",
+ "Input text" : "متن ورودی",
+ "The input text" : "متن ورودی",
"Sunday" : "یک‌شنبه",
"Monday" : "دوشنبه",
"Tuesday" : "سه‌شنبه",
@@ -183,6 +269,15 @@ OC.L10N.register(
"Nov." : "نو.",
"Dec." : "دس.",
"A valid password must be provided" : "رمز عبور صحیح باید وارد شود",
+ "The Login is already being used" : "نام کاربری قبلاً استفاده شده است",
+ "Could not create account" : "حساب کاربری ایجاد نشد",
+ "Only the following characters are allowed in an Login: \"a-z\", \"A-Z\", \"0-9\", spaces and \"_.@-'\"" : "فقط کاراکترهای زیر در نام کاربری مجاز هستند: \"a-z\", \"A-Z\", \"0-9\", فاصله و \"_.@-'\"",
+ "A valid Login must be provided" : "یک نام کاربری معتبر باید ارائه شود",
+ "Login contains whitespace at the beginning or at the end" : "نام کاربری حاوی فاصله در ابتدا یا انتها است",
+ "Login must not consist of dots only" : "نام کاربری نباید فقط از نقطه تشکیل شده باشد",
+ "Username is too long" : "نام کاربری بیش از حد طولانی است",
+ "Login is invalid because files already exist for this user" : "نام کاربری نامعتبر است زیرا فایل‌ها برای این کاربر از قبل وجود دارند",
+ "Account disabled" : "حساب کاربری غیرفعال است",
"Login canceled by app" : "ورود به دست کاره لغو شد",
"App \"%1$s\" cannot be installed because the following dependencies are not fulfilled: %2$s" : "کارهٔ «%1$s» نمی‌تواند نصب شود؛ چرا که وابستگی زیر تأمین نشده: %2$s",
"a safe home for all your data" : "خانه‌ای امن برای تمامی داده‌هایتان",
@@ -190,73 +285,173 @@ OC.L10N.register(
"Authentication error" : "خطا در اعتبار سنجی",
"Token expired. Please reload page." : "Token منقضی شده است. لطفا دوباره صفحه را بارگذاری نمایید.",
"No database drivers (sqlite, mysql, or postgresql) installed." : "هیچ درایور پایگاه داده (sqlite ، mysql یا postgresql) نصب نشده است.",
- "Cannot write into \"config\" directory." : "Cannot write into \"config\" directory.",
- "This can usually be fixed by giving the web server write access to the config directory. See %s" : "This can usually be fixed by giving the web server write access to the config directory. See %s",
- "Or, if you prefer to keep config.php file read only, set the option \"config_is_read_only\" to true in it. See %s" : "یا اگر ترجیح می دهید پرونده config.php را فقط بخوانید ، گزینه \"config_is_read_only\" را در آن تنظیم کنید. دیدن%s",
- "Cannot write into \"apps\" directory." : "Cannot write into \"apps\" directory.",
- "This can usually be fixed by giving the web server write access to the apps directory or disabling the App Store in the config file." : "This can usually be fixed by giving the web server write access to the apps directory or disabling the App Store in the config file.",
- "Cannot create \"data\" directory." : "Cannot create \"data\" directory.",
- "This can usually be fixed by giving the web server write access to the root directory. See %s" : "This can usually be fixed by giving the web server write access to the root directory. See %s",
- "Permissions can usually be fixed by giving the web server write access to the root directory. See %s." : "Permissions can usually be fixed by giving the web server write access to the root directory. See %s.",
- "Your data directory is not writable." : "Your data directory is not writable.",
- "Setting locale to %s failed." : "Setting locale to %s failed.",
- "Please install one of these locales on your system and restart your web server." : "Please install one of these locales on your system and restart your web server.",
+ "Cannot write into \"config\" directory." : "نمی‌توان در دایرکتوری «config» نوشت.",
+ "This can usually be fixed by giving the web server write access to the config directory. See %s" : "این مشکل معمولاً با دادن دسترسی نوشتن به وب‌سرور در دایرکتوری پیکربندی قابل رفع است. مشاهده %s",
+ "Or, if you prefer to keep config.php file read only, set the option \"config_is_read_only\" to true in it. See %s" : "یا اگر ترجیح می‌دهید فایل config.php فقط خواندنی باشد، گزینه \"config_is_read_only\" را در آن به true تنظیم کنید. مشاهده %s",
+ "Cannot write into \"apps\" directory." : "نمی‌توان در دایرکتوری «apps» نوشت.",
+ "This can usually be fixed by giving the web server write access to the apps directory or disabling the App Store in the config file." : "این مشکل معمولاً با دادن دسترسی نوشتن به وب‌سرور در دایرکتوری برنامه‌ها یا غیرفعال کردن فروشگاه برنامه در فایل پیکربندی قابل رفع است.",
+ "Cannot create \"data\" directory." : "نمی‌توان دایرکتوری «data» را ایجاد کرد.",
+ "This can usually be fixed by giving the web server write access to the root directory. See %s" : "این مشکل معمولاً با دادن دسترسی نوشتن به وب‌سرور در دایرکتوری ریشه قابل رفع است. مشاهده %s",
+ "Permissions can usually be fixed by giving the web server write access to the root directory. See %s." : "مجوزها معمولاً با دادن دسترسی نوشتن به وب‌سرور در دایرکتوری ریشه قابل رفع هستند. مشاهده %s.",
+ "Your data directory is not writable." : "دایرکتوری داده شما قابل نوشتن نیست.",
+ "Setting locale to %s failed." : "تنظیم محلی به %s ناموفق بود.",
+ "Please install one of these locales on your system and restart your web server." : "لطفاً یکی از این محلی‌ها را روی سیستم خود نصب کرده و وب‌سرور خود را مجدداً راه‌اندازی کنید.",
"PHP module %s not installed." : "ماژول PHP %s نصب نشده است.",
"Please ask your server administrator to install the module." : "لطفا از مدیر سیستم بخواهید تا ماژول را نصب کند.",
- "PHP setting \"%s\" is not set to \"%s\"." : "تنظیمات PHP%s تنظیم نشده است%s",
+ "PHP setting \"%s\" is not set to \"%s\"." : "تنظیمات PHP «%s» روی «%s» تنظیم نشده است.",
"Adjusting this setting in php.ini will make Nextcloud run again" : "تنظیم این تنظیمات در php.ini باعث می شود Nextcloud دوباره اجرا شود",
- "<code>mbstring.func_overload</code> is set to <code>%s</code> instead of the expected value <code>0</code>." : "<code>mbstring.func_overload</code> is set to <code>%s</code> instead of the expected value <code>0</code>.",
- "To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini." : "To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini.",
- "PHP is apparently set up to strip inline doc blocks. This will make several core apps inaccessible." : "PHP ظاهراً برای خنثی کردن بلوک های اسناد درون خطی تنظیم شده است. این کار چندین برنامه اصلی را غیرقابل دسترسی خواهد کرد.",
- "This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "این احتمالاً توسط حافظه پنهان / کش مانند Zend OPcache یا eAccelerator ایجاد شده است.",
- "PHP modules have been installed, but they are still listed as missing?" : "ماژول های پی اچ پی نصب شده اند ، اما هنوز هم به عنوان مفقود شده ذکر شده اند؟",
- "Please ask your server administrator to restart the web server." : "لطفاً از سرور سرور خود بخواهید که وب سرور را مجدداً راه اندازی کند.",
- "The required %s config variable is not configured in the config.php file." : "The required %s config variable is not configured in the config.php file.",
- "Please ask your server administrator to check the Nextcloud configuration." : "Please ask your server administrator to check the Nextcloud configuration.",
- "Your data directory must be an absolute path." : "Your data directory must be an absolute path.",
- "Check the value of \"datadirectory\" in your configuration." : "Check the value of \"datadirectory\" in your configuration.",
- "Your data directory is invalid." : "Your data directory is invalid.",
- "Action \"%s\" not supported or implemented." : "عملی%s پشتیبانی یا اجرا نشده است.",
- "Authentication failed, wrong token or provider ID given" : "تأیید اعتبار انجام نشد ، نشانه اشتباه یا شناسه ارائه دهنده داده شد",
- "Parameters missing in order to complete the request. Missing Parameters: \"%s\"" : "پارامترهای موجود برای تکمیل درخواست. پارامترهای موجود نیست%s",
- "ID \"%1$s\" already used by cloud federation provider \"%2$s\"" : "شناسه%1$s قبلاً توسط ارائه دهنده فدراسیون ابر استفاده شده است%2$s",
- "Cloud Federation Provider with ID: \"%s\" does not exist." : "ارائه دهنده فدراسیون Cloud با شناسه:%s وجود ندارد.",
- "Could not obtain lock type %d on \"%s\"." : "نمی توان نوع%d قفل را به دست آورد%s",
- "Storage unauthorized. %s" : "ذخیره سازی غیر مجاز.%s",
- "Storage incomplete configuration. %s" : "پیکربندی ناقص ذخیره سازی.%s<br>",
- "Storage connection error. %s" : "خطای اتصال ذخیره سازی%s",
- "Storage is temporarily not available" : "ذخیره سازی به طور موقت در دسترس نیست",
- "Storage connection timeout. %s" : "مدت زمان اتصال ذخیره سازی%s",
- "Confirmation" : "Confirmation",
- "Prompt" : "Prompt",
- "Chat" : "Chat",
- "Generates a possible headline for a text." : "Generates a possible headline for a text.",
+ "<code>mbstring.func_overload</code> is set to <code>%s</code> instead of the expected value <code>0</code>." : "<code>mbstring.func_overload</code> به جای مقدار مورد انتظار <code>0</code> روی <code>%s</code> تنظیم شده است.",
+ "To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini." : "برای رفع این مشکل، <code>mbstring.func_overload</code> را در php.ini خود روی <code>0</code> تنظیم کنید.",
+ "PHP is apparently set up to strip inline doc blocks. This will make several core apps inaccessible." : "PHP ظاهراً برای حذف بلوک‌های مستندات درون‌خطی تنظیم شده است. این کار چندین برنامه اصلی را غیرقابل دسترس خواهد کرد.",
+ "This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "این احتمالاً توسط حافظه پنهان/شتاب‌دهنده‌ای مانند Zend OPcache یا eAccelerator ایجاد شده است.",
+ "PHP modules have been installed, but they are still listed as missing?" : "ماژول‌های PHP نصب شده‌اند، اما همچنان به عنوان گم‌شده لیست شده‌اند؟",
+ "Please ask your server administrator to restart the web server." : "لطفاً از مدیر سرور خود بخواهید که وب‌سرور را مجدداً راه‌اندازی کند.",
+ "The required %s config variable is not configured in the config.php file." : "متغیر پیکربندی مورد نیاز %s در فایل config.php پیکربندی نشده است.",
+ "Please ask your server administrator to check the Nextcloud configuration." : "لطفاً از مدیر سرور خود بخواهید پیکربندی Nextcloud را بررسی کند.",
+ "Your data directory is readable by other people." : "دایرکتوری داده شما برای دیگران قابل خواندن است.",
+ "Please change the permissions to 0770 so that the directory cannot be listed by other people." : "لطفاً مجوزها را به 0770 تغییر دهید تا دایرکتوری توسط افراد دیگر قابل فهرست شدن نباشد.",
+ "Your data directory must be an absolute path." : "دایرکتوری داده شما باید یک مسیر مطلق باشد.",
+ "Check the value of \"datadirectory\" in your configuration." : "مقدار \"datadirectory\" را در پیکربندی خود بررسی کنید.",
+ "Your data directory is invalid." : "دایرکتوری داده شما نامعتبر است.",
+ "Ensure there is a file called \"%1$s\" in the root of the data directory. It should have the content: \"%2$s\"" : "اطمینان حاصل کنید که فایلی به نام «%1$s» در ریشه دایرکتوری داده وجود دارد. این فایل باید حاوی: «%2$s» باشد",
+ "Action \"%s\" not supported or implemented." : "عملیات «%s» پشتیبانی یا اجرا نشده است.",
+ "Authentication failed, wrong token or provider ID given" : "تأیید اعتبار انجام نشد، نشانه اشتباه یا شناسه ارائه دهنده داده شد",
+ "Parameters missing in order to complete the request. Missing Parameters: \"%s\"" : "پارامترهای مورد نیاز برای تکمیل درخواست وجود ندارند. پارامترهای از دست رفته: «%s»",
+ "ID \"%1$s\" already used by cloud federation provider \"%2$s\"" : "شناسه «%1$s» قبلاً توسط ارائه‌دهنده فدراسیون ابری «%2$s» استفاده شده است",
+ "Cloud Federation Provider with ID: \"%s\" does not exist." : "ارائه‌دهنده فدراسیون ابری با شناسه: «%s» وجود ندارد.",
+ "Could not obtain lock type %d on \"%s\"." : "نمی‌توان قفل از نوع %d را روی «%s» به دست آورد.",
+ "Storage unauthorized. %s" : "دسترسی به حافظه غیرمجاز است. %s",
+ "Storage incomplete configuration. %s" : "پیکربندی حافظه ناقص است. %s",
+ "Storage connection error. %s" : "خطای اتصال حافظه. %s",
+ "Storage is temporarily not available" : "حافظه به طور موقت در دسترس نیست",
+ "Storage connection timeout. %s" : "مهلت اتصال حافظه به پایان رسید. %s",
+ "To allow this check to run you have to make sure that your Web server can connect to itself. Therefore it must be able to resolve and connect to at least one of its `trusted_domains` or the `overwrite.cli.url`. This failure may be the result of a server-side DNS mismatch or outbound firewall rule." : "برای اجرای این بررسی، باید مطمئن شوید که وب‌سرور شما می‌تواند به خودش متصل شود. بنابراین باید بتواند حداقل یکی از `trusted_domains` یا `overwrite.cli.url` خود را حل و به آن متصل شود. این خطا ممکن است نتیجه عدم تطابق DNS سمت سرور یا قانون فایروال خروجی باشد.",
+ "Transcribe audio" : "رونوشت صوتی",
+ "Transcribe the things said in an audio" : "رونوشت چیزهای گفته شده در یک فایل صوتی",
+ "Audio input" : "ورودی صوتی",
+ "The audio to transcribe" : "فایل صوتی برای رونوشت",
+ "Transcription" : "رونوشت",
+ "The transcribed text" : "متن رونوشت شده",
+ "Chat with an agent" : "چت با یک عامل",
+ "Chat message" : "پیام چت",
+ "A chat message to send to the agent." : "یک پیام چت برای ارسال به عامل.",
+ "Confirmation" : "تأیید",
+ "Whether to confirm previously requested actions: 0 for denial and 1 for confirmation." : "آیا اقدامات قبلاً درخواست شده را تأیید کنید: 0 برای رد و 1 برای تأیید.",
+ "Conversation token" : "توکن مکالمه",
+ "A token representing the conversation." : "یک توکن نماینده مکالمه.",
+ "Generated response" : "پاسخ تولید شده",
+ "The response from the chat model." : "پاسخ از مدل چت.",
+ "The new conversation token" : "توکن مکالمه جدید",
+ "Send this along with the next interaction." : "این را همراه با تعامل بعدی ارسال کنید.",
+ "Requested actions by the agent" : "اقدامات درخواستی توسط عامل",
+ "Actions that the agent would like to carry out in JSON format." : "اقدامات که عامل مایل به انجام آنها در قالب JSON است.",
+ "Context write" : "نوشتن متنی",
+ "Writes text in a given style based on the provided source material." : "متن را با سبکی مشخص بر اساس محتوای منبع ارائه شده می‌نویسد.",
+ "Writing style" : "سبک نگارش",
+ "Demonstrate a writing style that you would like to immitate" : "یک سبک نگارش را که می‌خواهید تقلید کنید، نشان دهید",
+ "Source material" : "محتوای منبع",
+ "The content that would like to be rewritten in the new writing style" : "محتوایی که می‌خواهید با سبک نگارش جدید بازنویسی شود",
+ "Generated text" : "متن تولید شده",
+ "The generated text with content from the source material in the given style" : "متن تولید شده با محتوای منبع در سبک مشخص شده",
+ "Emoji generator" : "تولیدکننده اموجی",
+ "Takes text and generates a representative emoji for it." : "متن را دریافت کرده و یک اموجی مناسب برای آن تولید می‌کند.",
+ "The text to generate an emoji for" : "متنی که می‌خواهید برای آن اموجی تولید شود",
+ "Generated emoji" : "اموجی تولید شده",
+ "The generated emoji based on the input text" : "اموجی تولید شده بر اساس متن ورودی",
+ "Generate image" : "تولید تصویر",
+ "Generate an image from a text prompt" : "تولید تصویر از یک متن ورودی",
+ "Prompt" : "درخواست",
+ "Describe the image you want to generate" : "تصویری که می‌خواهید تولید شود را توصیف کنید",
+ "Number of images" : "تعداد تصاویر",
+ "How many images to generate" : "چه تعداد تصویر تولید شود",
+ "Output images" : "تصاویر خروجی",
+ "The generated images" : "تصاویر تولید شده",
+ "Generate speech" : "تولید گفتار",
+ "Generate speech from a transcript" : "تولید گفتار از یک رونوشت",
+ "Write transcript that you want the assistant to generate speech from" : "رونوشتی را بنویسید که می‌خواهید دستیار از آن گفتار تولید کند",
+ "Output speech" : "گفتار خروجی",
+ "The generated speech" : "گفتار تولید شده",
+ "Free text to text prompt" : "درخواست متن به متن آزاد",
+ "Runs an arbitrary prompt through a language model that returns a reply" : "یک درخواست دلخواه را از طریق یک مدل زبانی اجرا می‌کند که پاسخی را برمی‌گرداند",
+ "Describe a task that you want the assistant to do or ask a question" : "وظیفه‌ای که می‌خواهید دستیار انجام دهد را توصیف کنید یا سؤالی بپرسید",
+ "Generated reply" : "پاسخ تولید شده",
+ "The generated text from the assistant" : "متن تولید شده توسط دستیار",
+ "Change Tone" : "تغییر لحن",
+ "Change the tone of a piece of text." : "لحن یک قطعه متن را تغییر دهید.",
+ "Write a text that you want the assistant to rewrite in another tone." : "متنی را بنویسید که می‌خواهید دستیار آن را با لحن دیگری بازنویسی کند.",
+ "Desired tone" : "لحن مورد نظر",
+ "In which tone should your text be rewritten?" : "متن شما با چه لحنی بازنویسی شود؟",
+ "The rewritten text in the desired tone, written by the assistant:" : "متن بازنویسی شده با لحن مورد نظر، نوشته شده توسط دستیار:",
+ "Chat" : "چت",
+ "Chat with the assistant" : "چت با دستیار",
+ "System prompt" : "درخواست سیستمی",
+ "Define rules and assumptions that the assistant should follow during the conversation." : "قوانین و فرضیاتی را که دستیار باید در طول مکالمه رعایت کند، تعریف کنید.",
+ "Chat history" : "تاریخچه چت",
+ "The history of chat messages before the current message, starting with a message by the user" : "تاریخچه پیام‌های چت قبل از پیام فعلی، با شروع از یک پیام توسط کاربر",
+ "Response message" : "پیام پاسخ",
+ "The generated response as part of the conversation" : "پاسخ تولید شده به عنوان بخشی از مکالمه",
+ "Chat with tools" : "چت با ابزارها",
+ "Chat with the language model with tool calling support." : "چت با مدل زبانی با پشتیبانی از فراخوانی ابزار.",
+ "Tool message" : "پیام ابزار",
+ "The result of tool calls in the last interaction" : "نتیجه فراخوانی ابزارها در تعامل قبلی",
+ "Available tools" : "ابزارهای موجود",
+ "The available tools in JSON format" : "ابزارهای موجود در قالب JSON",
+ "The response from the chat model" : "پاسخ از مدل چت",
+ "Tool calls" : "فراخوانی ابزار",
+ "Tools call instructions from the model in JSON format" : "دستورالعمل‌های فراخوانی ابزار از مدل در قالب JSON",
+ "Formalize text" : "رسمی کردن متن",
+ "Takes a text and makes it sound more formal" : "یک متن را دریافت کرده و آن را رسمی‌تر می‌کند",
+ "Write a text that you want the assistant to formalize" : "متنی را بنویسید که می‌خواهید دستیار آن را رسمی کند",
+ "Formalized text" : "متن رسمی شده",
+ "The formalized text" : "متن رسمی شده",
+ "Generate a headline" : "تولید یک عنوان",
+ "Generates a possible headline for a text." : "یک عنوان احتمالی برای یک متن تولید می‌کند.",
+ "Original text" : "متن اصلی",
+ "The original text to generate a headline for" : "متن اصلی برای تولید عنوان",
+ "The generated headline" : "عنوان تولید شده",
+ "Proofread" : "ویرایش",
+ "Proofreads a text and lists corrections" : "یک متن را ویرایش کرده و اصلاحات را لیست می‌کند",
"Text" : "متن",
- "Summarize" : "Summarize",
+ "The text to proofread" : "متن برای ویرایش",
+ "Corrections" : "اصلاحات",
+ "The corrections that should be made in your text" : "اصلاحاتی که باید در متن شما انجام شود",
+ "Reformulate text" : "بازنویسی متن",
+ "Takes a text and reformulates it" : "یک متن را دریافت کرده و آن را بازنویسی می‌کند",
+ "Write a text that you want the assistant to reformulate" : "متنی را بنویسید که می‌خواهید دستیار آن را بازنویسی کند",
+ "Reformulated text" : "متن بازنویسی شده",
+ "The reformulated text, written by the assistant" : "متن بازنویسی شده، نوشته شده توسط دستیار",
+ "Simplify text" : "ساده‌سازی متن",
+ "Takes a text and simplifies it" : "یک متن را دریافت کرده و آن را ساده می‌کند",
+ "Write a text that you want the assistant to simplify" : "متنی را بنویسید که می‌خواهید دستیار آن را ساده کند",
+ "Simplified text" : "متن ساده شده",
+ "The simplified text" : "متن ساده شده",
+ "Summarize" : "خلاصه‌سازی",
+ "Summarizes a text" : "یک متن را خلاصه‌سازی می‌کند",
+ "The original text to summarize" : "متن اصلی برای خلاصه‌سازی",
"Summary" : "چکیده",
- "Extract topics" : "Extract topics",
+ "The generated summary" : "خلاصه تولید شده",
+ "Extract topics" : "استخراج موضوعات",
+ "Extracts topics from a text and outputs them separated by commas" : "موضوعات را از یک متن استخراج کرده و با کاما جدا شده خروجی می‌دهد",
+ "The original text to extract topics from" : "متن اصلی برای استخراج موضوعات",
+ "Topics" : "موضوعات",
+ "The list of extracted topics" : "لیست موضوعات استخراج شده",
"Translate" : "ترجمه",
- "Target language" : "Target language",
- "Result" : "شروع به اسکنیک",
- "Free prompt" : "Free prompt",
- "Runs an arbitrary prompt through the language model." : "Runs an arbitrary prompt through the language model.",
- "Generate headline" : "Generate headline",
- "Summarizes text by reducing its length without losing key information." : "Summarizes text by reducing its length without losing key information.",
- "Extracts topics from a text and outputs them separated by commas." : "Extracts topics from a text and outputs them separated by commas.",
- "Education Edition" : "نگارش آموزشی",
- "File name is a reserved word" : "این نام فایل جزو کلمات رزرو می‌باشد",
- "File name contains at least one invalid character" : "نام فایل دارای حداقل یک کاراکتر نامعتبر است",
- "File name is too long" : "نام فایل خیلی بزرگ است",
- "Users" : "کاربران",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s به اشتراک گذاشته شده »%2$s« با شماست و می خواهد اضافه کند:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s به اشتراک گذاشته شده »%2$s« با شماست و می خواهد اضافه کند:",
- "»%s« added a note to a file shared with you" : "»%s« یادداشتی را به پرونده ای که با شما به اشتراک گذاشته شده است اضافه کرد",
- "Open »%s«" : "باز کن »%s«",
- "%1$s shared »%2$s« with you" : "%1$s به اشتراک گذاشته » %2$s« با شما",
- "%1$s shared »%2$s« with you." : "%1$s به اشتراک گذاشته » %2$s« با شما",
- "Click the button below to open it." : "برای باز کردن آن روی دکمه زیر کلیک کنید.",
+ "Translate text from one language to another" : "ترجمه متن از یک زبان به زبان دیگر",
+ "Origin text" : "متن مبدأ",
+ "The text to translate" : "متن برای ترجمه",
+ "Origin language" : "زبان مبدأ",
+ "The language of the origin text" : "زبان متن مبدأ",
+ "Target language" : "زبان مقصد",
+ "The desired language to translate the origin text in" : "زبان مورد نظر برای ترجمه متن مبدأ",
+ "Result" : "نتیجه",
+ "The translated text" : "متن ترجمه شده",
+ "Free prompt" : "درخواست آزاد",
+ "Runs an arbitrary prompt through the language model." : "یک درخواست دلخواه را از طریق مدل زبانی اجرا می‌کند.",
+ "Generate headline" : "تولید عنوان",
+ "Summarizes text by reducing its length without losing key information." : "متن را با کاهش طول آن و بدون از دست دادن اطلاعات کلیدی، خلاصه‌سازی می‌کند.",
+ "Extracts topics from a text and outputs them separated by commas." : "موضوعات را از یک متن استخراج کرده و با کاما جدا شده خروجی می‌دهد.",
"File is currently busy, please try again later" : "فایل در حال حاضر مشغول است، لطفا مجددا تلاش کنید",
"Cannot download file" : "نمی‌توان پرونده را بارگرفت",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "اطمینان حاصل کنید که فایلی به نام \".ocdata\" در ریشه دایرکتوری داده وجود دارد."
+ "Login is too long" : "نام کاربری بیش از حد طولانی است"
},
"nplurals=2; plural=(n > 1);");
diff --git a/lib/l10n/fa.json b/lib/l10n/fa.json
index 9535354cf87..7fda24b1e51 100644
--- a/lib/l10n/fa.json
+++ b/lib/l10n/fa.json
@@ -1,25 +1,27 @@
{ "translations": {
"Cannot write into \"config\" directory!" : "نمیتوانید داخل دایرکتوری \"config\" تغییراتی ایجاد کنید",
- "This can usually be fixed by giving the web server write access to the config directory." : "This can usually be fixed by giving the web server write access to the config directory.",
- "But, if you prefer to keep config.php file read only, set the option \"config_is_read_only\" to true in it." : "But, if you prefer to keep config.php file read only, set the option \"config_is_read_only\" to true in it.",
+ "This can usually be fixed by giving the web server write access to the config directory." : "این مشکل معمولاً با دادن دسترسی نوشتن به وب‌سرور در دایرکتوری پیکربندی قابل رفع است.",
+ "But, if you prefer to keep config.php file read only, set the option \"config_is_read_only\" to true in it." : "اما، اگر ترجیح می‌دهید فایل config.php فقط خواندنی باشد، گزینه \"config_is_read_only\" را در آن به true تنظیم کنید.",
"See %s" : "مشاهده %s",
- "Application %1$s is not present or has a non-compatible version with this server. Please check the apps directory." : "Application %1$s is not present or has a non-compatible version with this server. Please check the apps directory.",
+ "Application %1$s is not present or has a non-compatible version with this server. Please check the apps directory." : "برنامه %1$s موجود نیست یا نسخه‌ای ناسازگار با این سرور دارد. لطفاً دایرکتوری برنامه‌ها را بررسی کنید.",
"Sample configuration detected" : "فایل پیکربندی نمونه پیدا شد",
"It has been detected that the sample configuration has been copied. This can break your installation and is unsupported. Please read the documentation before performing changes on config.php" : "تشخیص داده شده است که پیکربندی نمونه کپی شده است. این می تواند نصب شما را خراب کند و پشتیبانی نمی شود. لطفاً قبل از انجام تغییرات در config.php ، اسناد را بخوانید",
- "The page could not be found on the server." : "The page could not be found on the server.",
- "%s email verification" : "%s email verification",
- "Email verification" : "Email verification",
- "Click the following button to confirm your email." : "Click the following button to confirm your email.",
- "Click the following link to confirm your email." : "Click the following link to confirm your email.",
- "Confirm your email" : "Confirm your email",
+ "The page could not be found on the server." : "صفحه در سرور یافت نشد.",
+ "%s email verification" : "تأیید ایمیل %s",
+ "Email verification" : "تأیید ایمیل",
+ "Click the following button to confirm your email." : "برای تأیید ایمیل خود روی دکمه زیر کلیک کنید.",
+ "Click the following link to confirm your email." : "برای تأیید ایمیل خود روی لینک زیر کلیک کنید.",
+ "Confirm your email" : "ایمیل خود را تأیید کنید",
"Other activities" : "سایر فعالیت ها",
- "%1$s and %2$s" : "%1$sو%2$s",
- "%1$s, %2$s and %3$s" : "%1$s،%2$sو%3$s",
- "%1$s, %2$s, %3$s and %4$s" : "%1$s،%2$s،%3$sو%4$s",
- "%1$s, %2$s, %3$s, %4$s and %5$s" : "%1$s،%2$s،%3$s،%4$sو%5$s",
+ "%1$s and %2$s" : "%1$s و %2$s",
+ "%1$s, %2$s and %3$s" : "%1$s، %2$s و %3$s",
+ "%1$s, %2$s, %3$s and %4$s" : "%1$s، %2$s، %3$s و %4$s",
+ "%1$s, %2$s, %3$s, %4$s and %5$s" : "%1$s، %2$s، %3$s، %4$s و %5$s",
+ "Education bundle" : "بسته آموزشی",
"Enterprise bundle" : "بستهٔ سازمانی",
"Groupware bundle" : "بستهٔ کار گروهی",
"Hub bundle" : "بستهٔ هسته‌ای",
+ "Public sector bundle" : "بسته بخش عمومی",
"Social sharing bundle" : "بستهٔ هم‌رسانی اجتماعی",
"PHP %s or higher is required." : "PHP نسخه‌ی %s یا بالاتر نیاز است.",
"PHP with a version lower than %s is required." : "نیاز به نگارش پایین‌تر از %s پی‌اچ‌پی.",
@@ -33,26 +35,34 @@
"The following platforms are supported: %s" : "بن‌سازه‌های زیر پشتیبانی می‌شوند: %s",
"Server version %s or higher is required." : "نیاز به کارساز با نگارش %s یا بالاتر.",
"Server version %s or lower is required." : "نیاز به کارساز با نگارش %s یا پایین‌تر.",
- "Wiping of device %s has started" : "پاک کردن دستگاه%s شروع شده است",
- "Wiping of device »%s« has started" : "پاک کردن دستگاه%s شروع شده است",
- "»%s« started remote wipe" : "%sپاک کردن از راه دور",
- "Device or application »%s« has started the remote wipe process. You will receive another email once the process has finished" : "دستگاه یا برنامه%s فرآیند پاک کردن از راه دور را آغاز کرده است. پس از اتمام مراحل ، ایمیل دیگری دریافت خواهید کرد",
- "Wiping of device %s has finished" : "پاک کردن دستگاه %sبه پایان رسیده است",
- "Wiping of device »%s« has finished" : "پاک کردن دستگاه %sبه پایان رسیده است",
- "»%s« finished remote wipe" : "%sپاک کردن از راه دور",
- "Device or application »%s« has finished the remote wipe process." : "دستگاه یا برنامه %sفرآیند پاک کردن از راه دور را به پایان رسانده است.",
+ "Logged in account must be an admin, a sub admin or gotten special right to access this setting" : "حساب وارد شده باید یک مدیر، یک مدیر فرعی یا دارای حق دسترسی ویژه برای دسترسی به این تنظیم باشد",
+ "Your current IP address doesn't allow you to perform admin actions" : "آدرس IP فعلی شما اجازه انجام اقدامات مدیریتی را به شما نمی‌دهد",
+ "Logged in account must be an admin or sub admin" : "حساب وارد شده باید یک مدیر یا مدیر فرعی باشد",
+ "Logged in account must be an admin" : "حساب وارد شده باید یک مدیر باشد",
+ "Wiping of device %s has started" : "پاک کردن دستگاه %s آغاز شد",
+ "Wiping of device »%s« has started" : "پاک کردن دستگاه «%s» آغاز شد",
+ "»%s« started remote wipe" : "«%s» پاک کردن از راه دور را آغاز کرد",
+ "Device or application »%s« has started the remote wipe process. You will receive another email once the process has finished" : "دستگاه یا برنامه «%s» فرآیند پاک کردن از راه دور را آغاز کرده است. پس از اتمام مراحل، ایمیل دیگری دریافت خواهید کرد.",
+ "Wiping of device %s has finished" : "پاک کردن دستگاه %s به پایان رسید",
+ "Wiping of device »%s« has finished" : "پاک کردن دستگاه «%s» به پایان رسید",
+ "»%s« finished remote wipe" : "«%s» پاک کردن از راه دور را به پایان رساند",
+ "Device or application »%s« has finished the remote wipe process." : "دستگاه یا برنامه «%s» فرآیند پاک کردن از راه دور را به پایان رسانده است.",
"Remote wipe started" : "پاک کردن از راه دور شروع شد",
- "A remote wipe was started on device %s" : "پاک کردن از راه دور روی دستگاه شروع شد%s",
+ "A remote wipe was started on device %s" : "پاک کردن از راه دور روی دستگاه %s شروع شد",
"Remote wipe finished" : "پاک کردن از راه دور به پایان رسید",
- "The remote wipe on %s has finished" : "پاک کردن از راه دور روی%s کار تمام شد",
+ "The remote wipe on %s has finished" : "پاک کردن از راه دور روی %s کار تمام شد",
"Authentication" : "احراز هویت",
"Unknown filetype" : "نوع فایل ناشناخته",
"Invalid image" : "عکس نامعتبر",
"Avatar image is not square" : "تصویر آواتار مربع نیست",
"Files" : "پوشه‌ها",
"View profile" : "مشاهدهٔ نمایه",
- "_%nh_::_%nh_" : ["%nh","%nh"],
- "Local time: %s" : "Local time: %s",
+ "same time" : "همزمان",
+ "_%nh_::_%nh_" : ["%n ساعت","%n ساعت"],
+ "_%nm_::_%nm_" : ["%n دقیقه","%n دقیقه"],
+ "%s ahead" : "%s جلوتر",
+ "%s behind" : "%s عقب‌تر",
+ "Local time: %s" : "زمان محلی: %s",
"today" : "امروز",
"tomorrow" : "فردا",
"yesterday" : "دیروز",
@@ -73,13 +83,37 @@
"in a few seconds" : "در چند ثانیه",
"seconds ago" : "ثانیه‌ها پیش",
"Empty file" : "پروندهٔ خالی",
- "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "ماژول با شناسه:%s وجود ندارد. لطفاً آن را در تنظیمات برنامه خود فعال کنید یا با سرپرست خود تماس بگیرید",
+ "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "ماژول با شناسه: %s وجود ندارد. لطفاً آن را در تنظیمات برنامه خود فعال کنید یا با سرپرست خود تماس بگیرید.",
+ "No file conversion providers available" : "ارائه‌دهنده تبدیل فایل در دسترس نیست",
+ "File is too large to convert" : "فایل برای تبدیل خیلی بزرگ است",
+ "Destination does not match conversion extension" : "مقصد با پسوند تبدیل مطابقت ندارد",
+ "Could not convert file" : "فایل قابل تبدیل نبود",
+ "Destination does not exist" : "مقصد وجود ندارد",
+ "Destination is not creatable" : "مقصد قابل ایجاد نیست",
"Dot files are not allowed" : "پرونده‌های نقطه‌دار مجاز نیستند",
+ "%1$s (renamed)" : "%1$s (تغییر نام داده شد)",
+ "renamed file" : "فایل تغییر نام داده شد",
+ "\"%1$s\" is a forbidden file or folder name." : "«%1$s» یک نام فایل یا پوشه ممنوع است.",
+ "\"%1$s\" is a forbidden prefix for file or folder names." : "«%1$s» یک پیشوند ممنوع برای نام فایل یا پوشه است.",
+ "\"%1$s\" is not allowed inside a file or folder name." : "«%1$s» در نام فایل یا پوشه مجاز نیست.",
+ "\"%1$s\" is a forbidden file type." : "«%1$s» یک نوع فایل ممنوع است.",
+ "Filenames must not end with \"%1$s\"." : "نام فایل‌ها نباید با «%1$s» به پایان برسند.",
+ "Invalid parent path" : "مسیر والد نامعتبر",
"File already exists" : "پرونده از پیش موجود است",
"Invalid path" : "مسیر نامعتبر",
"Failed to create file from template" : "شکست در ایجاد پرونده از قالب",
"Templates" : "قالب‌ها",
+ "Storage %s cannot be moved" : "حافظه %s قابل جابجایی نیست",
+ "Moving a share (%s) into a shared folder is not allowed" : "انتقال یک اشتراک (%s) به یک پوشه مشترک مجاز نیست",
+ "Moving a storage (%s) into a shared folder is not allowed" : "انتقال یک حافظه (%s) به یک پوشه مشترک مجاز نیست",
+ "Moving a share (%s) into another share (%s) is not allowed" : "انتقال یک اشتراک (%s) به اشتراک دیگر (%s) مجاز نیست",
+ "Moving a share (%s) into another storage (%s) is not allowed" : "انتقال یک اشتراک (%s) به حافظه دیگر (%s) مجاز نیست",
+ "Moving a storage (%s) into a share (%s) is not allowed" : "انتقال یک حافظه (%s) به یک اشتراک (%s) مجاز نیست",
+ "Moving a storage (%s) into another storage (%s) is not allowed" : "انتقال یک حافظه (%s) به حافظه دیگر (%s) مجاز نیست",
+ "Path contains invalid segments" : "مسیر شامل بخش‌های نامعتبر است",
+ "Filename is a reserved word" : "نام فایل یک کلمه رزرو شده است",
"Filename contains at least one invalid character" : "نام فایل حداقل دارای یک کاراکتر نامعتبر است",
+ "Filename is too long" : "نام فایل بیش از حد طولانی است",
"Empty filename is not allowed" : "نام فایل نمی‌تواند خالی باشد",
"App \"%s\" cannot be installed because appinfo file cannot be read." : "کارهٔ «%s» به دلیل ناتوانی در خواندن پروندهٔ appinfo نمی‌تواند نصب شود.",
"App \"%s\" cannot be installed because it is not compatible with this version of the server." : "کارهٔ «%s» به دلیل سازگار نبودن با این نگارش از کارساز نمی‌تواند نصب شود.",
@@ -95,8 +129,8 @@
"Accounts" : "حساب‌ها",
"Email" : "رایانامه",
"Mail %s" : "نامه به %s",
- "Fediverse" : "Fediverse",
- "View %s on the fediverse" : "View %s on the fediverse",
+ "Fediverse" : "فدیورس",
+ "View %s on the fediverse" : "مشاهده %s در فدیورس",
"Phone" : "تلفن",
"Call %s" : "تماس با %s",
"Twitter" : "توییتر",
@@ -106,35 +140,87 @@
"Address" : "نشانی",
"Profile picture" : "تصویر نمایه",
"About" : "درباره",
- "Display name" : "Display name",
+ "Display name" : "نام نمایشی",
"Headline" : "عنوان",
"Organisation" : "سازمان",
"Role" : "نقش",
+ "Pronouns" : "ضمایر",
+ "Unknown account" : "حساب ناشناخته",
"Additional settings" : "تنظیمات اضافی",
+ "Enter the database Login and name for %s" : "نام کاربری و نام پایگاه داده را برای %s وارد کنید",
+ "Enter the database Login for %s" : "نام کاربری پایگاه داده را برای %s وارد کنید",
"Enter the database name for %s" : "ورود نام پایگاه داده برای %s",
"You cannot use dots in the database name %s" : "نمی‌توانید در در نام پایگاه دادهٔ %s از نقطه استفاده کنید",
+ "MySQL Login and/or password not valid" : "نام کاربری و/یا رمز عبور MySQL نامعتبر است",
"You need to enter details of an existing account." : "لازم است جزییات یک حساب موحود را وارد کنید.",
"Oracle connection could not be established" : "ارتباط اراکل نمیتواند برقرار باشد.",
+ "Oracle Login and/or password not valid" : "نام کاربری و/یا رمز عبور Oracle نامعتبر است",
+ "PostgreSQL Login and/or password not valid" : "نام کاربری و/یا رمز عبور PostgreSQL نامعتبر است",
+ "Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk!" : "Mac OS X پشتیبانی نمی‌شود و %s روی این پلتفرم به درستی کار نخواهد کرد. با مسئولیت خودتان از آن استفاده کنید!",
"For the best results, please consider using a GNU/Linux server instead." : "برای بهترین نتیجه، استفاده از یک کارساز گنو/لینوکسی را در نظر داشته باشید.",
- "It seems that this %s instance is running on a 32-bit PHP environment and the open_basedir has been configured in php.ini. This will lead to problems with files over 4 GB and is highly discouraged." : "به نظر می رسد%s که این نمونه در یک محیط PHP 32 بیتی در حال اجرا است و open_baseir در php.ini پیکربندی شده است. این مسئله به پرونده هایی با بیش از 4 گیگ منجر می شود و بسیار دلسرد می شود",
- "Please remove the open_basedir setting within your php.ini or switch to 64-bit PHP." : "لطفاً تنظیمات open_baseir را درون php.ini خود حذف کنید یا به PHP 64 بیتی تغییر دهید.",
+ "It seems that this %s instance is running on a 32-bit PHP environment and the open_basedir has been configured in php.ini. This will lead to problems with files over 4 GB and is highly discouraged." : "به نظر می رسد %s که این نمونه در یک محیط PHP 32 بیتی در حال اجرا است و open_basedir در php.ini پیکربندی شده است. این مسئله به پرونده هایی با بیش از 4 گیگ منجر می شود و بسیار دلسرد می شود.",
+ "Please remove the open_basedir setting within your php.ini or switch to 64-bit PHP." : "لطفاً تنظیمات open_basedir را درون php.ini خود حذف کنید یا به PHP 64 بیتی تغییر دهید.",
+ "Set an admin Login." : "یک نام کاربری برای مدیر تنظیم کنید.",
"Set an admin password." : "یک رمزعبور برای مدیر تنظیم نمایید.",
- "Cannot create or write into the data directory %s" : "Cannot create or write into the data directory %s",
- "Sharing backend %s must implement the interface OCP\\Share_Backend" : "به اشتراک گذاشتن باطن باید رابط OCP \\ Share_Backend %sرا پیاده سازی کند",
- "Sharing backend %s not found" : "به اشتراک گذاشتن باطن%s یافت نشد",
- "Sharing backend for %s not found" : "به اشتراک گذاشتن باطن برای%s یافت نشد",
+ "Cannot create or write into the data directory %s" : "نمی‌توان در دایرکتوری داده %s ایجاد یا نوشت",
+ "Sharing backend %s must implement the interface OCP\\Share_Backend" : "بک‌اند اشتراک‌گذاری %s باید رابط OCP\\Share_Backend را پیاده‌سازی کند",
+ "Sharing backend %s not found" : "بک‌اند اشتراک‌گذاری %s یافت نشد",
+ "Sharing backend for %s not found" : "بک‌اند اشتراک‌گذاری برای %s یافت نشد",
+ "%1$s shared %2$s with you" : "%1$s %2$s را با شما به اشتراک گذاشت",
+ "Open %s" : "باز کردن %s",
"%1$s via %2$s" : "%1$s از طریق %2$s",
+ "%1$s shared %2$s with you and wants to add:" : "%1$s %2$s را با شما به اشتراک گذاشت و می‌خواهد اضافه کند:",
+ "%1$s shared %2$s with you and wants to add" : "%1$s %2$s را با شما به اشتراک گذاشت و می‌خواهد اضافه کند",
+ "%s added a note to a file shared with you" : "%s یک یادداشت به فایلی که با شما به اشتراک گذاشته شده است اضافه کرد",
+ "Passwords are enforced for link and mail shares" : "رمزهای عبور برای اشتراک‌گذاری لینک و ایمیل اجباری هستند",
+ "Share recipient is not a valid user" : "گیرنده اشتراک یک کاربر معتبر نیست",
+ "Share recipient is not a valid group" : "گیرنده اشتراک یک گروه معتبر نیست",
+ "Share recipient should be empty" : "گیرنده اشتراک باید خالی باشد",
+ "Share recipient should not be empty" : "گیرنده اشتراک نباید خالی باشد",
+ "Share recipient is not a valid circle" : "گیرنده اشتراک یک دایره معتبر نیست",
"Unknown share type" : "نوع اشتراک ناشناخته",
- "You are not allowed to share %s" : "شما مجاز به اشتراک گذاری نیستید%s",
- "Cannot increase permissions of %s" : "Cannot increase permissions of %s",
- "Files cannot be shared with delete permissions" : "Files cannot be shared with delete permissions",
- "Files cannot be shared with create permissions" : "Files cannot be shared with create permissions",
+ "Share initiator must be set" : "شروع‌کننده اشتراک باید تنظیم شود",
+ "Cannot share with yourself" : "نمی‌توانید با خودتان به اشتراک بگذارید",
+ "Shared path must be set" : "مسیر مشترک باید تنظیم شود",
+ "Shared path must be either a file or a folder" : "مسیر مشترک باید یک فایل یا یک پوشه باشد",
+ "You cannot share your root folder" : "نمی‌توانید پوشه ریشه خود را به اشتراک بگذارید",
+ "You are not allowed to share %s" : "شما مجاز به اشتراک گذاری %s نیستید",
+ "Valid permissions are required for sharing" : "مجوزهای معتبر برای اشتراک‌گذاری لازم است",
+ "File shares cannot have create or delete permissions" : "اشتراک‌گذاری فایل‌ها نمی‌تواند مجوزهای ایجاد یا حذف داشته باشد",
+ "Cannot increase permissions of %s" : "نمی‌توان مجوزهای %s را افزایش داد",
+ "Shares need at least read permissions" : "اشتراک‌گذاری‌ها حداقل به مجوزهای خواندن نیاز دارند",
+ "Files cannot be shared with delete permissions" : "فایل‌ها را نمی‌توان با مجوزهای حذف به اشتراک گذاشت",
+ "Files cannot be shared with create permissions" : "فایل‌ها را نمی‌توان با مجوزهای ایجاد به اشتراک گذاشت",
"Expiration date is in the past" : "تاریخ انقضا در گذشته است",
- "_Cannot set expiration date more than %n day in the future_::_Cannot set expiration date more than %n days in the future_" : ["Cannot set expiration date more than %n day in the future","Cannot set expiration date more than %n days in the future"],
- "Sharing is only allowed with group members" : "Sharing is only allowed with group members",
+ "Expiration date is enforced" : "تاریخ انقضا اجباری است",
+ "_Cannot set expiration date more than %n day in the future_::_Cannot set expiration date more than %n days in the future_" : ["نمی‌توان تاریخ انقضا را بیش از %n روز در آینده تنظیم کرد","نمی‌توان تاریخ انقضا را بیش از %n روز در آینده تنظیم کرد"],
+ "Sharing is only allowed with group members" : "اشتراک‌گذاری فقط با اعضای گروه مجاز است",
+ "Sharing %s failed, because this item is already shared with the account %s" : "اشتراک‌گذاری %s ناموفق بود، زیرا این مورد قبلاً با حساب %s به اشتراک گذاشته شده است",
+ "Group sharing is now allowed" : "اشتراک‌گذاری گروهی اکنون مجاز است",
+ "Sharing is only allowed within your own groups" : "اشتراک‌گذاری فقط در گروه‌های خودتان مجاز است",
+ "Path is already shared with this group" : "این مسیر قبلاً با این گروه به اشتراک گذاشته شده است",
+ "Link sharing is not allowed" : "اشتراک‌گذاری لینک مجاز نیست",
+ "Public upload is not allowed" : "بارگذاری عمومی مجاز نیست",
+ "You cannot share a folder that contains other shares" : "نمی‌توانید پوشه‌ای را به اشتراک بگذارید که حاوی اشتراک‌های دیگر است",
+ "Sharing is disabled" : "اشتراک‌گذاری غیرفعال است",
+ "Sharing is disabled for you" : "اشتراک‌گذاری برای شما غیرفعال است",
+ "Cannot share with the share owner" : "نمی‌توان با صاحب اشتراک به اشتراک گذاشت",
+ "Share does not have a full ID" : "اشتراک شناسه کامل ندارد",
+ "Cannot change share type" : "نمی‌توان نوع اشتراک را تغییر داد",
+ "Can only update recipient on user shares" : "فقط می‌توان گیرنده را در اشتراک‌های کاربر به‌روزرسانی کرد",
+ "Cannot enable sending the password by Talk with an empty password" : "نمی‌توان ارسال رمز عبور از طریق Talk را با رمز عبور خالی فعال کرد",
+ "Cannot enable sending the password by Talk without setting a new password" : "نمی‌توان ارسال رمز عبور از طریق Talk را بدون تنظیم رمز عبور جدید فعال کرد",
+ "Cannot disable sending the password by Talk without setting a new password" : "نمی‌توان ارسال رمز عبور از طریق Talk را بدون تنظیم رمز عبور جدید غیرفعال کرد",
+ "Share provider does not support accepting" : "ارائه‌دهنده اشتراک از پذیرش پشتیبانی نمی‌کند",
+ "Cannot change target of link share" : "نمی‌توان مقصد اشتراک لینک را تغییر داد",
+ "Invalid share recipient" : "گیرنده اشتراک نامعتبر است",
+ "Group \"%s\" does not exist" : "گروه «%s» وجود ندارد",
"The requested share does not exist anymore" : "سهم درخواست شده دیگر وجود ندارد",
- "The user was not created because the user limit has been reached. Check your notifications to learn more." : "The user was not created because the user limit has been reached. Check your notifications to learn more.",
+ "The requested share comes from a disabled user" : "اشتراک درخواستی از یک کاربر غیرفعال است",
+ "The user was not created because the user limit has been reached. Check your notifications to learn more." : "کاربر ایجاد نشد زیرا محدودیت کاربر به پایان رسیده است. برای اطلاعات بیشتر اعلان‌های خود را بررسی کنید.",
"Could not find category \"%s\"" : "دسته بندی %s یافت نشد",
+ "Input text" : "متن ورودی",
+ "The input text" : "متن ورودی",
"Sunday" : "یک‌شنبه",
"Monday" : "دوشنبه",
"Tuesday" : "سه‌شنبه",
@@ -181,6 +267,15 @@
"Nov." : "نو.",
"Dec." : "دس.",
"A valid password must be provided" : "رمز عبور صحیح باید وارد شود",
+ "The Login is already being used" : "نام کاربری قبلاً استفاده شده است",
+ "Could not create account" : "حساب کاربری ایجاد نشد",
+ "Only the following characters are allowed in an Login: \"a-z\", \"A-Z\", \"0-9\", spaces and \"_.@-'\"" : "فقط کاراکترهای زیر در نام کاربری مجاز هستند: \"a-z\", \"A-Z\", \"0-9\", فاصله و \"_.@-'\"",
+ "A valid Login must be provided" : "یک نام کاربری معتبر باید ارائه شود",
+ "Login contains whitespace at the beginning or at the end" : "نام کاربری حاوی فاصله در ابتدا یا انتها است",
+ "Login must not consist of dots only" : "نام کاربری نباید فقط از نقطه تشکیل شده باشد",
+ "Username is too long" : "نام کاربری بیش از حد طولانی است",
+ "Login is invalid because files already exist for this user" : "نام کاربری نامعتبر است زیرا فایل‌ها برای این کاربر از قبل وجود دارند",
+ "Account disabled" : "حساب کاربری غیرفعال است",
"Login canceled by app" : "ورود به دست کاره لغو شد",
"App \"%1$s\" cannot be installed because the following dependencies are not fulfilled: %2$s" : "کارهٔ «%1$s» نمی‌تواند نصب شود؛ چرا که وابستگی زیر تأمین نشده: %2$s",
"a safe home for all your data" : "خانه‌ای امن برای تمامی داده‌هایتان",
@@ -188,73 +283,173 @@
"Authentication error" : "خطا در اعتبار سنجی",
"Token expired. Please reload page." : "Token منقضی شده است. لطفا دوباره صفحه را بارگذاری نمایید.",
"No database drivers (sqlite, mysql, or postgresql) installed." : "هیچ درایور پایگاه داده (sqlite ، mysql یا postgresql) نصب نشده است.",
- "Cannot write into \"config\" directory." : "Cannot write into \"config\" directory.",
- "This can usually be fixed by giving the web server write access to the config directory. See %s" : "This can usually be fixed by giving the web server write access to the config directory. See %s",
- "Or, if you prefer to keep config.php file read only, set the option \"config_is_read_only\" to true in it. See %s" : "یا اگر ترجیح می دهید پرونده config.php را فقط بخوانید ، گزینه \"config_is_read_only\" را در آن تنظیم کنید. دیدن%s",
- "Cannot write into \"apps\" directory." : "Cannot write into \"apps\" directory.",
- "This can usually be fixed by giving the web server write access to the apps directory or disabling the App Store in the config file." : "This can usually be fixed by giving the web server write access to the apps directory or disabling the App Store in the config file.",
- "Cannot create \"data\" directory." : "Cannot create \"data\" directory.",
- "This can usually be fixed by giving the web server write access to the root directory. See %s" : "This can usually be fixed by giving the web server write access to the root directory. See %s",
- "Permissions can usually be fixed by giving the web server write access to the root directory. See %s." : "Permissions can usually be fixed by giving the web server write access to the root directory. See %s.",
- "Your data directory is not writable." : "Your data directory is not writable.",
- "Setting locale to %s failed." : "Setting locale to %s failed.",
- "Please install one of these locales on your system and restart your web server." : "Please install one of these locales on your system and restart your web server.",
+ "Cannot write into \"config\" directory." : "نمی‌توان در دایرکتوری «config» نوشت.",
+ "This can usually be fixed by giving the web server write access to the config directory. See %s" : "این مشکل معمولاً با دادن دسترسی نوشتن به وب‌سرور در دایرکتوری پیکربندی قابل رفع است. مشاهده %s",
+ "Or, if you prefer to keep config.php file read only, set the option \"config_is_read_only\" to true in it. See %s" : "یا اگر ترجیح می‌دهید فایل config.php فقط خواندنی باشد، گزینه \"config_is_read_only\" را در آن به true تنظیم کنید. مشاهده %s",
+ "Cannot write into \"apps\" directory." : "نمی‌توان در دایرکتوری «apps» نوشت.",
+ "This can usually be fixed by giving the web server write access to the apps directory or disabling the App Store in the config file." : "این مشکل معمولاً با دادن دسترسی نوشتن به وب‌سرور در دایرکتوری برنامه‌ها یا غیرفعال کردن فروشگاه برنامه در فایل پیکربندی قابل رفع است.",
+ "Cannot create \"data\" directory." : "نمی‌توان دایرکتوری «data» را ایجاد کرد.",
+ "This can usually be fixed by giving the web server write access to the root directory. See %s" : "این مشکل معمولاً با دادن دسترسی نوشتن به وب‌سرور در دایرکتوری ریشه قابل رفع است. مشاهده %s",
+ "Permissions can usually be fixed by giving the web server write access to the root directory. See %s." : "مجوزها معمولاً با دادن دسترسی نوشتن به وب‌سرور در دایرکتوری ریشه قابل رفع هستند. مشاهده %s.",
+ "Your data directory is not writable." : "دایرکتوری داده شما قابل نوشتن نیست.",
+ "Setting locale to %s failed." : "تنظیم محلی به %s ناموفق بود.",
+ "Please install one of these locales on your system and restart your web server." : "لطفاً یکی از این محلی‌ها را روی سیستم خود نصب کرده و وب‌سرور خود را مجدداً راه‌اندازی کنید.",
"PHP module %s not installed." : "ماژول PHP %s نصب نشده است.",
"Please ask your server administrator to install the module." : "لطفا از مدیر سیستم بخواهید تا ماژول را نصب کند.",
- "PHP setting \"%s\" is not set to \"%s\"." : "تنظیمات PHP%s تنظیم نشده است%s",
+ "PHP setting \"%s\" is not set to \"%s\"." : "تنظیمات PHP «%s» روی «%s» تنظیم نشده است.",
"Adjusting this setting in php.ini will make Nextcloud run again" : "تنظیم این تنظیمات در php.ini باعث می شود Nextcloud دوباره اجرا شود",
- "<code>mbstring.func_overload</code> is set to <code>%s</code> instead of the expected value <code>0</code>." : "<code>mbstring.func_overload</code> is set to <code>%s</code> instead of the expected value <code>0</code>.",
- "To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini." : "To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini.",
- "PHP is apparently set up to strip inline doc blocks. This will make several core apps inaccessible." : "PHP ظاهراً برای خنثی کردن بلوک های اسناد درون خطی تنظیم شده است. این کار چندین برنامه اصلی را غیرقابل دسترسی خواهد کرد.",
- "This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "این احتمالاً توسط حافظه پنهان / کش مانند Zend OPcache یا eAccelerator ایجاد شده است.",
- "PHP modules have been installed, but they are still listed as missing?" : "ماژول های پی اچ پی نصب شده اند ، اما هنوز هم به عنوان مفقود شده ذکر شده اند؟",
- "Please ask your server administrator to restart the web server." : "لطفاً از سرور سرور خود بخواهید که وب سرور را مجدداً راه اندازی کند.",
- "The required %s config variable is not configured in the config.php file." : "The required %s config variable is not configured in the config.php file.",
- "Please ask your server administrator to check the Nextcloud configuration." : "Please ask your server administrator to check the Nextcloud configuration.",
- "Your data directory must be an absolute path." : "Your data directory must be an absolute path.",
- "Check the value of \"datadirectory\" in your configuration." : "Check the value of \"datadirectory\" in your configuration.",
- "Your data directory is invalid." : "Your data directory is invalid.",
- "Action \"%s\" not supported or implemented." : "عملی%s پشتیبانی یا اجرا نشده است.",
- "Authentication failed, wrong token or provider ID given" : "تأیید اعتبار انجام نشد ، نشانه اشتباه یا شناسه ارائه دهنده داده شد",
- "Parameters missing in order to complete the request. Missing Parameters: \"%s\"" : "پارامترهای موجود برای تکمیل درخواست. پارامترهای موجود نیست%s",
- "ID \"%1$s\" already used by cloud federation provider \"%2$s\"" : "شناسه%1$s قبلاً توسط ارائه دهنده فدراسیون ابر استفاده شده است%2$s",
- "Cloud Federation Provider with ID: \"%s\" does not exist." : "ارائه دهنده فدراسیون Cloud با شناسه:%s وجود ندارد.",
- "Could not obtain lock type %d on \"%s\"." : "نمی توان نوع%d قفل را به دست آورد%s",
- "Storage unauthorized. %s" : "ذخیره سازی غیر مجاز.%s",
- "Storage incomplete configuration. %s" : "پیکربندی ناقص ذخیره سازی.%s<br>",
- "Storage connection error. %s" : "خطای اتصال ذخیره سازی%s",
- "Storage is temporarily not available" : "ذخیره سازی به طور موقت در دسترس نیست",
- "Storage connection timeout. %s" : "مدت زمان اتصال ذخیره سازی%s",
- "Confirmation" : "Confirmation",
- "Prompt" : "Prompt",
- "Chat" : "Chat",
- "Generates a possible headline for a text." : "Generates a possible headline for a text.",
+ "<code>mbstring.func_overload</code> is set to <code>%s</code> instead of the expected value <code>0</code>." : "<code>mbstring.func_overload</code> به جای مقدار مورد انتظار <code>0</code> روی <code>%s</code> تنظیم شده است.",
+ "To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini." : "برای رفع این مشکل، <code>mbstring.func_overload</code> را در php.ini خود روی <code>0</code> تنظیم کنید.",
+ "PHP is apparently set up to strip inline doc blocks. This will make several core apps inaccessible." : "PHP ظاهراً برای حذف بلوک‌های مستندات درون‌خطی تنظیم شده است. این کار چندین برنامه اصلی را غیرقابل دسترس خواهد کرد.",
+ "This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "این احتمالاً توسط حافظه پنهان/شتاب‌دهنده‌ای مانند Zend OPcache یا eAccelerator ایجاد شده است.",
+ "PHP modules have been installed, but they are still listed as missing?" : "ماژول‌های PHP نصب شده‌اند، اما همچنان به عنوان گم‌شده لیست شده‌اند؟",
+ "Please ask your server administrator to restart the web server." : "لطفاً از مدیر سرور خود بخواهید که وب‌سرور را مجدداً راه‌اندازی کند.",
+ "The required %s config variable is not configured in the config.php file." : "متغیر پیکربندی مورد نیاز %s در فایل config.php پیکربندی نشده است.",
+ "Please ask your server administrator to check the Nextcloud configuration." : "لطفاً از مدیر سرور خود بخواهید پیکربندی Nextcloud را بررسی کند.",
+ "Your data directory is readable by other people." : "دایرکتوری داده شما برای دیگران قابل خواندن است.",
+ "Please change the permissions to 0770 so that the directory cannot be listed by other people." : "لطفاً مجوزها را به 0770 تغییر دهید تا دایرکتوری توسط افراد دیگر قابل فهرست شدن نباشد.",
+ "Your data directory must be an absolute path." : "دایرکتوری داده شما باید یک مسیر مطلق باشد.",
+ "Check the value of \"datadirectory\" in your configuration." : "مقدار \"datadirectory\" را در پیکربندی خود بررسی کنید.",
+ "Your data directory is invalid." : "دایرکتوری داده شما نامعتبر است.",
+ "Ensure there is a file called \"%1$s\" in the root of the data directory. It should have the content: \"%2$s\"" : "اطمینان حاصل کنید که فایلی به نام «%1$s» در ریشه دایرکتوری داده وجود دارد. این فایل باید حاوی: «%2$s» باشد",
+ "Action \"%s\" not supported or implemented." : "عملیات «%s» پشتیبانی یا اجرا نشده است.",
+ "Authentication failed, wrong token or provider ID given" : "تأیید اعتبار انجام نشد، نشانه اشتباه یا شناسه ارائه دهنده داده شد",
+ "Parameters missing in order to complete the request. Missing Parameters: \"%s\"" : "پارامترهای مورد نیاز برای تکمیل درخواست وجود ندارند. پارامترهای از دست رفته: «%s»",
+ "ID \"%1$s\" already used by cloud federation provider \"%2$s\"" : "شناسه «%1$s» قبلاً توسط ارائه‌دهنده فدراسیون ابری «%2$s» استفاده شده است",
+ "Cloud Federation Provider with ID: \"%s\" does not exist." : "ارائه‌دهنده فدراسیون ابری با شناسه: «%s» وجود ندارد.",
+ "Could not obtain lock type %d on \"%s\"." : "نمی‌توان قفل از نوع %d را روی «%s» به دست آورد.",
+ "Storage unauthorized. %s" : "دسترسی به حافظه غیرمجاز است. %s",
+ "Storage incomplete configuration. %s" : "پیکربندی حافظه ناقص است. %s",
+ "Storage connection error. %s" : "خطای اتصال حافظه. %s",
+ "Storage is temporarily not available" : "حافظه به طور موقت در دسترس نیست",
+ "Storage connection timeout. %s" : "مهلت اتصال حافظه به پایان رسید. %s",
+ "To allow this check to run you have to make sure that your Web server can connect to itself. Therefore it must be able to resolve and connect to at least one of its `trusted_domains` or the `overwrite.cli.url`. This failure may be the result of a server-side DNS mismatch or outbound firewall rule." : "برای اجرای این بررسی، باید مطمئن شوید که وب‌سرور شما می‌تواند به خودش متصل شود. بنابراین باید بتواند حداقل یکی از `trusted_domains` یا `overwrite.cli.url` خود را حل و به آن متصل شود. این خطا ممکن است نتیجه عدم تطابق DNS سمت سرور یا قانون فایروال خروجی باشد.",
+ "Transcribe audio" : "رونوشت صوتی",
+ "Transcribe the things said in an audio" : "رونوشت چیزهای گفته شده در یک فایل صوتی",
+ "Audio input" : "ورودی صوتی",
+ "The audio to transcribe" : "فایل صوتی برای رونوشت",
+ "Transcription" : "رونوشت",
+ "The transcribed text" : "متن رونوشت شده",
+ "Chat with an agent" : "چت با یک عامل",
+ "Chat message" : "پیام چت",
+ "A chat message to send to the agent." : "یک پیام چت برای ارسال به عامل.",
+ "Confirmation" : "تأیید",
+ "Whether to confirm previously requested actions: 0 for denial and 1 for confirmation." : "آیا اقدامات قبلاً درخواست شده را تأیید کنید: 0 برای رد و 1 برای تأیید.",
+ "Conversation token" : "توکن مکالمه",
+ "A token representing the conversation." : "یک توکن نماینده مکالمه.",
+ "Generated response" : "پاسخ تولید شده",
+ "The response from the chat model." : "پاسخ از مدل چت.",
+ "The new conversation token" : "توکن مکالمه جدید",
+ "Send this along with the next interaction." : "این را همراه با تعامل بعدی ارسال کنید.",
+ "Requested actions by the agent" : "اقدامات درخواستی توسط عامل",
+ "Actions that the agent would like to carry out in JSON format." : "اقدامات که عامل مایل به انجام آنها در قالب JSON است.",
+ "Context write" : "نوشتن متنی",
+ "Writes text in a given style based on the provided source material." : "متن را با سبکی مشخص بر اساس محتوای منبع ارائه شده می‌نویسد.",
+ "Writing style" : "سبک نگارش",
+ "Demonstrate a writing style that you would like to immitate" : "یک سبک نگارش را که می‌خواهید تقلید کنید، نشان دهید",
+ "Source material" : "محتوای منبع",
+ "The content that would like to be rewritten in the new writing style" : "محتوایی که می‌خواهید با سبک نگارش جدید بازنویسی شود",
+ "Generated text" : "متن تولید شده",
+ "The generated text with content from the source material in the given style" : "متن تولید شده با محتوای منبع در سبک مشخص شده",
+ "Emoji generator" : "تولیدکننده اموجی",
+ "Takes text and generates a representative emoji for it." : "متن را دریافت کرده و یک اموجی مناسب برای آن تولید می‌کند.",
+ "The text to generate an emoji for" : "متنی که می‌خواهید برای آن اموجی تولید شود",
+ "Generated emoji" : "اموجی تولید شده",
+ "The generated emoji based on the input text" : "اموجی تولید شده بر اساس متن ورودی",
+ "Generate image" : "تولید تصویر",
+ "Generate an image from a text prompt" : "تولید تصویر از یک متن ورودی",
+ "Prompt" : "درخواست",
+ "Describe the image you want to generate" : "تصویری که می‌خواهید تولید شود را توصیف کنید",
+ "Number of images" : "تعداد تصاویر",
+ "How many images to generate" : "چه تعداد تصویر تولید شود",
+ "Output images" : "تصاویر خروجی",
+ "The generated images" : "تصاویر تولید شده",
+ "Generate speech" : "تولید گفتار",
+ "Generate speech from a transcript" : "تولید گفتار از یک رونوشت",
+ "Write transcript that you want the assistant to generate speech from" : "رونوشتی را بنویسید که می‌خواهید دستیار از آن گفتار تولید کند",
+ "Output speech" : "گفتار خروجی",
+ "The generated speech" : "گفتار تولید شده",
+ "Free text to text prompt" : "درخواست متن به متن آزاد",
+ "Runs an arbitrary prompt through a language model that returns a reply" : "یک درخواست دلخواه را از طریق یک مدل زبانی اجرا می‌کند که پاسخی را برمی‌گرداند",
+ "Describe a task that you want the assistant to do or ask a question" : "وظیفه‌ای که می‌خواهید دستیار انجام دهد را توصیف کنید یا سؤالی بپرسید",
+ "Generated reply" : "پاسخ تولید شده",
+ "The generated text from the assistant" : "متن تولید شده توسط دستیار",
+ "Change Tone" : "تغییر لحن",
+ "Change the tone of a piece of text." : "لحن یک قطعه متن را تغییر دهید.",
+ "Write a text that you want the assistant to rewrite in another tone." : "متنی را بنویسید که می‌خواهید دستیار آن را با لحن دیگری بازنویسی کند.",
+ "Desired tone" : "لحن مورد نظر",
+ "In which tone should your text be rewritten?" : "متن شما با چه لحنی بازنویسی شود؟",
+ "The rewritten text in the desired tone, written by the assistant:" : "متن بازنویسی شده با لحن مورد نظر، نوشته شده توسط دستیار:",
+ "Chat" : "چت",
+ "Chat with the assistant" : "چت با دستیار",
+ "System prompt" : "درخواست سیستمی",
+ "Define rules and assumptions that the assistant should follow during the conversation." : "قوانین و فرضیاتی را که دستیار باید در طول مکالمه رعایت کند، تعریف کنید.",
+ "Chat history" : "تاریخچه چت",
+ "The history of chat messages before the current message, starting with a message by the user" : "تاریخچه پیام‌های چت قبل از پیام فعلی، با شروع از یک پیام توسط کاربر",
+ "Response message" : "پیام پاسخ",
+ "The generated response as part of the conversation" : "پاسخ تولید شده به عنوان بخشی از مکالمه",
+ "Chat with tools" : "چت با ابزارها",
+ "Chat with the language model with tool calling support." : "چت با مدل زبانی با پشتیبانی از فراخوانی ابزار.",
+ "Tool message" : "پیام ابزار",
+ "The result of tool calls in the last interaction" : "نتیجه فراخوانی ابزارها در تعامل قبلی",
+ "Available tools" : "ابزارهای موجود",
+ "The available tools in JSON format" : "ابزارهای موجود در قالب JSON",
+ "The response from the chat model" : "پاسخ از مدل چت",
+ "Tool calls" : "فراخوانی ابزار",
+ "Tools call instructions from the model in JSON format" : "دستورالعمل‌های فراخوانی ابزار از مدل در قالب JSON",
+ "Formalize text" : "رسمی کردن متن",
+ "Takes a text and makes it sound more formal" : "یک متن را دریافت کرده و آن را رسمی‌تر می‌کند",
+ "Write a text that you want the assistant to formalize" : "متنی را بنویسید که می‌خواهید دستیار آن را رسمی کند",
+ "Formalized text" : "متن رسمی شده",
+ "The formalized text" : "متن رسمی شده",
+ "Generate a headline" : "تولید یک عنوان",
+ "Generates a possible headline for a text." : "یک عنوان احتمالی برای یک متن تولید می‌کند.",
+ "Original text" : "متن اصلی",
+ "The original text to generate a headline for" : "متن اصلی برای تولید عنوان",
+ "The generated headline" : "عنوان تولید شده",
+ "Proofread" : "ویرایش",
+ "Proofreads a text and lists corrections" : "یک متن را ویرایش کرده و اصلاحات را لیست می‌کند",
"Text" : "متن",
- "Summarize" : "Summarize",
+ "The text to proofread" : "متن برای ویرایش",
+ "Corrections" : "اصلاحات",
+ "The corrections that should be made in your text" : "اصلاحاتی که باید در متن شما انجام شود",
+ "Reformulate text" : "بازنویسی متن",
+ "Takes a text and reformulates it" : "یک متن را دریافت کرده و آن را بازنویسی می‌کند",
+ "Write a text that you want the assistant to reformulate" : "متنی را بنویسید که می‌خواهید دستیار آن را بازنویسی کند",
+ "Reformulated text" : "متن بازنویسی شده",
+ "The reformulated text, written by the assistant" : "متن بازنویسی شده، نوشته شده توسط دستیار",
+ "Simplify text" : "ساده‌سازی متن",
+ "Takes a text and simplifies it" : "یک متن را دریافت کرده و آن را ساده می‌کند",
+ "Write a text that you want the assistant to simplify" : "متنی را بنویسید که می‌خواهید دستیار آن را ساده کند",
+ "Simplified text" : "متن ساده شده",
+ "The simplified text" : "متن ساده شده",
+ "Summarize" : "خلاصه‌سازی",
+ "Summarizes a text" : "یک متن را خلاصه‌سازی می‌کند",
+ "The original text to summarize" : "متن اصلی برای خلاصه‌سازی",
"Summary" : "چکیده",
- "Extract topics" : "Extract topics",
+ "The generated summary" : "خلاصه تولید شده",
+ "Extract topics" : "استخراج موضوعات",
+ "Extracts topics from a text and outputs them separated by commas" : "موضوعات را از یک متن استخراج کرده و با کاما جدا شده خروجی می‌دهد",
+ "The original text to extract topics from" : "متن اصلی برای استخراج موضوعات",
+ "Topics" : "موضوعات",
+ "The list of extracted topics" : "لیست موضوعات استخراج شده",
"Translate" : "ترجمه",
- "Target language" : "Target language",
- "Result" : "شروع به اسکنیک",
- "Free prompt" : "Free prompt",
- "Runs an arbitrary prompt through the language model." : "Runs an arbitrary prompt through the language model.",
- "Generate headline" : "Generate headline",
- "Summarizes text by reducing its length without losing key information." : "Summarizes text by reducing its length without losing key information.",
- "Extracts topics from a text and outputs them separated by commas." : "Extracts topics from a text and outputs them separated by commas.",
- "Education Edition" : "نگارش آموزشی",
- "File name is a reserved word" : "این نام فایل جزو کلمات رزرو می‌باشد",
- "File name contains at least one invalid character" : "نام فایل دارای حداقل یک کاراکتر نامعتبر است",
- "File name is too long" : "نام فایل خیلی بزرگ است",
- "Users" : "کاربران",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s به اشتراک گذاشته شده »%2$s« با شماست و می خواهد اضافه کند:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s به اشتراک گذاشته شده »%2$s« با شماست و می خواهد اضافه کند:",
- "»%s« added a note to a file shared with you" : "»%s« یادداشتی را به پرونده ای که با شما به اشتراک گذاشته شده است اضافه کرد",
- "Open »%s«" : "باز کن »%s«",
- "%1$s shared »%2$s« with you" : "%1$s به اشتراک گذاشته » %2$s« با شما",
- "%1$s shared »%2$s« with you." : "%1$s به اشتراک گذاشته » %2$s« با شما",
- "Click the button below to open it." : "برای باز کردن آن روی دکمه زیر کلیک کنید.",
+ "Translate text from one language to another" : "ترجمه متن از یک زبان به زبان دیگر",
+ "Origin text" : "متن مبدأ",
+ "The text to translate" : "متن برای ترجمه",
+ "Origin language" : "زبان مبدأ",
+ "The language of the origin text" : "زبان متن مبدأ",
+ "Target language" : "زبان مقصد",
+ "The desired language to translate the origin text in" : "زبان مورد نظر برای ترجمه متن مبدأ",
+ "Result" : "نتیجه",
+ "The translated text" : "متن ترجمه شده",
+ "Free prompt" : "درخواست آزاد",
+ "Runs an arbitrary prompt through the language model." : "یک درخواست دلخواه را از طریق مدل زبانی اجرا می‌کند.",
+ "Generate headline" : "تولید عنوان",
+ "Summarizes text by reducing its length without losing key information." : "متن را با کاهش طول آن و بدون از دست دادن اطلاعات کلیدی، خلاصه‌سازی می‌کند.",
+ "Extracts topics from a text and outputs them separated by commas." : "موضوعات را از یک متن استخراج کرده و با کاما جدا شده خروجی می‌دهد.",
"File is currently busy, please try again later" : "فایل در حال حاضر مشغول است، لطفا مجددا تلاش کنید",
"Cannot download file" : "نمی‌توان پرونده را بارگرفت",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "اطمینان حاصل کنید که فایلی به نام \".ocdata\" در ریشه دایرکتوری داده وجود دارد."
+ "Login is too long" : "نام کاربری بیش از حد طولانی است"
},"pluralForm" :"nplurals=2; plural=(n > 1);"
} \ No newline at end of file
diff --git a/lib/l10n/fi.js b/lib/l10n/fi.js
index 0af095d14a4..fdabc59a9e1 100644
--- a/lib/l10n/fi.js
+++ b/lib/l10n/fi.js
@@ -67,6 +67,7 @@ OC.L10N.register(
"seconds ago" : "sekunteja sitten",
"Empty file" : "Tyhjä tiedosto",
"Dot files are not allowed" : "Pistetiedostot eivät ole sallittuja",
+ "%1$s (renamed)" : "%1$s (nimetty uudelleen)",
"File already exists" : "Tiedosto on jo olemassa",
"Invalid path" : "Virheellinen polku",
"Failed to create file from template" : "Tiedoston luominen mallipohjasta epäonnistui",
@@ -218,19 +219,7 @@ OC.L10N.register(
"Translate" : "Käännä",
"Target language" : "Kohdekieli",
"Result" : "Tulos",
- "File name is a reserved word" : "Tiedoston nimi on varattu sana",
- "File name contains at least one invalid character" : "Tiedoston nimi sisältää ainakin yhden virheellisen merkin",
- "File name is too long" : "Tiedoston nimi on liian pitkä",
- "Users" : "Käyttäjät",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s jakoi kohteen »%2$s« kanssasi ja haluaa lisätä:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s jakoi kohteen »%2$s« kanssasi ja haluaa lisätä",
- "»%s« added a note to a file shared with you" : "»%s« lisäsi huomion jakamaasi tiedostoon",
- "Open »%s«" : "Avaa »%s«",
- "%1$s shared »%2$s« with you" : "%1$s jakoi kohteen »%2$s« kanssasi",
- "%1$s shared »%2$s« with you." : "%1$s jakoi kohteen »%2$s« kanssasi.",
- "Click the button below to open it." : "Napsauta alla olevaa painiketta avataksesi sen.",
"File is currently busy, please try again later" : "Tiedosto on parhaillaan käytössä, yritä myöhemmin uudelleen",
- "Cannot download file" : "Tiedostoa ei voi ladata",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Varmista että datahakemiston juuressa on tiedosto nimeltä \".ocdata\"."
+ "Cannot download file" : "Tiedostoa ei voi ladata"
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/fi.json b/lib/l10n/fi.json
index 0b582eecd74..a2b35c13827 100644
--- a/lib/l10n/fi.json
+++ b/lib/l10n/fi.json
@@ -65,6 +65,7 @@
"seconds ago" : "sekunteja sitten",
"Empty file" : "Tyhjä tiedosto",
"Dot files are not allowed" : "Pistetiedostot eivät ole sallittuja",
+ "%1$s (renamed)" : "%1$s (nimetty uudelleen)",
"File already exists" : "Tiedosto on jo olemassa",
"Invalid path" : "Virheellinen polku",
"Failed to create file from template" : "Tiedoston luominen mallipohjasta epäonnistui",
@@ -216,19 +217,7 @@
"Translate" : "Käännä",
"Target language" : "Kohdekieli",
"Result" : "Tulos",
- "File name is a reserved word" : "Tiedoston nimi on varattu sana",
- "File name contains at least one invalid character" : "Tiedoston nimi sisältää ainakin yhden virheellisen merkin",
- "File name is too long" : "Tiedoston nimi on liian pitkä",
- "Users" : "Käyttäjät",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s jakoi kohteen »%2$s« kanssasi ja haluaa lisätä:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s jakoi kohteen »%2$s« kanssasi ja haluaa lisätä",
- "»%s« added a note to a file shared with you" : "»%s« lisäsi huomion jakamaasi tiedostoon",
- "Open »%s«" : "Avaa »%s«",
- "%1$s shared »%2$s« with you" : "%1$s jakoi kohteen »%2$s« kanssasi",
- "%1$s shared »%2$s« with you." : "%1$s jakoi kohteen »%2$s« kanssasi.",
- "Click the button below to open it." : "Napsauta alla olevaa painiketta avataksesi sen.",
"File is currently busy, please try again later" : "Tiedosto on parhaillaan käytössä, yritä myöhemmin uudelleen",
- "Cannot download file" : "Tiedostoa ei voi ladata",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Varmista että datahakemiston juuressa on tiedosto nimeltä \".ocdata\"."
+ "Cannot download file" : "Tiedostoa ei voi ladata"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/fr.js b/lib/l10n/fr.js
index cc9d43282cd..bcdeeeabd83 100644
--- a/lib/l10n/fr.js
+++ b/lib/l10n/fr.js
@@ -93,6 +93,8 @@ OC.L10N.register(
"Destination does not exist" : "La destination n'existe pas",
"Destination is not creatable" : "La destination ne peut pas être créée",
"Dot files are not allowed" : "Le nom de fichier ne peut pas commencer par un point",
+ "%1$s (renamed)" : "%1$s (renommé)",
+ "renamed file" : "fichier renommé",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" est un nom de fichier ou de dossier interdit.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" est un préfixe interdit pour les noms de fichiers ou de dossiers.",
"\"%1$s\" is not allowed inside a file or folder name." : "\"%1$s\" n'est pas autorisé dans un nom de fichier ou de dossier.",
@@ -201,6 +203,7 @@ OC.L10N.register(
"Path is already shared with this group" : "Le chemin est déjà partagé avec ce groupe",
"Link sharing is not allowed" : "Le partage de liens n'est pas autorisé",
"Public upload is not allowed" : "Le téléversement public n'est pas autorisé",
+ "You cannot share a folder that contains other shares" : "Vous ne pouvez pas partager un dossier qui contient déjà d'autres partages.",
"Sharing is disabled" : "Le partage est désactivé",
"Sharing is disabled for you" : "Le partage est désactivé pour vous",
"Cannot share with the share owner" : "Impossible de partager avec le propriétaire de l'action",
@@ -272,6 +275,7 @@ OC.L10N.register(
"A valid Login must be provided" : "Un identifiant valide doit être saisi",
"Login contains whitespace at the beginning or at the end" : "L'identifiant contient des espaces au début ou à la fin",
"Login must not consist of dots only" : "L'identifiant ne doit pas être composé uniquement de points",
+ "Username is too long" : "Le nom d'utilisateur est trop long",
"Login is invalid because files already exist for this user" : "L’identifiant n'est pas valide car des fichiers existent déjà pour cet utilisateur",
"Account disabled" : "Compte désactivé",
"Login canceled by app" : "L'authentification a été annulée par l'application",
@@ -362,6 +366,11 @@ OC.L10N.register(
"How many images to generate" : "Nombre d'images à générer",
"Output images" : "Images de sortie",
"The generated images" : "Les images générées",
+ "Generate speech" : "Générer la vocalisation",
+ "Generate speech from a transcript" : "Générer la vocalisation à partir d'une transcription",
+ "Write transcript that you want the assistant to generate speech from" : "Écrire la transcription à partir de laquelle vous voulez générer la vocalisation",
+ "Output speech" : "Sortie de la vocalisation",
+ "The generated speech" : "La vocalisation générée",
"Free text to text prompt" : "Texte libre à texte libre",
"Runs an arbitrary prompt through a language model that returns a reply" : "Exécute une commande arbitraire à l'aide d'un modèle linguistique qui génère une réponse",
"Describe a task that you want the assistant to do or ask a question" : "Décrivez une tâche que vous voulez que l'assistant effectue ou posez une question",
@@ -441,20 +450,8 @@ OC.L10N.register(
"Generate headline" : "Générer un titre",
"Summarizes text by reducing its length without losing key information." : "Résume un texte en réduisant sa longueur sans perdre d’informations essentielles.",
"Extracts topics from a text and outputs them separated by commas." : "Extrait les thèmes d'un texte et les restitue séparés par des virgules.",
- "Education Edition" : "Édition pour l'éducation ",
- "File name is a reserved word" : "Ce nom de fichier est un mot réservé",
- "File name contains at least one invalid character" : "Le nom de fichier contient au moins un caractère invalide",
- "File name is too long" : "Nom de fichier trop long",
- "Users" : "Utilisateurs",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s a partagé « %2$s » avec vous et souhaite ajouter :",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s a partagé « %2$s » avec vous et souhaite ajouter",
- "»%s« added a note to a file shared with you" : "« %s » a ajouté une note à un fichier partagé avec vous",
- "Open »%s«" : "Ouvrir « %s »",
- "%1$s shared »%2$s« with you" : "%1$s a partagé « %2$s » avec vous",
- "%1$s shared »%2$s« with you." : "%1$s a partagé « %2$s » avec vous.",
- "Click the button below to open it." : "Cliquez sur le bouton ci-dessous pour l'ouvrir",
"File is currently busy, please try again later" : "Le fichier est actuellement utilisé, veuillez réessayer plus tard",
"Cannot download file" : "Impossible de télécharger le fichier",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Assurez-vous que le répertoire de données contient un fichier \".ocdata\" à sa racine."
+ "Login is too long" : "L'authentification est trop longue"
},
"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/lib/l10n/fr.json b/lib/l10n/fr.json
index 83615416df1..e6d19d589f0 100644
--- a/lib/l10n/fr.json
+++ b/lib/l10n/fr.json
@@ -91,6 +91,8 @@
"Destination does not exist" : "La destination n'existe pas",
"Destination is not creatable" : "La destination ne peut pas être créée",
"Dot files are not allowed" : "Le nom de fichier ne peut pas commencer par un point",
+ "%1$s (renamed)" : "%1$s (renommé)",
+ "renamed file" : "fichier renommé",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" est un nom de fichier ou de dossier interdit.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" est un préfixe interdit pour les noms de fichiers ou de dossiers.",
"\"%1$s\" is not allowed inside a file or folder name." : "\"%1$s\" n'est pas autorisé dans un nom de fichier ou de dossier.",
@@ -199,6 +201,7 @@
"Path is already shared with this group" : "Le chemin est déjà partagé avec ce groupe",
"Link sharing is not allowed" : "Le partage de liens n'est pas autorisé",
"Public upload is not allowed" : "Le téléversement public n'est pas autorisé",
+ "You cannot share a folder that contains other shares" : "Vous ne pouvez pas partager un dossier qui contient déjà d'autres partages.",
"Sharing is disabled" : "Le partage est désactivé",
"Sharing is disabled for you" : "Le partage est désactivé pour vous",
"Cannot share with the share owner" : "Impossible de partager avec le propriétaire de l'action",
@@ -270,6 +273,7 @@
"A valid Login must be provided" : "Un identifiant valide doit être saisi",
"Login contains whitespace at the beginning or at the end" : "L'identifiant contient des espaces au début ou à la fin",
"Login must not consist of dots only" : "L'identifiant ne doit pas être composé uniquement de points",
+ "Username is too long" : "Le nom d'utilisateur est trop long",
"Login is invalid because files already exist for this user" : "L’identifiant n'est pas valide car des fichiers existent déjà pour cet utilisateur",
"Account disabled" : "Compte désactivé",
"Login canceled by app" : "L'authentification a été annulée par l'application",
@@ -360,6 +364,11 @@
"How many images to generate" : "Nombre d'images à générer",
"Output images" : "Images de sortie",
"The generated images" : "Les images générées",
+ "Generate speech" : "Générer la vocalisation",
+ "Generate speech from a transcript" : "Générer la vocalisation à partir d'une transcription",
+ "Write transcript that you want the assistant to generate speech from" : "Écrire la transcription à partir de laquelle vous voulez générer la vocalisation",
+ "Output speech" : "Sortie de la vocalisation",
+ "The generated speech" : "La vocalisation générée",
"Free text to text prompt" : "Texte libre à texte libre",
"Runs an arbitrary prompt through a language model that returns a reply" : "Exécute une commande arbitraire à l'aide d'un modèle linguistique qui génère une réponse",
"Describe a task that you want the assistant to do or ask a question" : "Décrivez une tâche que vous voulez que l'assistant effectue ou posez une question",
@@ -439,20 +448,8 @@
"Generate headline" : "Générer un titre",
"Summarizes text by reducing its length without losing key information." : "Résume un texte en réduisant sa longueur sans perdre d’informations essentielles.",
"Extracts topics from a text and outputs them separated by commas." : "Extrait les thèmes d'un texte et les restitue séparés par des virgules.",
- "Education Edition" : "Édition pour l'éducation ",
- "File name is a reserved word" : "Ce nom de fichier est un mot réservé",
- "File name contains at least one invalid character" : "Le nom de fichier contient au moins un caractère invalide",
- "File name is too long" : "Nom de fichier trop long",
- "Users" : "Utilisateurs",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s a partagé « %2$s » avec vous et souhaite ajouter :",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s a partagé « %2$s » avec vous et souhaite ajouter",
- "»%s« added a note to a file shared with you" : "« %s » a ajouté une note à un fichier partagé avec vous",
- "Open »%s«" : "Ouvrir « %s »",
- "%1$s shared »%2$s« with you" : "%1$s a partagé « %2$s » avec vous",
- "%1$s shared »%2$s« with you." : "%1$s a partagé « %2$s » avec vous.",
- "Click the button below to open it." : "Cliquez sur le bouton ci-dessous pour l'ouvrir",
"File is currently busy, please try again later" : "Le fichier est actuellement utilisé, veuillez réessayer plus tard",
"Cannot download file" : "Impossible de télécharger le fichier",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Assurez-vous que le répertoire de données contient un fichier \".ocdata\" à sa racine."
+ "Login is too long" : "L'authentification est trop longue"
},"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
} \ No newline at end of file
diff --git a/lib/l10n/ga.js b/lib/l10n/ga.js
index 4c1832afec9..481a89b9f06 100644
--- a/lib/l10n/ga.js
+++ b/lib/l10n/ga.js
@@ -93,6 +93,8 @@ OC.L10N.register(
"Destination does not exist" : "Níl ceann scríbe ann",
"Destination is not creatable" : "Níl ceann scríbe cruthaithe",
"Dot files are not allowed" : "Ní cheadaítear comhaid ponc",
+ "%1$s (renamed)" : "%1$s (athainmnithe)",
+ "renamed file" : "comhad athainmnithe",
"\"%1$s\" is a forbidden file or folder name." : "Is ainm toirmiscthe comhaid nó fillteáin é \"%1$s\".",
"\"%1$s\" is a forbidden prefix for file or folder names." : "Réimír toirmiscthe é \"%1$s\" d'ainmneacha comhaid nó fillteán.",
"\"%1$s\" is not allowed inside a file or folder name." : "Ní cheadaítear \"%1$s\" taobh istigh d'ainm comhaid nó fillteáin.",
@@ -273,7 +275,7 @@ OC.L10N.register(
"A valid Login must be provided" : "Ní mór Logáil Isteach bailí a sholáthar",
"Login contains whitespace at the beginning or at the end" : "Tá spás bán sa logáil isteach ag an tús nó ag an deireadh",
"Login must not consist of dots only" : "Níor cheart go gcuimseodh logáil isteach poncanna amháin",
- "Login is too long" : "Tá logáil isteach ró-fhada",
+ "Username is too long" : "Tá an t-ainm úsáideora rófhada",
"Login is invalid because files already exist for this user" : "Tá logáil isteach neamhbhailí toisc go bhfuil comhaid ann cheana don úsáideoir seo",
"Account disabled" : "Díchumasaíodh an cuntas",
"Login canceled by app" : "Cealaíodh logáil isteach ag an aip",
@@ -364,6 +366,11 @@ OC.L10N.register(
"How many images to generate" : "Cé mhéad íomhánna atá le giniúint",
"Output images" : "Íomhánna aschuir",
"The generated images" : "Na híomhánna a ghintear",
+ "Generate speech" : "Gin urlabhra",
+ "Generate speech from a transcript" : "Gin urlabhra ó thrascríbhinn",
+ "Write transcript that you want the assistant to generate speech from" : "Scríobh an tras-scríbhinn ar mhaith leat go nginfeadh an cúntóir urlabhra uaidh",
+ "Output speech" : "Aschur cainte",
+ "The generated speech" : "An chaint ghinte",
"Free text to text prompt" : "Teimpléad téacs go téacs saor in aisce,",
"Runs an arbitrary prompt through a language model that returns a reply" : "Ritheann leid treallach trí mhúnla teanga a sheolann freagra ar ais",
"Describe a task that you want the assistant to do or ask a question" : "Déan cur síos ar thasc a theastaíonn uait don chúntóir a dhéanamh nó ceist a chur",
@@ -443,20 +450,8 @@ OC.L10N.register(
"Generate headline" : "Gin ceannlíne",
"Summarizes text by reducing its length without losing key information." : "Déanann sé achoimre ar théacs trína fhad a laghdú gan eochairfhaisnéis a chailliúint.",
"Extracts topics from a text and outputs them separated by commas." : "Sliocht topaicí as téacs agus aschuir iad scartha le camóga.",
- "Education Edition" : "Eagrán Oideachais",
- "File name is a reserved word" : "Focal in áirithe is ea ainm comhaid",
- "File name contains at least one invalid character" : "Tá carachtar neamhbhailí amháin ar a laghad san ainm comhaid",
- "File name is too long" : "Tá ainm an chomhaid rófhada",
- "Users" : "Úsáideoirí",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s shared »%2$s« with you and wants to add:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s shared »%2$s« with you and wants to add",
- "»%s« added a note to a file shared with you" : "»%s« added a note to a file shared with you",
- "Open »%s«" : "Oscail »%s«",
- "%1$s shared »%2$s« with you" : "Roinn %1$s »%2$s« leat",
- "%1$s shared »%2$s« with you." : "Roinn %1$s »%2$s« leat.",
- "Click the button below to open it." : "Cliceáil ar an gcnaipe thíos chun é a oscailt.",
"File is currently busy, please try again later" : "Tá an comhad gnóthach faoi láthair, bain triail eile as ar ball le do thoil",
"Cannot download file" : "Ní féidir an comhad a íoslódáil",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Cinntigh go bhfuil comhad darb ainm \".ocdata\" i bhfréamh an eolaire sonraí."
+ "Login is too long" : "Tá logáil isteach ró-fhada"
},
"nplurals=5; plural=(n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n<11 ? 3 : 4);");
diff --git a/lib/l10n/ga.json b/lib/l10n/ga.json
index 9c680309924..669754526c2 100644
--- a/lib/l10n/ga.json
+++ b/lib/l10n/ga.json
@@ -91,6 +91,8 @@
"Destination does not exist" : "Níl ceann scríbe ann",
"Destination is not creatable" : "Níl ceann scríbe cruthaithe",
"Dot files are not allowed" : "Ní cheadaítear comhaid ponc",
+ "%1$s (renamed)" : "%1$s (athainmnithe)",
+ "renamed file" : "comhad athainmnithe",
"\"%1$s\" is a forbidden file or folder name." : "Is ainm toirmiscthe comhaid nó fillteáin é \"%1$s\".",
"\"%1$s\" is a forbidden prefix for file or folder names." : "Réimír toirmiscthe é \"%1$s\" d'ainmneacha comhaid nó fillteán.",
"\"%1$s\" is not allowed inside a file or folder name." : "Ní cheadaítear \"%1$s\" taobh istigh d'ainm comhaid nó fillteáin.",
@@ -271,7 +273,7 @@
"A valid Login must be provided" : "Ní mór Logáil Isteach bailí a sholáthar",
"Login contains whitespace at the beginning or at the end" : "Tá spás bán sa logáil isteach ag an tús nó ag an deireadh",
"Login must not consist of dots only" : "Níor cheart go gcuimseodh logáil isteach poncanna amháin",
- "Login is too long" : "Tá logáil isteach ró-fhada",
+ "Username is too long" : "Tá an t-ainm úsáideora rófhada",
"Login is invalid because files already exist for this user" : "Tá logáil isteach neamhbhailí toisc go bhfuil comhaid ann cheana don úsáideoir seo",
"Account disabled" : "Díchumasaíodh an cuntas",
"Login canceled by app" : "Cealaíodh logáil isteach ag an aip",
@@ -362,6 +364,11 @@
"How many images to generate" : "Cé mhéad íomhánna atá le giniúint",
"Output images" : "Íomhánna aschuir",
"The generated images" : "Na híomhánna a ghintear",
+ "Generate speech" : "Gin urlabhra",
+ "Generate speech from a transcript" : "Gin urlabhra ó thrascríbhinn",
+ "Write transcript that you want the assistant to generate speech from" : "Scríobh an tras-scríbhinn ar mhaith leat go nginfeadh an cúntóir urlabhra uaidh",
+ "Output speech" : "Aschur cainte",
+ "The generated speech" : "An chaint ghinte",
"Free text to text prompt" : "Teimpléad téacs go téacs saor in aisce,",
"Runs an arbitrary prompt through a language model that returns a reply" : "Ritheann leid treallach trí mhúnla teanga a sheolann freagra ar ais",
"Describe a task that you want the assistant to do or ask a question" : "Déan cur síos ar thasc a theastaíonn uait don chúntóir a dhéanamh nó ceist a chur",
@@ -441,20 +448,8 @@
"Generate headline" : "Gin ceannlíne",
"Summarizes text by reducing its length without losing key information." : "Déanann sé achoimre ar théacs trína fhad a laghdú gan eochairfhaisnéis a chailliúint.",
"Extracts topics from a text and outputs them separated by commas." : "Sliocht topaicí as téacs agus aschuir iad scartha le camóga.",
- "Education Edition" : "Eagrán Oideachais",
- "File name is a reserved word" : "Focal in áirithe is ea ainm comhaid",
- "File name contains at least one invalid character" : "Tá carachtar neamhbhailí amháin ar a laghad san ainm comhaid",
- "File name is too long" : "Tá ainm an chomhaid rófhada",
- "Users" : "Úsáideoirí",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s shared »%2$s« with you and wants to add:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s shared »%2$s« with you and wants to add",
- "»%s« added a note to a file shared with you" : "»%s« added a note to a file shared with you",
- "Open »%s«" : "Oscail »%s«",
- "%1$s shared »%2$s« with you" : "Roinn %1$s »%2$s« leat",
- "%1$s shared »%2$s« with you." : "Roinn %1$s »%2$s« leat.",
- "Click the button below to open it." : "Cliceáil ar an gcnaipe thíos chun é a oscailt.",
"File is currently busy, please try again later" : "Tá an comhad gnóthach faoi láthair, bain triail eile as ar ball le do thoil",
"Cannot download file" : "Ní féidir an comhad a íoslódáil",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Cinntigh go bhfuil comhad darb ainm \".ocdata\" i bhfréamh an eolaire sonraí."
+ "Login is too long" : "Tá logáil isteach ró-fhada"
},"pluralForm" :"nplurals=5; plural=(n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n<11 ? 3 : 4);"
} \ No newline at end of file
diff --git a/lib/l10n/gl.js b/lib/l10n/gl.js
index 2a93ff8dc0c..adcd145ae66 100644
--- a/lib/l10n/gl.js
+++ b/lib/l10n/gl.js
@@ -112,7 +112,7 @@ OC.L10N.register(
"Moving a storage (%s) into another storage (%s) is not allowed" : "Non está permitido mover un almacenamento (%s) cara a outro almacenamento (%s)",
"Path contains invalid segments" : "A ruta contén segmentos non válidos",
"Filename is a reserved word" : "O nome de ficheiro é unha palabra reservada",
- "Filename contains at least one invalid character" : "O nome de ficheiro contén algún carácter incorrecto",
+ "Filename contains at least one invalid character" : "O nome de ficheiro contén algún carácter non aceptado",
"Filename is too long" : "O nome de ficheiro é longo de máis",
"Empty filename is not allowed" : "Non está permitido deixar baleiro o nome de ficheiro",
"App \"%s\" cannot be installed because appinfo file cannot be read." : "Non é posíbel instalar a aplicación «%s» por mor de non poder ler o ficheiro appinfo.",
@@ -441,20 +441,7 @@ OC.L10N.register(
"Generate headline" : "Xerar titular",
"Summarizes text by reducing its length without losing key information." : "Resume o texto reducindo a súa lonxitude sen perder a información clave.",
"Extracts topics from a text and outputs them separated by commas." : "Extrae temas dun texto e amósaos separados por comas.",
- "Education Edition" : "Edición para educación",
- "File name is a reserved word" : "O nome de ficheiro é unha palabra reservada",
- "File name contains at least one invalid character" : "O nome de ficheiro contén algún carácter incorrecto",
- "File name is too long" : "O nome de ficheiro é longo de máis",
- "Users" : "Usuarios",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s compartiu «%2$s» con Vde. e quere engadir:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s compartiu «%2$s» con Vde. e quere engadir",
- "»%s« added a note to a file shared with you" : "«%s» engadiu unha nota a un ficheiro compartido con Vde.",
- "Open »%s«" : "Abrir «%s»",
- "%1$s shared »%2$s« with you" : "%1$s compartiu «%2$s» con Vde.",
- "%1$s shared »%2$s« with you." : "%1$s compartiu «%2$s» con Vde.",
- "Click the button below to open it." : "Prema no botón de embaixo para abrilo.",
"File is currently busy, please try again later" : "O ficheiro está ocupado neste momento, ténteo máis adiante.",
- "Cannot download file" : "Non é posíbel descargar o ficheiro",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegúrese de que existe un ficheiro chamado «.ocdata» na raíz do directorio de datos."
+ "Cannot download file" : "Non é posíbel descargar o ficheiro"
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/gl.json b/lib/l10n/gl.json
index 5554f08ac06..ea8fc00b36c 100644
--- a/lib/l10n/gl.json
+++ b/lib/l10n/gl.json
@@ -110,7 +110,7 @@
"Moving a storage (%s) into another storage (%s) is not allowed" : "Non está permitido mover un almacenamento (%s) cara a outro almacenamento (%s)",
"Path contains invalid segments" : "A ruta contén segmentos non válidos",
"Filename is a reserved word" : "O nome de ficheiro é unha palabra reservada",
- "Filename contains at least one invalid character" : "O nome de ficheiro contén algún carácter incorrecto",
+ "Filename contains at least one invalid character" : "O nome de ficheiro contén algún carácter non aceptado",
"Filename is too long" : "O nome de ficheiro é longo de máis",
"Empty filename is not allowed" : "Non está permitido deixar baleiro o nome de ficheiro",
"App \"%s\" cannot be installed because appinfo file cannot be read." : "Non é posíbel instalar a aplicación «%s» por mor de non poder ler o ficheiro appinfo.",
@@ -439,20 +439,7 @@
"Generate headline" : "Xerar titular",
"Summarizes text by reducing its length without losing key information." : "Resume o texto reducindo a súa lonxitude sen perder a información clave.",
"Extracts topics from a text and outputs them separated by commas." : "Extrae temas dun texto e amósaos separados por comas.",
- "Education Edition" : "Edición para educación",
- "File name is a reserved word" : "O nome de ficheiro é unha palabra reservada",
- "File name contains at least one invalid character" : "O nome de ficheiro contén algún carácter incorrecto",
- "File name is too long" : "O nome de ficheiro é longo de máis",
- "Users" : "Usuarios",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s compartiu «%2$s» con Vde. e quere engadir:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s compartiu «%2$s» con Vde. e quere engadir",
- "»%s« added a note to a file shared with you" : "«%s» engadiu unha nota a un ficheiro compartido con Vde.",
- "Open »%s«" : "Abrir «%s»",
- "%1$s shared »%2$s« with you" : "%1$s compartiu «%2$s» con Vde.",
- "%1$s shared »%2$s« with you." : "%1$s compartiu «%2$s» con Vde.",
- "Click the button below to open it." : "Prema no botón de embaixo para abrilo.",
"File is currently busy, please try again later" : "O ficheiro está ocupado neste momento, ténteo máis adiante.",
- "Cannot download file" : "Non é posíbel descargar o ficheiro",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asegúrese de que existe un ficheiro chamado «.ocdata» na raíz do directorio de datos."
+ "Cannot download file" : "Non é posíbel descargar o ficheiro"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/he.js b/lib/l10n/he.js
index 3e95f5baab2..f323b3980b3 100644
--- a/lib/l10n/he.js
+++ b/lib/l10n/he.js
@@ -156,19 +156,6 @@ OC.L10N.register(
"Summary" : "תקציר",
"Translate" : "תרגום",
"Result" : "תוצאה",
- "Education Edition" : "מהדורה חינוכית",
- "File name is a reserved word" : "שם קובץ הוא מילה שמורה",
- "File name contains at least one invalid character" : "שם הקובץ כולל לפחות תו אחד לא חוקי",
- "File name is too long" : "שם קובץ ארוך מדי",
- "Users" : "משתמשים",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s שיתף » %2$s« איתך, ורוצה להוסיף:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$sשיתף »%2$s« איתך, ורוצה להוסיף:",
- "»%s« added a note to a file shared with you" : "התווספה הערה על קובץ ששותף את על ידי „%s”",
- "Open »%s«" : "פתיחת „%s”",
- "%1$s shared »%2$s« with you" : "%2$s שותף אתך על ידי %1$s",
- "%1$s shared »%2$s« with you." : "„%2$s” שותף אתך על ידי %1$s.",
- "Click the button below to open it." : "יש ללחוץ על הכפתור להלן כדי לפתוח אותו.",
- "File is currently busy, please try again later" : "הקובץ בשימוש כרגע, יש לנסות שוב מאוחר יותר",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "נא לוודא שיש קובץ בשם „‎.ocdata” בבסיס תיקיית הנתונים שלך."
+ "File is currently busy, please try again later" : "הקובץ בשימוש כרגע, יש לנסות שוב מאוחר יותר"
},
"nplurals=3; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % 1 == 0) ? 1: 2;");
diff --git a/lib/l10n/he.json b/lib/l10n/he.json
index edbf2b81230..68fd61703fd 100644
--- a/lib/l10n/he.json
+++ b/lib/l10n/he.json
@@ -154,19 +154,6 @@
"Summary" : "תקציר",
"Translate" : "תרגום",
"Result" : "תוצאה",
- "Education Edition" : "מהדורה חינוכית",
- "File name is a reserved word" : "שם קובץ הוא מילה שמורה",
- "File name contains at least one invalid character" : "שם הקובץ כולל לפחות תו אחד לא חוקי",
- "File name is too long" : "שם קובץ ארוך מדי",
- "Users" : "משתמשים",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s שיתף » %2$s« איתך, ורוצה להוסיף:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$sשיתף »%2$s« איתך, ורוצה להוסיף:",
- "»%s« added a note to a file shared with you" : "התווספה הערה על קובץ ששותף את על ידי „%s”",
- "Open »%s«" : "פתיחת „%s”",
- "%1$s shared »%2$s« with you" : "%2$s שותף אתך על ידי %1$s",
- "%1$s shared »%2$s« with you." : "„%2$s” שותף אתך על ידי %1$s.",
- "Click the button below to open it." : "יש ללחוץ על הכפתור להלן כדי לפתוח אותו.",
- "File is currently busy, please try again later" : "הקובץ בשימוש כרגע, יש לנסות שוב מאוחר יותר",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "נא לוודא שיש קובץ בשם „‎.ocdata” בבסיס תיקיית הנתונים שלך."
+ "File is currently busy, please try again later" : "הקובץ בשימוש כרגע, יש לנסות שוב מאוחר יותר"
},"pluralForm" :"nplurals=3; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % 1 == 0) ? 1: 2;"
} \ No newline at end of file
diff --git a/lib/l10n/hr.js b/lib/l10n/hr.js
index fc647a96851..9d8f5fdd20a 100644
--- a/lib/l10n/hr.js
+++ b/lib/l10n/hr.js
@@ -200,19 +200,6 @@ OC.L10N.register(
"Summary" : "Sažetak",
"Translate" : "Prevedi",
"Result" : "Rezultat",
- "Education Edition" : "Obrazovno izdanje",
- "File name is a reserved word" : "Naziv datoteke je rezervirana riječ",
- "File name contains at least one invalid character" : "Naziv datoteke sadrži barem jedan nevažeći znak",
- "File name is too long" : "Naziv datoteke je predugačak",
- "Users" : "Korisnici",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s dijeli »%2$s« s vama i želi dodati:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s dijeli »%2$s« s vama i želi dodati",
- "»%s« added a note to a file shared with you" : "»%s« je dodao bilješku datoteci koju dijeli s vama",
- "Open »%s«" : "Otvori »%s«",
- "%1$s shared »%2$s« with you" : "%1$s dijeli »%2$s« s vama",
- "%1$s shared »%2$s« with you." : "%1$s dijeli »%2$s« s vama.",
- "Click the button below to open it." : "Kliknite gumb u nastavku za otvaranje.",
- "File is currently busy, please try again later" : "Datoteka je trenutno zauzeta, pokušajte ponovo kasnije",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Provjerite postoji li datoteka pod nazivom „.ocdata” u korijenu podatkovnog direktorija."
+ "File is currently busy, please try again later" : "Datoteka je trenutno zauzeta, pokušajte ponovo kasnije"
},
"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/lib/l10n/hr.json b/lib/l10n/hr.json
index 48f7d480bd9..1fb76436871 100644
--- a/lib/l10n/hr.json
+++ b/lib/l10n/hr.json
@@ -198,19 +198,6 @@
"Summary" : "Sažetak",
"Translate" : "Prevedi",
"Result" : "Rezultat",
- "Education Edition" : "Obrazovno izdanje",
- "File name is a reserved word" : "Naziv datoteke je rezervirana riječ",
- "File name contains at least one invalid character" : "Naziv datoteke sadrži barem jedan nevažeći znak",
- "File name is too long" : "Naziv datoteke je predugačak",
- "Users" : "Korisnici",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s dijeli »%2$s« s vama i želi dodati:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s dijeli »%2$s« s vama i želi dodati",
- "»%s« added a note to a file shared with you" : "»%s« je dodao bilješku datoteci koju dijeli s vama",
- "Open »%s«" : "Otvori »%s«",
- "%1$s shared »%2$s« with you" : "%1$s dijeli »%2$s« s vama",
- "%1$s shared »%2$s« with you." : "%1$s dijeli »%2$s« s vama.",
- "Click the button below to open it." : "Kliknite gumb u nastavku za otvaranje.",
- "File is currently busy, please try again later" : "Datoteka je trenutno zauzeta, pokušajte ponovo kasnije",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Provjerite postoji li datoteka pod nazivom „.ocdata” u korijenu podatkovnog direktorija."
+ "File is currently busy, please try again later" : "Datoteka je trenutno zauzeta, pokušajte ponovo kasnije"
},"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;"
} \ No newline at end of file
diff --git a/lib/l10n/hu.js b/lib/l10n/hu.js
index a54358dcf1e..21d0f6b986f 100644
--- a/lib/l10n/hu.js
+++ b/lib/l10n/hu.js
@@ -77,6 +77,8 @@ OC.L10N.register(
"Empty file" : "Üres fájl",
"Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "A(z) %s azonosítójú modul nem létezik. Engedélyezze az alkalmazásbeállításokban, vagy lépjen kapcsolatba a rendszergazdával.",
"Dot files are not allowed" : "A ponttal kezdődő fájlok nem engedélyezettek",
+ "%1$s (renamed)" : "%1$s (átnevezve)",
+ "renamed file" : "átnevezett fájl",
"Filenames must not end with \"%1$s\"." : "Fájlnév nem végződhet így: „%1$s”.",
"File already exists" : "A fájl már létezik",
"Invalid path" : "Érvénytelen útvonal",
@@ -245,20 +247,7 @@ OC.L10N.register(
"Generate headline" : "Címsor előállítása",
"Summarizes text by reducing its length without losing key information." : "Összesíti a szöveget a hosszúság csökkentésével anélkül, hogy a kulcsinformációk elvesznének.",
"Extracts topics from a text and outputs them separated by commas." : "Kinyeri a témákat a szövegből, és vesszőkkel elválasztva megjeleníti.",
- "Education Edition" : "Oktatási kiadás",
- "File name is a reserved word" : "A fájl neve egy fenntartott szó",
- "File name contains at least one invalid character" : "A fájlnév legalább egy érvénytelen karaktert tartalmaz",
- "File name is too long" : "A fájlnév túl hosszú",
- "Users" : "Felhasználók",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s megosztotta Önnel: „%2$s”, és hozzá akarja adni:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s megosztotta Önnel: „%2$s”, és hozzá akarja adni",
- "»%s« added a note to a file shared with you" : "„%s” megjegyzést fűzött az Önnel megosztott fájlhoz",
- "Open »%s«" : "A(z) „%s” megnyitása",
- "%1$s shared »%2$s« with you" : "%1$s megosztotta Önnel: „%2$s”",
- "%1$s shared »%2$s« with you." : "%1$s megosztotta Önnel: „%2$s”.",
- "Click the button below to open it." : "Kattintson a lenti gombra a megnyitáshoz.",
"File is currently busy, please try again later" : "A fájl jelenleg foglalt, próbálja újra később",
- "Cannot download file" : "A fájl nem tölthető le",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Győződjön meg róla, hogy az adatmappa gyökerében van-e egy „.ocdata” fájl."
+ "Cannot download file" : "A fájl nem tölthető le"
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/hu.json b/lib/l10n/hu.json
index 267e472e282..e40d8174716 100644
--- a/lib/l10n/hu.json
+++ b/lib/l10n/hu.json
@@ -75,6 +75,8 @@
"Empty file" : "Üres fájl",
"Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "A(z) %s azonosítójú modul nem létezik. Engedélyezze az alkalmazásbeállításokban, vagy lépjen kapcsolatba a rendszergazdával.",
"Dot files are not allowed" : "A ponttal kezdődő fájlok nem engedélyezettek",
+ "%1$s (renamed)" : "%1$s (átnevezve)",
+ "renamed file" : "átnevezett fájl",
"Filenames must not end with \"%1$s\"." : "Fájlnév nem végződhet így: „%1$s”.",
"File already exists" : "A fájl már létezik",
"Invalid path" : "Érvénytelen útvonal",
@@ -243,20 +245,7 @@
"Generate headline" : "Címsor előállítása",
"Summarizes text by reducing its length without losing key information." : "Összesíti a szöveget a hosszúság csökkentésével anélkül, hogy a kulcsinformációk elvesznének.",
"Extracts topics from a text and outputs them separated by commas." : "Kinyeri a témákat a szövegből, és vesszőkkel elválasztva megjeleníti.",
- "Education Edition" : "Oktatási kiadás",
- "File name is a reserved word" : "A fájl neve egy fenntartott szó",
- "File name contains at least one invalid character" : "A fájlnév legalább egy érvénytelen karaktert tartalmaz",
- "File name is too long" : "A fájlnév túl hosszú",
- "Users" : "Felhasználók",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s megosztotta Önnel: „%2$s”, és hozzá akarja adni:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s megosztotta Önnel: „%2$s”, és hozzá akarja adni",
- "»%s« added a note to a file shared with you" : "„%s” megjegyzést fűzött az Önnel megosztott fájlhoz",
- "Open »%s«" : "A(z) „%s” megnyitása",
- "%1$s shared »%2$s« with you" : "%1$s megosztotta Önnel: „%2$s”",
- "%1$s shared »%2$s« with you." : "%1$s megosztotta Önnel: „%2$s”.",
- "Click the button below to open it." : "Kattintson a lenti gombra a megnyitáshoz.",
"File is currently busy, please try again later" : "A fájl jelenleg foglalt, próbálja újra később",
- "Cannot download file" : "A fájl nem tölthető le",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Győződjön meg róla, hogy az adatmappa gyökerében van-e egy „.ocdata” fájl."
+ "Cannot download file" : "A fájl nem tölthető le"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/hy.js b/lib/l10n/hy.js
index 03eec156fb5..2c74b272b2f 100644
--- a/lib/l10n/hy.js
+++ b/lib/l10n/hy.js
@@ -57,7 +57,6 @@ OC.L10N.register(
"Oct." : "Հոկ.",
"Nov." : "Նոյ.",
"Dec." : "Դեկ.",
- "Translate" : "Թարգմանել",
- "File name contains at least one invalid character" : "Ֆայլի անունը առնվազն մի անվավեր նիշ է պարունակում"
+ "Translate" : "Թարգմանել"
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/hy.json b/lib/l10n/hy.json
index 24bf5ae146b..7284fefe1af 100644
--- a/lib/l10n/hy.json
+++ b/lib/l10n/hy.json
@@ -55,7 +55,6 @@
"Oct." : "Հոկ.",
"Nov." : "Նոյ.",
"Dec." : "Դեկ.",
- "Translate" : "Թարգմանել",
- "File name contains at least one invalid character" : "Ֆայլի անունը առնվազն մի անվավեր նիշ է պարունակում"
+ "Translate" : "Թարգմանել"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/ia.js b/lib/l10n/ia.js
index f5bd981b64f..cc0a431ce3a 100644
--- a/lib/l10n/ia.js
+++ b/lib/l10n/ia.js
@@ -64,7 +64,6 @@ OC.L10N.register(
"A valid password must be provided" : "Un contrasigno valide debe esser providite",
"Authentication error" : "Error in authentication",
"Storage is temporarily not available" : "Immagazinage es provisorimente non disponibile",
- "Summary" : "Summario",
- "Users" : "Usatores"
+ "Summary" : "Summario"
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/ia.json b/lib/l10n/ia.json
index e9513320161..62ee67dcb63 100644
--- a/lib/l10n/ia.json
+++ b/lib/l10n/ia.json
@@ -62,7 +62,6 @@
"A valid password must be provided" : "Un contrasigno valide debe esser providite",
"Authentication error" : "Error in authentication",
"Storage is temporarily not available" : "Immagazinage es provisorimente non disponibile",
- "Summary" : "Summario",
- "Users" : "Usatores"
+ "Summary" : "Summario"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/id.js b/lib/l10n/id.js
index 2d601410fab..c7c14e71638 100644
--- a/lib/l10n/id.js
+++ b/lib/l10n/id.js
@@ -130,11 +130,6 @@ OC.L10N.register(
"Text" : "Teks",
"Summary" : "Kesimpulan",
"Translate" : "Terjemahkan",
- "File name is a reserved word" : "Nama berkas merupakan kata yang disediakan",
- "File name contains at least one invalid character" : "Nama berkas berisi setidaknya satu karakter yang tidak sah.",
- "File name is too long" : "Nama berkas terlalu panjang",
- "Users" : "Pengguna",
- "Open »%s«" : "Buka »%s«",
"File is currently busy, please try again later" : "Berkas sedang sibuk, mohon coba lagi nanti"
},
"nplurals=1; plural=0;");
diff --git a/lib/l10n/id.json b/lib/l10n/id.json
index 9a315a4a2d2..99bf3880dd6 100644
--- a/lib/l10n/id.json
+++ b/lib/l10n/id.json
@@ -128,11 +128,6 @@
"Text" : "Teks",
"Summary" : "Kesimpulan",
"Translate" : "Terjemahkan",
- "File name is a reserved word" : "Nama berkas merupakan kata yang disediakan",
- "File name contains at least one invalid character" : "Nama berkas berisi setidaknya satu karakter yang tidak sah.",
- "File name is too long" : "Nama berkas terlalu panjang",
- "Users" : "Pengguna",
- "Open »%s«" : "Buka »%s«",
"File is currently busy, please try again later" : "Berkas sedang sibuk, mohon coba lagi nanti"
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/lib/l10n/is.js b/lib/l10n/is.js
index 536995a9e81..48c2e7cfb57 100644
--- a/lib/l10n/is.js
+++ b/lib/l10n/is.js
@@ -306,20 +306,7 @@ OC.L10N.register(
"Generate headline" : "Útbúa fyrirsögn",
"Summarizes text by reducing its length without losing key information." : "Tekur saman aðalatriði texta með því að stytta hann án þess að tapa mikilvægustu upplýsingum.",
"Extracts topics from a text and outputs them separated by commas." : "Greinir efnisflokka úr texta og aðskilur þá með kommum.",
- "Education Edition" : "Kennsluútgáfa",
- "File name is a reserved word" : "Skráarheiti er þegar frátekið orð",
- "File name contains at least one invalid character" : "Skráarheitið inniheldur að minnsta kosti einn ógildan staf",
- "File name is too long" : "Skráarheiti er of langt",
- "Users" : "Notendur",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s deildi »%2$s« með þér og vill bæta við:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s deildi »%2$s« með þér og vill bæta við",
- "»%s« added a note to a file shared with you" : "»%s« bætti minnispunkti við skrá sem deilt er með þér",
- "Open »%s«" : "Opna »%s«",
- "%1$s shared »%2$s« with you" : "%1$s deildi »%2$s« með þér",
- "%1$s shared »%2$s« with you." : "%1$s deildi »%2$s« með þér.",
- "Click the button below to open it." : "Smelltu á hnappinn hér fyrir neðan til að opna það.",
"File is currently busy, please try again later" : "Skráin er upptekin í augnablikinu, reyndu aftur síðar",
- "Cannot download file" : "Get ekki sótt skrá",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Gakktu úr skugga um að til staðar sé skrá með heitinu \".ocdata\" í rót gagnageymslunnar."
+ "Cannot download file" : "Get ekki sótt skrá"
},
"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);");
diff --git a/lib/l10n/is.json b/lib/l10n/is.json
index 99ffdef7a37..a318ed36098 100644
--- a/lib/l10n/is.json
+++ b/lib/l10n/is.json
@@ -304,20 +304,7 @@
"Generate headline" : "Útbúa fyrirsögn",
"Summarizes text by reducing its length without losing key information." : "Tekur saman aðalatriði texta með því að stytta hann án þess að tapa mikilvægustu upplýsingum.",
"Extracts topics from a text and outputs them separated by commas." : "Greinir efnisflokka úr texta og aðskilur þá með kommum.",
- "Education Edition" : "Kennsluútgáfa",
- "File name is a reserved word" : "Skráarheiti er þegar frátekið orð",
- "File name contains at least one invalid character" : "Skráarheitið inniheldur að minnsta kosti einn ógildan staf",
- "File name is too long" : "Skráarheiti er of langt",
- "Users" : "Notendur",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s deildi »%2$s« með þér og vill bæta við:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s deildi »%2$s« með þér og vill bæta við",
- "»%s« added a note to a file shared with you" : "»%s« bætti minnispunkti við skrá sem deilt er með þér",
- "Open »%s«" : "Opna »%s«",
- "%1$s shared »%2$s« with you" : "%1$s deildi »%2$s« með þér",
- "%1$s shared »%2$s« with you." : "%1$s deildi »%2$s« með þér.",
- "Click the button below to open it." : "Smelltu á hnappinn hér fyrir neðan til að opna það.",
"File is currently busy, please try again later" : "Skráin er upptekin í augnablikinu, reyndu aftur síðar",
- "Cannot download file" : "Get ekki sótt skrá",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Gakktu úr skugga um að til staðar sé skrá með heitinu \".ocdata\" í rót gagnageymslunnar."
+ "Cannot download file" : "Get ekki sótt skrá"
},"pluralForm" :"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);"
} \ No newline at end of file
diff --git a/lib/l10n/it.js b/lib/l10n/it.js
index 50750f18726..6ff6c4be9be 100644
--- a/lib/l10n/it.js
+++ b/lib/l10n/it.js
@@ -82,6 +82,8 @@ OC.L10N.register(
"Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "Il modulo con ID: %s non esiste. Abilitalo nelle impostazioni delle applicazioni o contatta il tuo amministratore.",
"File is too large to convert" : "Il file è troppo grande per essere convertito",
"Dot files are not allowed" : "I file con un punto iniziale non sono consentiti",
+ "%1$s (renamed)" : "%1$s (rinominato)",
+ "renamed file" : "file rinominato",
"File already exists" : "Il file esiste già",
"Invalid path" : "Percorso non valido",
"Failed to create file from template" : "Impossibile creare un file dal modello",
@@ -265,20 +267,7 @@ OC.L10N.register(
"Generate headline" : "Genera titolo",
"Summarizes text by reducing its length without losing key information." : "Riassume il testo riducendone la lunghezza senza perdere le informazioni chiave.",
"Extracts topics from a text and outputs them separated by commas." : "Estrae gli argomenti da un testo e li elenca separati da virgole.",
- "Education Edition" : "Edizione didattica",
- "File name is a reserved word" : "Il nome del file è una parola riservata",
- "File name contains at least one invalid character" : "Il nome del file contiene almeno un carattere non valido",
- "File name is too long" : "Il nome del file è troppo lungo",
- "Users" : "Utenti",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s ha condiviso «%2$s» con te e vuole aggiungere:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s ha condiviso «%2$s» con te e vuole aggiungere",
- "»%s« added a note to a file shared with you" : "«%s» ha aggiunto una nota a un file condiviso con te",
- "Open »%s«" : "Apri «%s»",
- "%1$s shared »%2$s« with you" : "%1$s ha condiviso «%2$s» con te",
- "%1$s shared »%2$s« with you." : "%1$s ha condiviso «%2$s» con te.",
- "Click the button below to open it." : "Fai clic sul pulsante sotto per aprirlo.",
"File is currently busy, please try again later" : "Il file è attualmente occupato, riprova più tardi",
- "Cannot download file" : "Impossibile scaricare il file",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Assicurati che ci sia un file \".ocdata\" nella radice della cartella data."
+ "Cannot download file" : "Impossibile scaricare il file"
},
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/lib/l10n/it.json b/lib/l10n/it.json
index c6a820d0f5d..bdc6eace836 100644
--- a/lib/l10n/it.json
+++ b/lib/l10n/it.json
@@ -80,6 +80,8 @@
"Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "Il modulo con ID: %s non esiste. Abilitalo nelle impostazioni delle applicazioni o contatta il tuo amministratore.",
"File is too large to convert" : "Il file è troppo grande per essere convertito",
"Dot files are not allowed" : "I file con un punto iniziale non sono consentiti",
+ "%1$s (renamed)" : "%1$s (rinominato)",
+ "renamed file" : "file rinominato",
"File already exists" : "Il file esiste già",
"Invalid path" : "Percorso non valido",
"Failed to create file from template" : "Impossibile creare un file dal modello",
@@ -263,20 +265,7 @@
"Generate headline" : "Genera titolo",
"Summarizes text by reducing its length without losing key information." : "Riassume il testo riducendone la lunghezza senza perdere le informazioni chiave.",
"Extracts topics from a text and outputs them separated by commas." : "Estrae gli argomenti da un testo e li elenca separati da virgole.",
- "Education Edition" : "Edizione didattica",
- "File name is a reserved word" : "Il nome del file è una parola riservata",
- "File name contains at least one invalid character" : "Il nome del file contiene almeno un carattere non valido",
- "File name is too long" : "Il nome del file è troppo lungo",
- "Users" : "Utenti",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s ha condiviso «%2$s» con te e vuole aggiungere:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s ha condiviso «%2$s» con te e vuole aggiungere",
- "»%s« added a note to a file shared with you" : "«%s» ha aggiunto una nota a un file condiviso con te",
- "Open »%s«" : "Apri «%s»",
- "%1$s shared »%2$s« with you" : "%1$s ha condiviso «%2$s» con te",
- "%1$s shared »%2$s« with you." : "%1$s ha condiviso «%2$s» con te.",
- "Click the button below to open it." : "Fai clic sul pulsante sotto per aprirlo.",
"File is currently busy, please try again later" : "Il file è attualmente occupato, riprova più tardi",
- "Cannot download file" : "Impossibile scaricare il file",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Assicurati che ci sia un file \".ocdata\" nella radice della cartella data."
+ "Cannot download file" : "Impossibile scaricare il file"
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
} \ No newline at end of file
diff --git a/lib/l10n/ja.js b/lib/l10n/ja.js
index c3c82dc9b17..72a4b6f133b 100644
--- a/lib/l10n/ja.js
+++ b/lib/l10n/ja.js
@@ -93,6 +93,8 @@ OC.L10N.register(
"Destination does not exist" : "宛先が存在しません",
"Destination is not creatable" : "宛先は作成できません",
"Dot files are not allowed" : "隠しファイルは許可されていません",
+ "%1$s (renamed)" : "%1$s (リネーム済み)",
+ "renamed file" : "リネーム済みファイル",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\"は禁止されているファイル名またはフォルダー名です。",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\"は、ファイル名やフォルダー名には使用できない接頭辞です。",
"\"%1$s\" is not allowed inside a file or folder name." : "\"%1$s\"はファイル名やフォルダー名の中に入れることはできません。",
@@ -273,7 +275,7 @@ OC.L10N.register(
"A valid Login must be provided" : "ログイン名を提供する必要があります",
"Login contains whitespace at the beginning or at the end" : "ログイン名の最初か最後に空白が含まれています",
"Login must not consist of dots only" : "ログイン名はドットのみで構成されてはいけません",
- "Login is too long" : "ログインが長すぎます",
+ "Username is too long" : "ユーザー名が長すぎます",
"Login is invalid because files already exist for this user" : "このユーザのファイルが既に存在するため、このログイン名は使用できません",
"Account disabled" : "アカウントは無効",
"Login canceled by app" : "アプリによりログインが中止されました",
@@ -364,6 +366,11 @@ OC.L10N.register(
"How many images to generate" : "生成する画像の数",
"Output images" : "出力画像",
"The generated images" : "生成された画像",
+ "Generate speech" : "スピーチの生成",
+ "Generate speech from a transcript" : "原稿からスピーチを生成する",
+ "Write transcript that you want the assistant to generate speech from" : "アシスタントに音声を生成させたい原稿を書きます",
+ "Output speech" : "スピーチの出力",
+ "The generated speech" : "生成されたスピーチ",
"Free text to text prompt" : "フリーテキストからテキストへのプロンプト",
"Runs an arbitrary prompt through a language model that returns a reply" : "応答を返す言語モデルを通じて任意のプロンプトを実行します",
"Describe a task that you want the assistant to do or ask a question" : "アシスタントに実行してほしいタスクまたは質問を記述します",
@@ -443,20 +450,8 @@ OC.L10N.register(
"Generate headline" : "見出しの生成",
"Summarizes text by reducing its length without losing key information." : "重要な情報を失わずにテキストの長さを要約して短縮する。",
"Extracts topics from a text and outputs them separated by commas." : "テキストからトピックを抽出し、カンマ区切りで出力します。",
- "Education Edition" : "教育向けエディション",
- "File name is a reserved word" : "ファイル名が予約された単語です",
- "File name contains at least one invalid character" : "ファイル名に1文字以上の無効な文字が含まれています",
- "File name is too long" : "ファイル名が長すぎます",
- "Users" : "ユーザー",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s さんが »%2$s« にノートを追加しました。",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s shared »%2$s« with you and wants to add",
- "»%s« added a note to a file shared with you" : "»%s« があなたと共有しているファイルにノートを追加しました。 ",
- "Open »%s«" : "»%s«を開く",
- "%1$s shared »%2$s« with you" : "%1$s は »%2$s« をあなたと共有しました",
- "%1$s shared »%2$s« with you." : "%1$sが あなたと »%2$s« を共有しました。",
- "Click the button below to open it." : "開くには下のボタンをクリック",
"File is currently busy, please try again later" : "現在ファイルはビジーです。後でもう一度試してください。",
"Cannot download file" : "ファイルをダウンロードできません",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "データディレクトリの直下に \".ocdata\" ファイルがあるのを確認してください。"
+ "Login is too long" : "ログインが長すぎます"
},
"nplurals=1; plural=0;");
diff --git a/lib/l10n/ja.json b/lib/l10n/ja.json
index cd55a7d7703..5a6af204f01 100644
--- a/lib/l10n/ja.json
+++ b/lib/l10n/ja.json
@@ -91,6 +91,8 @@
"Destination does not exist" : "宛先が存在しません",
"Destination is not creatable" : "宛先は作成できません",
"Dot files are not allowed" : "隠しファイルは許可されていません",
+ "%1$s (renamed)" : "%1$s (リネーム済み)",
+ "renamed file" : "リネーム済みファイル",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\"は禁止されているファイル名またはフォルダー名です。",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\"は、ファイル名やフォルダー名には使用できない接頭辞です。",
"\"%1$s\" is not allowed inside a file or folder name." : "\"%1$s\"はファイル名やフォルダー名の中に入れることはできません。",
@@ -271,7 +273,7 @@
"A valid Login must be provided" : "ログイン名を提供する必要があります",
"Login contains whitespace at the beginning or at the end" : "ログイン名の最初か最後に空白が含まれています",
"Login must not consist of dots only" : "ログイン名はドットのみで構成されてはいけません",
- "Login is too long" : "ログインが長すぎます",
+ "Username is too long" : "ユーザー名が長すぎます",
"Login is invalid because files already exist for this user" : "このユーザのファイルが既に存在するため、このログイン名は使用できません",
"Account disabled" : "アカウントは無効",
"Login canceled by app" : "アプリによりログインが中止されました",
@@ -362,6 +364,11 @@
"How many images to generate" : "生成する画像の数",
"Output images" : "出力画像",
"The generated images" : "生成された画像",
+ "Generate speech" : "スピーチの生成",
+ "Generate speech from a transcript" : "原稿からスピーチを生成する",
+ "Write transcript that you want the assistant to generate speech from" : "アシスタントに音声を生成させたい原稿を書きます",
+ "Output speech" : "スピーチの出力",
+ "The generated speech" : "生成されたスピーチ",
"Free text to text prompt" : "フリーテキストからテキストへのプロンプト",
"Runs an arbitrary prompt through a language model that returns a reply" : "応答を返す言語モデルを通じて任意のプロンプトを実行します",
"Describe a task that you want the assistant to do or ask a question" : "アシスタントに実行してほしいタスクまたは質問を記述します",
@@ -441,20 +448,8 @@
"Generate headline" : "見出しの生成",
"Summarizes text by reducing its length without losing key information." : "重要な情報を失わずにテキストの長さを要約して短縮する。",
"Extracts topics from a text and outputs them separated by commas." : "テキストからトピックを抽出し、カンマ区切りで出力します。",
- "Education Edition" : "教育向けエディション",
- "File name is a reserved word" : "ファイル名が予約された単語です",
- "File name contains at least one invalid character" : "ファイル名に1文字以上の無効な文字が含まれています",
- "File name is too long" : "ファイル名が長すぎます",
- "Users" : "ユーザー",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s さんが »%2$s« にノートを追加しました。",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s shared »%2$s« with you and wants to add",
- "»%s« added a note to a file shared with you" : "»%s« があなたと共有しているファイルにノートを追加しました。 ",
- "Open »%s«" : "»%s«を開く",
- "%1$s shared »%2$s« with you" : "%1$s は »%2$s« をあなたと共有しました",
- "%1$s shared »%2$s« with you." : "%1$sが あなたと »%2$s« を共有しました。",
- "Click the button below to open it." : "開くには下のボタンをクリック",
"File is currently busy, please try again later" : "現在ファイルはビジーです。後でもう一度試してください。",
"Cannot download file" : "ファイルをダウンロードできません",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "データディレクトリの直下に \".ocdata\" ファイルがあるのを確認してください。"
+ "Login is too long" : "ログインが長すぎます"
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/lib/l10n/ka.js b/lib/l10n/ka.js
index 0f32b8a5bb4..706ba8411db 100644
--- a/lib/l10n/ka.js
+++ b/lib/l10n/ka.js
@@ -239,20 +239,7 @@ OC.L10N.register(
"Generate headline" : "Generate headline",
"Summarizes text by reducing its length without losing key information." : "Summarizes text by reducing its length without losing key information.",
"Extracts topics from a text and outputs them separated by commas." : "Extracts topics from a text and outputs them separated by commas.",
- "Education Edition" : "Education Edition",
- "File name is a reserved word" : "File name is a reserved word",
- "File name contains at least one invalid character" : "File name contains at least one invalid character",
- "File name is too long" : "File name is too long",
- "Users" : "Users",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s shared »%2$s« with you and wants to add:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s shared »%2$s« with you and wants to add",
- "»%s« added a note to a file shared with you" : "»%s« added a note to a file shared with you",
- "Open »%s«" : "Open »%s«",
- "%1$s shared »%2$s« with you" : "%1$s shared »%2$s« with you",
- "%1$s shared »%2$s« with you." : "%1$s shared »%2$s« with you.",
- "Click the button below to open it." : "Click the button below to open it.",
"File is currently busy, please try again later" : "File is currently busy, please try again later",
- "Cannot download file" : "Cannot download file",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Ensure there is a file called \".ocdata\" in the root of the data directory."
+ "Cannot download file" : "Cannot download file"
},
"nplurals=2; plural=(n!=1);");
diff --git a/lib/l10n/ka.json b/lib/l10n/ka.json
index d920c2c0c6d..9ae23be8656 100644
--- a/lib/l10n/ka.json
+++ b/lib/l10n/ka.json
@@ -237,20 +237,7 @@
"Generate headline" : "Generate headline",
"Summarizes text by reducing its length without losing key information." : "Summarizes text by reducing its length without losing key information.",
"Extracts topics from a text and outputs them separated by commas." : "Extracts topics from a text and outputs them separated by commas.",
- "Education Edition" : "Education Edition",
- "File name is a reserved word" : "File name is a reserved word",
- "File name contains at least one invalid character" : "File name contains at least one invalid character",
- "File name is too long" : "File name is too long",
- "Users" : "Users",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s shared »%2$s« with you and wants to add:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s shared »%2$s« with you and wants to add",
- "»%s« added a note to a file shared with you" : "»%s« added a note to a file shared with you",
- "Open »%s«" : "Open »%s«",
- "%1$s shared »%2$s« with you" : "%1$s shared »%2$s« with you",
- "%1$s shared »%2$s« with you." : "%1$s shared »%2$s« with you.",
- "Click the button below to open it." : "Click the button below to open it.",
"File is currently busy, please try again later" : "File is currently busy, please try again later",
- "Cannot download file" : "Cannot download file",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Ensure there is a file called \".ocdata\" in the root of the data directory."
+ "Cannot download file" : "Cannot download file"
},"pluralForm" :"nplurals=2; plural=(n!=1);"
} \ No newline at end of file
diff --git a/lib/l10n/ka_GE.js b/lib/l10n/ka_GE.js
index a1fd14cf23b..897e4947af7 100644
--- a/lib/l10n/ka_GE.js
+++ b/lib/l10n/ka_GE.js
@@ -149,14 +149,6 @@ OC.L10N.register(
"Summary" : "შეჯამება",
"Translate" : "გადათარგმნეთ",
"Result" : "შედეგი",
- "Education Edition" : "საგანმანათლებლო გამოცემა",
- "File name is a reserved word" : "ფაილის სახელი რეზერვირებული სიტყვაა",
- "File name contains at least one invalid character" : "ფაილის სახელი მოიცავს დაუშვებელ სიმბოლოს",
- "File name is too long" : "ფაილის სახელი ზედმეტად გრძელია",
- "Users" : "მომხმარებლები",
- "Open »%s«" : "გახნსნა »%s«",
- "Click the button below to open it." : "გასახსნელად დააჭირეთ ქვემოთ მყოფ ღილაკს.",
- "File is currently busy, please try again later" : "ფაილი ამჟამად დაკავებულია, გთხოვთ მოგვიანებით სცადოთ ახლიდან",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "დარწმუნდით რომ ფაილი სახელად \".ocdata\" მონაცემების დირექტორიის საწყისშია."
+ "File is currently busy, please try again later" : "ფაილი ამჟამად დაკავებულია, გთხოვთ მოგვიანებით სცადოთ ახლიდან"
},
"nplurals=2; plural=(n!=1);");
diff --git a/lib/l10n/ka_GE.json b/lib/l10n/ka_GE.json
index 13f6999c143..f4ef8658ab4 100644
--- a/lib/l10n/ka_GE.json
+++ b/lib/l10n/ka_GE.json
@@ -147,14 +147,6 @@
"Summary" : "შეჯამება",
"Translate" : "გადათარგმნეთ",
"Result" : "შედეგი",
- "Education Edition" : "საგანმანათლებლო გამოცემა",
- "File name is a reserved word" : "ფაილის სახელი რეზერვირებული სიტყვაა",
- "File name contains at least one invalid character" : "ფაილის სახელი მოიცავს დაუშვებელ სიმბოლოს",
- "File name is too long" : "ფაილის სახელი ზედმეტად გრძელია",
- "Users" : "მომხმარებლები",
- "Open »%s«" : "გახნსნა »%s«",
- "Click the button below to open it." : "გასახსნელად დააჭირეთ ქვემოთ მყოფ ღილაკს.",
- "File is currently busy, please try again later" : "ფაილი ამჟამად დაკავებულია, გთხოვთ მოგვიანებით სცადოთ ახლიდან",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "დარწმუნდით რომ ფაილი სახელად \".ocdata\" მონაცემების დირექტორიის საწყისშია."
+ "File is currently busy, please try again later" : "ფაილი ამჟამად დაკავებულია, გთხოვთ მოგვიანებით სცადოთ ახლიდან"
},"pluralForm" :"nplurals=2; plural=(n!=1);"
} \ No newline at end of file
diff --git a/lib/l10n/kab.js b/lib/l10n/kab.js
index fa7d5300223..3d3822ecfef 100644
--- a/lib/l10n/kab.js
+++ b/lib/l10n/kab.js
@@ -12,7 +12,6 @@ OC.L10N.register(
"Website" : "Asmel web",
"Address" : "Adresse",
"About" : "Γef",
- "Translate" : "Suqel",
- "Users" : "Iseqdacen"
+ "Translate" : "Suqel"
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/kab.json b/lib/l10n/kab.json
index d34c0f8ed40..f9b7184e1c4 100644
--- a/lib/l10n/kab.json
+++ b/lib/l10n/kab.json
@@ -10,7 +10,6 @@
"Website" : "Asmel web",
"Address" : "Adresse",
"About" : "Γef",
- "Translate" : "Suqel",
- "Users" : "Iseqdacen"
+ "Translate" : "Suqel"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/km.js b/lib/l10n/km.js
index 05d9e5c1ff0..5f499f816bd 100644
--- a/lib/l10n/km.js
+++ b/lib/l10n/km.js
@@ -63,7 +63,6 @@ OC.L10N.register(
"Dec." : "ធ្នូ",
"A valid password must be provided" : "ត្រូវ​ផ្ដល់​ពាក្យ​សម្ងាត់​ឲ្យ​បាន​ត្រឹម​ត្រូវ",
"Application is not enabled" : "មិន​បាន​បើក​កម្មវិធី",
- "Authentication error" : "កំហុស​ការ​ផ្ទៀង​ផ្ទាត់​ភាព​ត្រឹម​ត្រូវ",
- "Users" : "អ្នកប្រើ"
+ "Authentication error" : "កំហុស​ការ​ផ្ទៀង​ផ្ទាត់​ភាព​ត្រឹម​ត្រូវ"
},
"nplurals=1; plural=0;");
diff --git a/lib/l10n/km.json b/lib/l10n/km.json
index 0f311106bf0..209a4ab7f5f 100644
--- a/lib/l10n/km.json
+++ b/lib/l10n/km.json
@@ -61,7 +61,6 @@
"Dec." : "ធ្នូ",
"A valid password must be provided" : "ត្រូវ​ផ្ដល់​ពាក្យ​សម្ងាត់​ឲ្យ​បាន​ត្រឹម​ត្រូវ",
"Application is not enabled" : "មិន​បាន​បើក​កម្មវិធី",
- "Authentication error" : "កំហុស​ការ​ផ្ទៀង​ផ្ទាត់​ភាព​ត្រឹម​ត្រូវ",
- "Users" : "អ្នកប្រើ"
+ "Authentication error" : "កំហុស​ការ​ផ្ទៀង​ផ្ទាត់​ភាព​ត្រឹម​ត្រូវ"
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/lib/l10n/kn.js b/lib/l10n/kn.js
index f3e2c7dd050..30b6ed8db54 100644
--- a/lib/l10n/kn.js
+++ b/lib/l10n/kn.js
@@ -30,7 +30,6 @@ OC.L10N.register(
"November" : "ನವೆಂಬರ್",
"December" : "ಡಿಸೆಂಬರ್",
"A valid password must be provided" : "ಸರಿಯಾದ ಬಳಕೆದಾರ ಗುಪ್ತಪದ ಒದಗಿಸಬೇಕಾಗಿದೆ",
- "Authentication error" : "ದೃಢೀಕರಣ ದೋಷ",
- "Users" : "ಬಳಕೆದಾರರು"
+ "Authentication error" : "ದೃಢೀಕರಣ ದೋಷ"
},
"nplurals=2; plural=(n > 1);");
diff --git a/lib/l10n/kn.json b/lib/l10n/kn.json
index ef0e81d6b6f..590b685ac63 100644
--- a/lib/l10n/kn.json
+++ b/lib/l10n/kn.json
@@ -28,7 +28,6 @@
"November" : "ನವೆಂಬರ್",
"December" : "ಡಿಸೆಂಬರ್",
"A valid password must be provided" : "ಸರಿಯಾದ ಬಳಕೆದಾರ ಗುಪ್ತಪದ ಒದಗಿಸಬೇಕಾಗಿದೆ",
- "Authentication error" : "ದೃಢೀಕರಣ ದೋಷ",
- "Users" : "ಬಳಕೆದಾರರು"
+ "Authentication error" : "ದೃಢೀಕರಣ ದೋಷ"
},"pluralForm" :"nplurals=2; plural=(n > 1);"
} \ No newline at end of file
diff --git a/lib/l10n/ko.js b/lib/l10n/ko.js
index 8e7a3855568..41178d953f3 100644
--- a/lib/l10n/ko.js
+++ b/lib/l10n/ko.js
@@ -140,6 +140,7 @@ OC.L10N.register(
"The requested share comes from a disabled user" : "요청한 공유가 비활성화된 사용자로부터 수신되었습니다",
"The user was not created because the user limit has been reached. Check your notifications to learn more." : "사용자 수 제한에 도달하여 사용자를 만들 수 없습니다. 더 자세한 정보는 알림을 참조하십시오.",
"Could not find category \"%s\"" : "분류 \"%s\"을(를) 찾을 수 없습니다",
+ "Input text" : "텍스트를 입력",
"Sunday" : "일요일",
"Monday" : "월요일",
"Tuesday" : "화요일",
@@ -234,12 +235,18 @@ OC.L10N.register(
"Storage connection timeout. %s" : "저장소 연결 시간이 초과되었습니다. %s",
"Audio input" : "음성 입력",
"Confirmation" : "확인",
+ "Generated response" : "생성된 응답",
"Context write" : "컨텍스트 쓰기",
"Writes text in a given style based on the provided source material." : "제공된 소스 자료를 기반으로 특정 스타일로 텍스트를 작성합니다.",
"Writing style" : "작문 스타일",
"Source material" : "소스 자료",
"Generate image" : "이미지 생성",
"Prompt" : "프롬프트",
+ "Change Tone" : "톤을 변경",
+ "Write a text that you want the assistant to rewrite in another tone." : "어시스턴트에 다른 톤으로 다시 쓰고 싶은 텍스트를 쓰기",
+ "Desired tone" : "희망하는 톤",
+ "In which tone should your text be rewritten?" : "텍스트를 어떤 어조로 다시 씁니까?",
+ "The rewritten text in the desired tone, written by the assistant:" : "원하는 톤으로 어시스턴트에 의해서 다시 쓴 텍스트:",
"Chat" : "대화",
"Generates a possible headline for a text." : "내용에 대한 헤드라인을 생성하십시오.",
"Text" : "텍스트",
@@ -251,20 +258,7 @@ OC.L10N.register(
"Generate headline" : "헤드라인 생성",
"Summarizes text by reducing its length without losing key information." : "중요 정보로 내용을 축약하십시오.",
"Extracts topics from a text and outputs them separated by commas." : "내용에서 주요 주제를 추출하고 쉼표로 이를 구분하십시오.",
- "Education Edition" : "교육용 에디션",
- "File name is a reserved word" : "파일 이름이 예약된 단어임",
- "File name contains at least one invalid character" : "파일 이름에 잘못된 글자가 한 자 이상 있음",
- "File name is too long" : "파일 이름이 너무 김",
- "Users" : "사용자",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s님이 %2$s을(를) 당신과 공유하며, 다음을 추가하고자 함:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s님이 %2$s을(를) 당신과 공유하며 다음을 추가하고자 함",
- "»%s« added a note to a file shared with you" : "%s님이 당신과 공유한 파일에 메모를 추가함",
- "Open »%s«" : "%s 열기",
- "%1$s shared »%2$s« with you" : "%1$s 님이 »%2$s« 항목을 공유했습니다",
- "%1$s shared »%2$s« with you." : "%1$s 님이 »%2$s« 항목을 공유했습니다",
- "Click the button below to open it." : "아래 단추를 눌러서 열 수 있습니다.",
"File is currently busy, please try again later" : "파일이 현재 사용 중, 나중에 다시 시도하십시오",
- "Cannot download file" : "파일을 다운로드할 수 없음",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "데이터 디렉터리의 최상위 디렉터리에 \".ocdata\" 파일이 있는지 확인하십시오."
+ "Cannot download file" : "파일을 다운로드할 수 없음"
},
"nplurals=1; plural=0;");
diff --git a/lib/l10n/ko.json b/lib/l10n/ko.json
index 4f14221f165..409bc07408d 100644
--- a/lib/l10n/ko.json
+++ b/lib/l10n/ko.json
@@ -138,6 +138,7 @@
"The requested share comes from a disabled user" : "요청한 공유가 비활성화된 사용자로부터 수신되었습니다",
"The user was not created because the user limit has been reached. Check your notifications to learn more." : "사용자 수 제한에 도달하여 사용자를 만들 수 없습니다. 더 자세한 정보는 알림을 참조하십시오.",
"Could not find category \"%s\"" : "분류 \"%s\"을(를) 찾을 수 없습니다",
+ "Input text" : "텍스트를 입력",
"Sunday" : "일요일",
"Monday" : "월요일",
"Tuesday" : "화요일",
@@ -232,12 +233,18 @@
"Storage connection timeout. %s" : "저장소 연결 시간이 초과되었습니다. %s",
"Audio input" : "음성 입력",
"Confirmation" : "확인",
+ "Generated response" : "생성된 응답",
"Context write" : "컨텍스트 쓰기",
"Writes text in a given style based on the provided source material." : "제공된 소스 자료를 기반으로 특정 스타일로 텍스트를 작성합니다.",
"Writing style" : "작문 스타일",
"Source material" : "소스 자료",
"Generate image" : "이미지 생성",
"Prompt" : "프롬프트",
+ "Change Tone" : "톤을 변경",
+ "Write a text that you want the assistant to rewrite in another tone." : "어시스턴트에 다른 톤으로 다시 쓰고 싶은 텍스트를 쓰기",
+ "Desired tone" : "희망하는 톤",
+ "In which tone should your text be rewritten?" : "텍스트를 어떤 어조로 다시 씁니까?",
+ "The rewritten text in the desired tone, written by the assistant:" : "원하는 톤으로 어시스턴트에 의해서 다시 쓴 텍스트:",
"Chat" : "대화",
"Generates a possible headline for a text." : "내용에 대한 헤드라인을 생성하십시오.",
"Text" : "텍스트",
@@ -249,20 +256,7 @@
"Generate headline" : "헤드라인 생성",
"Summarizes text by reducing its length without losing key information." : "중요 정보로 내용을 축약하십시오.",
"Extracts topics from a text and outputs them separated by commas." : "내용에서 주요 주제를 추출하고 쉼표로 이를 구분하십시오.",
- "Education Edition" : "교육용 에디션",
- "File name is a reserved word" : "파일 이름이 예약된 단어임",
- "File name contains at least one invalid character" : "파일 이름에 잘못된 글자가 한 자 이상 있음",
- "File name is too long" : "파일 이름이 너무 김",
- "Users" : "사용자",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s님이 %2$s을(를) 당신과 공유하며, 다음을 추가하고자 함:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s님이 %2$s을(를) 당신과 공유하며 다음을 추가하고자 함",
- "»%s« added a note to a file shared with you" : "%s님이 당신과 공유한 파일에 메모를 추가함",
- "Open »%s«" : "%s 열기",
- "%1$s shared »%2$s« with you" : "%1$s 님이 »%2$s« 항목을 공유했습니다",
- "%1$s shared »%2$s« with you." : "%1$s 님이 »%2$s« 항목을 공유했습니다",
- "Click the button below to open it." : "아래 단추를 눌러서 열 수 있습니다.",
"File is currently busy, please try again later" : "파일이 현재 사용 중, 나중에 다시 시도하십시오",
- "Cannot download file" : "파일을 다운로드할 수 없음",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "데이터 디렉터리의 최상위 디렉터리에 \".ocdata\" 파일이 있는지 확인하십시오."
+ "Cannot download file" : "파일을 다운로드할 수 없음"
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/lib/l10n/lb.js b/lib/l10n/lb.js
index a036aa4e6a4..95e013a5895 100644
--- a/lib/l10n/lb.js
+++ b/lib/l10n/lb.js
@@ -67,7 +67,6 @@ OC.L10N.register(
"Dec." : "Dez.",
"Authentication error" : "Authentifikatioun's Fehler",
"Storage is temporarily not available" : "Späicherplaatz temporär net erreeschbar",
- "Translate" : "Iwwersetzen",
- "Users" : "Benotzer"
+ "Translate" : "Iwwersetzen"
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/lb.json b/lib/l10n/lb.json
index 054c6337f7a..6670b881769 100644
--- a/lib/l10n/lb.json
+++ b/lib/l10n/lb.json
@@ -65,7 +65,6 @@
"Dec." : "Dez.",
"Authentication error" : "Authentifikatioun's Fehler",
"Storage is temporarily not available" : "Späicherplaatz temporär net erreeschbar",
- "Translate" : "Iwwersetzen",
- "Users" : "Benotzer"
+ "Translate" : "Iwwersetzen"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/lo.js b/lib/l10n/lo.js
index be20249c046..cdb86b0dd40 100644
--- a/lib/l10n/lo.js
+++ b/lib/l10n/lo.js
@@ -17,7 +17,6 @@ OC.L10N.register(
"Address" : "ທີ່ຢູ່",
"About" : "ກ່ຽວກັບ",
"Role" : "ພາລະບົດບາດ",
- "Translate" : "ແປ",
- "Users" : "ຜູ້ໃຊ້"
+ "Translate" : "ແປ"
},
"nplurals=1; plural=0;");
diff --git a/lib/l10n/lo.json b/lib/l10n/lo.json
index 575a364c6f3..443e99a5ed1 100644
--- a/lib/l10n/lo.json
+++ b/lib/l10n/lo.json
@@ -15,7 +15,6 @@
"Address" : "ທີ່ຢູ່",
"About" : "ກ່ຽວກັບ",
"Role" : "ພາລະບົດບາດ",
- "Translate" : "ແປ",
- "Users" : "ຜູ້ໃຊ້"
+ "Translate" : "ແປ"
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/lib/l10n/lt_LT.js b/lib/l10n/lt_LT.js
index b8a9d9440cb..8f4044127d9 100644
--- a/lib/l10n/lt_LT.js
+++ b/lib/l10n/lt_LT.js
@@ -183,19 +183,7 @@ OC.L10N.register(
"Text" : "Tekstas",
"Summary" : "Santrauka",
"Translate" : "Verskite",
- "File name is a reserved word" : "Failo pavadinimas negalimas, žodis rezervuotas",
- "File name contains at least one invalid character" : "Failo vardas sudarytas iš neleistinų simbolių",
- "File name is too long" : "Failo pavadinimas per ilgas",
- "Users" : "Naudotojai",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s pasidalino „%2$s“ su jumis ir parašė pastabą:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s pasidalino „%2$s“ su jumis ir parašė pastabą",
- "»%s« added a note to a file shared with you" : "„%s“ parašė pastabą su jumis pasidalintam failui",
- "Open »%s«" : "Atverti \"%s\"",
- "%1$s shared »%2$s« with you" : "%1$s pasidalino „%2$s“ su jumis",
- "%1$s shared »%2$s« with you." : "%1$s pasidalino „%2$s“ su jumis.",
- "Click the button below to open it." : "Norėdami atverti failą, spustelėkite mygtuką žemiau.",
"File is currently busy, please try again later" : "Failas šiuo metu yra užimtas, prašome vėliau pabandyti dar kartą",
- "Cannot download file" : "Nepavyksta atsisiųsti failo",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Įsitikinkite, kad šakniniame duomenų kataloge yra failas, pavadinimu „.ocdata“."
+ "Cannot download file" : "Nepavyksta atsisiųsti failo"
},
"nplurals=4; plural=(n % 10 == 1 && (n % 100 > 19 || n % 100 < 11) ? 0 : (n % 10 >= 2 && n % 10 <=9) && (n % 100 > 19 || n % 100 < 11) ? 1 : n % 1 != 0 ? 2: 3);");
diff --git a/lib/l10n/lt_LT.json b/lib/l10n/lt_LT.json
index 21d9d6c9699..d7ab36c7f46 100644
--- a/lib/l10n/lt_LT.json
+++ b/lib/l10n/lt_LT.json
@@ -181,19 +181,7 @@
"Text" : "Tekstas",
"Summary" : "Santrauka",
"Translate" : "Verskite",
- "File name is a reserved word" : "Failo pavadinimas negalimas, žodis rezervuotas",
- "File name contains at least one invalid character" : "Failo vardas sudarytas iš neleistinų simbolių",
- "File name is too long" : "Failo pavadinimas per ilgas",
- "Users" : "Naudotojai",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s pasidalino „%2$s“ su jumis ir parašė pastabą:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s pasidalino „%2$s“ su jumis ir parašė pastabą",
- "»%s« added a note to a file shared with you" : "„%s“ parašė pastabą su jumis pasidalintam failui",
- "Open »%s«" : "Atverti \"%s\"",
- "%1$s shared »%2$s« with you" : "%1$s pasidalino „%2$s“ su jumis",
- "%1$s shared »%2$s« with you." : "%1$s pasidalino „%2$s“ su jumis.",
- "Click the button below to open it." : "Norėdami atverti failą, spustelėkite mygtuką žemiau.",
"File is currently busy, please try again later" : "Failas šiuo metu yra užimtas, prašome vėliau pabandyti dar kartą",
- "Cannot download file" : "Nepavyksta atsisiųsti failo",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Įsitikinkite, kad šakniniame duomenų kataloge yra failas, pavadinimu „.ocdata“."
+ "Cannot download file" : "Nepavyksta atsisiųsti failo"
},"pluralForm" :"nplurals=4; plural=(n % 10 == 1 && (n % 100 > 19 || n % 100 < 11) ? 0 : (n % 10 >= 2 && n % 10 <=9) && (n % 100 > 19 || n % 100 < 11) ? 1 : n % 1 != 0 ? 2: 3);"
} \ No newline at end of file
diff --git a/lib/l10n/lv.js b/lib/l10n/lv.js
index a201c8c6081..d70b713b15f 100644
--- a/lib/l10n/lv.js
+++ b/lib/l10n/lv.js
@@ -5,7 +5,7 @@ OC.L10N.register(
"See %s" : "Skatīt %s",
"Application %1$s is not present or has a non-compatible version with this server. Please check the apps directory." : "Lietotne %1$s nav pieejama vai tai ir ar šo serveri nesaderīga versija. Lūgums pārbaudīt lietotņu mapi.",
"Sample configuration detected" : "Atrasta konfigurācijas paraugs",
- "It has been detected that the sample configuration has been copied. This can break your installation and is unsupported. Please read the documentation before performing changes on config.php" : "Konstatēts, ka paraug konfigurācija ir nokopēta. Tas var izjaukt jūsu instalāciju un nav atbalstīts. Lūdzu, izlasiet dokumentāciju, pirms veicat izmaiņas config.php",
+ "It has been detected that the sample configuration has been copied. This can break your installation and is unsupported. Please read the documentation before performing changes on config.php" : "Tika noteikts, ka tika kopēta paraugkonfigurācija. Tas var salauzt uzstādīto un netiek atbalstīts. Lūgums pirms izmaiņu veikšanas config.php izlasīt dokumentāciju",
"%s email verification" : "%s e-pasta pārbaude",
"Email verification" : "E-pasta pārbaude",
"Click the following button to confirm your email." : "Jāklikšķina zemā esošā poga, lai apstiprinātu savu e-pasta adresi.",
@@ -26,19 +26,22 @@ OC.L10N.register(
"Authentication" : "Autentifikācija",
"Unknown filetype" : "Nezināms datnes veids",
"Invalid image" : "Nederīgs attēls",
- "Avatar image is not square" : "Avatar attēls nav kvadrāts",
+ "Avatar image is not square" : "Profila attēls nav kvadrāts",
"Files" : "Datnes",
"View profile" : "Skatīt profilu",
"today" : "šodien",
"yesterday" : "vakar",
- "_%n day ago_::_%n days ago_" : ["%n dienas atpakaļ","%n dienas atpakaļ","%n dienām"],
+ "_%n day ago_::_%n days ago_" : ["pirms %n dienām","pirms %n dienas","pirms %n dienām"],
"last month" : "pagājušajā mēnesī",
- "_%n month ago_::_%n months ago_" : ["%n mēneši atpakaļ","%n mēneši atpakaļ","%n mēnešiem"],
+ "_%n month ago_::_%n months ago_" : ["pirms %n mēnešiem","pirms %n mēneša","pirms %n mēnešiem"],
"last year" : "gājušajā gadā",
- "_%n year ago_::_%n years ago_" : ["%n gadiem","%n gadiem","%n gadiem"],
- "_%n hour ago_::_%n hours ago_" : ["%n stundas atpakaļ","%n stundas atpakaļ","%n stundām"],
- "_%n minute ago_::_%n minutes ago_" : ["%n minūtes atpakaļ","%n minūtes atpakaļ","%n minūtēm"],
- "seconds ago" : "sekundēm",
+ "_%n year ago_::_%n years ago_" : ["pirms %n gadiem","pirms %n gada","pirms %n gadiem"],
+ "_%n hour ago_::_%n hours ago_" : ["pirms %n stundām","pirms %n stundas","pirms %n stundām"],
+ "_%n minute ago_::_%n minutes ago_" : ["pirms %n minūtēm","pirms %n minūtes","pirms %n minūtēm"],
+ "seconds ago" : "pirms vairākām sekundēm",
+ "Empty file" : "Tukša datne",
+ "%1$s (renamed)" : "%1$s (pārdēvēta)",
+ "renamed file" : "pārdēvēja datni",
"File already exists" : "Datne jau pastāv",
"Filename contains at least one invalid character" : "Datnes nosaukums satur vismaz vienu nederīgu rakstzīmi",
"Empty filename is not allowed" : "Tukšs datnes nosaukums nav atļauts",
@@ -67,7 +70,7 @@ OC.L10N.register(
"Set an admin password." : "Iestatīt pārvaldītāja paroli.",
"Open %s" : "Atvērt %s",
"Unknown share type" : "Nezināms kopīgošanas veids",
- "You are not allowed to share %s" : "Tev nav ļauts dalīties ar %s",
+ "You are not allowed to share %s" : "Tev nav ļauts kopīgot %s",
"Could not find category \"%s\"" : "Nevarēja atrast kategoriju “%s”",
"Sunday" : "Svētdiena",
"Monday" : "Pirmdiena",
@@ -115,12 +118,12 @@ OC.L10N.register(
"Nov." : "Nov.",
"Dec." : "Dec.",
"A valid password must be provided" : "Jānorāda derīga parole",
- "Login canceled by app" : "Pieteikšanos atcelā lietotne",
+ "Login canceled by app" : "Lietotne atcēla pieteikšanos",
"a safe home for all your data" : "droša vieta visiem Taviem datiem",
"Application is not enabled" : "Lietotne nav iespējota",
"Authentication error" : "Autentificēšanās kļūda",
"Token expired. Please reload page." : "Pilnvarai ir beidzies derīgums. Lūgums pārlādēt lapu.",
- "PHP module %s not installed." : "PHP modulis %s nav instalēts.",
+ "PHP module %s not installed." : "Nav uzstādīts PHP modulis %s.",
"Please ask your server administrator to install the module." : "Lūgums vaicāt savam servera pārvaldītāja, lai uzstāda moduli.",
"This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "Tas ir iespējams, kešatmiņa / paātrinātājs, piemēram, Zend OPcache vai eAccelerator.",
"PHP modules have been installed, but they are still listed as missing?" : "PHP modulis ir uzstādīts, taču tas joprojām ir uzskatāms kā trūkstošs, pazudis?",
@@ -128,15 +131,11 @@ OC.L10N.register(
"Storage unauthorized. %s" : "Krātuve neautorizēta. %s",
"Storage incomplete configuration. %s" : "Storage incomplete configuration. %s",
"Storage connection error. %s" : "Datu savienojuma kļūda. %s",
- "Storage is temporarily not available" : "Glabātuve īslaicīgi nav pieejama",
+ "Storage is temporarily not available" : "Krātuve īslaicīgi nav pieejama",
"Storage connection timeout. %s" : "Datu savienojuma taimauts. %s",
"Text" : "Teksts",
"Summary" : "Kopsavilkums",
"Translate" : "Tulkot",
- "File name is a reserved word" : "Datnes nosaukums ir aizņemts vārds",
- "File name is too long" : "Datnes nosaukums ir pārāk garš",
- "Users" : "Lietotāji",
- "Open »%s«" : "Atvērt »%s«",
"File is currently busy, please try again later" : "Datne pašlaik ir aizņemta. Lūgums vēlāk mēģināt vēlreiz"
},
"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);");
diff --git a/lib/l10n/lv.json b/lib/l10n/lv.json
index 6ae08bbf873..985ca12e30a 100644
--- a/lib/l10n/lv.json
+++ b/lib/l10n/lv.json
@@ -3,7 +3,7 @@
"See %s" : "Skatīt %s",
"Application %1$s is not present or has a non-compatible version with this server. Please check the apps directory." : "Lietotne %1$s nav pieejama vai tai ir ar šo serveri nesaderīga versija. Lūgums pārbaudīt lietotņu mapi.",
"Sample configuration detected" : "Atrasta konfigurācijas paraugs",
- "It has been detected that the sample configuration has been copied. This can break your installation and is unsupported. Please read the documentation before performing changes on config.php" : "Konstatēts, ka paraug konfigurācija ir nokopēta. Tas var izjaukt jūsu instalāciju un nav atbalstīts. Lūdzu, izlasiet dokumentāciju, pirms veicat izmaiņas config.php",
+ "It has been detected that the sample configuration has been copied. This can break your installation and is unsupported. Please read the documentation before performing changes on config.php" : "Tika noteikts, ka tika kopēta paraugkonfigurācija. Tas var salauzt uzstādīto un netiek atbalstīts. Lūgums pirms izmaiņu veikšanas config.php izlasīt dokumentāciju",
"%s email verification" : "%s e-pasta pārbaude",
"Email verification" : "E-pasta pārbaude",
"Click the following button to confirm your email." : "Jāklikšķina zemā esošā poga, lai apstiprinātu savu e-pasta adresi.",
@@ -24,19 +24,22 @@
"Authentication" : "Autentifikācija",
"Unknown filetype" : "Nezināms datnes veids",
"Invalid image" : "Nederīgs attēls",
- "Avatar image is not square" : "Avatar attēls nav kvadrāts",
+ "Avatar image is not square" : "Profila attēls nav kvadrāts",
"Files" : "Datnes",
"View profile" : "Skatīt profilu",
"today" : "šodien",
"yesterday" : "vakar",
- "_%n day ago_::_%n days ago_" : ["%n dienas atpakaļ","%n dienas atpakaļ","%n dienām"],
+ "_%n day ago_::_%n days ago_" : ["pirms %n dienām","pirms %n dienas","pirms %n dienām"],
"last month" : "pagājušajā mēnesī",
- "_%n month ago_::_%n months ago_" : ["%n mēneši atpakaļ","%n mēneši atpakaļ","%n mēnešiem"],
+ "_%n month ago_::_%n months ago_" : ["pirms %n mēnešiem","pirms %n mēneša","pirms %n mēnešiem"],
"last year" : "gājušajā gadā",
- "_%n year ago_::_%n years ago_" : ["%n gadiem","%n gadiem","%n gadiem"],
- "_%n hour ago_::_%n hours ago_" : ["%n stundas atpakaļ","%n stundas atpakaļ","%n stundām"],
- "_%n minute ago_::_%n minutes ago_" : ["%n minūtes atpakaļ","%n minūtes atpakaļ","%n minūtēm"],
- "seconds ago" : "sekundēm",
+ "_%n year ago_::_%n years ago_" : ["pirms %n gadiem","pirms %n gada","pirms %n gadiem"],
+ "_%n hour ago_::_%n hours ago_" : ["pirms %n stundām","pirms %n stundas","pirms %n stundām"],
+ "_%n minute ago_::_%n minutes ago_" : ["pirms %n minūtēm","pirms %n minūtes","pirms %n minūtēm"],
+ "seconds ago" : "pirms vairākām sekundēm",
+ "Empty file" : "Tukša datne",
+ "%1$s (renamed)" : "%1$s (pārdēvēta)",
+ "renamed file" : "pārdēvēja datni",
"File already exists" : "Datne jau pastāv",
"Filename contains at least one invalid character" : "Datnes nosaukums satur vismaz vienu nederīgu rakstzīmi",
"Empty filename is not allowed" : "Tukšs datnes nosaukums nav atļauts",
@@ -65,7 +68,7 @@
"Set an admin password." : "Iestatīt pārvaldītāja paroli.",
"Open %s" : "Atvērt %s",
"Unknown share type" : "Nezināms kopīgošanas veids",
- "You are not allowed to share %s" : "Tev nav ļauts dalīties ar %s",
+ "You are not allowed to share %s" : "Tev nav ļauts kopīgot %s",
"Could not find category \"%s\"" : "Nevarēja atrast kategoriju “%s”",
"Sunday" : "Svētdiena",
"Monday" : "Pirmdiena",
@@ -113,12 +116,12 @@
"Nov." : "Nov.",
"Dec." : "Dec.",
"A valid password must be provided" : "Jānorāda derīga parole",
- "Login canceled by app" : "Pieteikšanos atcelā lietotne",
+ "Login canceled by app" : "Lietotne atcēla pieteikšanos",
"a safe home for all your data" : "droša vieta visiem Taviem datiem",
"Application is not enabled" : "Lietotne nav iespējota",
"Authentication error" : "Autentificēšanās kļūda",
"Token expired. Please reload page." : "Pilnvarai ir beidzies derīgums. Lūgums pārlādēt lapu.",
- "PHP module %s not installed." : "PHP modulis %s nav instalēts.",
+ "PHP module %s not installed." : "Nav uzstādīts PHP modulis %s.",
"Please ask your server administrator to install the module." : "Lūgums vaicāt savam servera pārvaldītāja, lai uzstāda moduli.",
"This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "Tas ir iespējams, kešatmiņa / paātrinātājs, piemēram, Zend OPcache vai eAccelerator.",
"PHP modules have been installed, but they are still listed as missing?" : "PHP modulis ir uzstādīts, taču tas joprojām ir uzskatāms kā trūkstošs, pazudis?",
@@ -126,15 +129,11 @@
"Storage unauthorized. %s" : "Krātuve neautorizēta. %s",
"Storage incomplete configuration. %s" : "Storage incomplete configuration. %s",
"Storage connection error. %s" : "Datu savienojuma kļūda. %s",
- "Storage is temporarily not available" : "Glabātuve īslaicīgi nav pieejama",
+ "Storage is temporarily not available" : "Krātuve īslaicīgi nav pieejama",
"Storage connection timeout. %s" : "Datu savienojuma taimauts. %s",
"Text" : "Teksts",
"Summary" : "Kopsavilkums",
"Translate" : "Tulkot",
- "File name is a reserved word" : "Datnes nosaukums ir aizņemts vārds",
- "File name is too long" : "Datnes nosaukums ir pārāk garš",
- "Users" : "Lietotāji",
- "Open »%s«" : "Atvērt »%s«",
"File is currently busy, please try again later" : "Datne pašlaik ir aizņemta. Lūgums vēlāk mēģināt vēlreiz"
},"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);"
} \ No newline at end of file
diff --git a/lib/l10n/mk.js b/lib/l10n/mk.js
index 360efcb0867..01c7c4a17f8 100644
--- a/lib/l10n/mk.js
+++ b/lib/l10n/mk.js
@@ -52,6 +52,8 @@ OC.L10N.register(
"Avatar image is not square" : "Сликата за Аватар не е квадратна",
"Files" : "Датотеки",
"View profile" : "Прегледај профил",
+ "_%nh_::_%nh_" : ["%nч","%nч"],
+ "_%nm_::_%nm_" : ["%nм","%nм"],
"Local time: %s" : "Локално време: %s",
"today" : "денес",
"tomorrow" : "утре",
@@ -122,6 +124,8 @@ OC.L10N.register(
"Sharing backend %s must implement the interface OCP\\Share_Backend" : "За позадинското споделување %s мора се имплементира интерфејсот OCP\\Share_Backend",
"Sharing backend %s not found" : "Не е пронајдено позадинско споделување %s",
"Sharing backend for %s not found" : "Не е пронајдено позадинско споделување за %s.",
+ "%1$s shared %2$s with you" : "%1$s сподели %2$s со вас",
+ "Open %s" : "Отвори %s",
"%1$s via %2$s" : "%1$s преку %2$s",
"Unknown share type" : "Непознат вид на споделување",
"You are not allowed to share %s" : "Не сте овластени да ја споделите %s",
@@ -228,20 +232,7 @@ OC.L10N.register(
"Summary" : "Резиме",
"Translate" : "Преведи",
"Generate headline" : "Генерирај заглавие",
- "Education Edition" : "Едукативно издание",
- "File name is a reserved word" : "Името на датотеката е резервиран збор",
- "File name contains at least one invalid character" : "Името на датотеката соджи невалиден карактер",
- "File name is too long" : "Името на датотеката е премногу долго",
- "Users" : "Корисници",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s ја сподели папката »%2$s« и додаде:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s ја сподели папката »%2$s« и додаде",
- "»%s« added a note to a file shared with you" : "»%s« додаде белешка до датотеката што ја сподели со вас",
- "Open »%s«" : "Отвори »%s«",
- "%1$s shared »%2$s« with you" : "%1$s сподели »%2$s« со вас",
- "%1$s shared »%2$s« with you." : "%1$s сподели »%2$s« со вас.",
- "Click the button below to open it." : "Кликнете на копчето подолу за да ја отворите.",
"File is currently busy, please try again later" : "Датотеката моментално е зафатена, обидете се повторно",
- "Cannot download file" : "Не може да се преземе датотеката",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Осигурете се дека има датотека наречена \".ocdata\" во главната папка со податоци."
+ "Cannot download file" : "Не може да се преземе датотеката"
},
"nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;");
diff --git a/lib/l10n/mk.json b/lib/l10n/mk.json
index d4fbd122d20..c83132cc235 100644
--- a/lib/l10n/mk.json
+++ b/lib/l10n/mk.json
@@ -50,6 +50,8 @@
"Avatar image is not square" : "Сликата за Аватар не е квадратна",
"Files" : "Датотеки",
"View profile" : "Прегледај профил",
+ "_%nh_::_%nh_" : ["%nч","%nч"],
+ "_%nm_::_%nm_" : ["%nм","%nм"],
"Local time: %s" : "Локално време: %s",
"today" : "денес",
"tomorrow" : "утре",
@@ -120,6 +122,8 @@
"Sharing backend %s must implement the interface OCP\\Share_Backend" : "За позадинското споделување %s мора се имплементира интерфејсот OCP\\Share_Backend",
"Sharing backend %s not found" : "Не е пронајдено позадинско споделување %s",
"Sharing backend for %s not found" : "Не е пронајдено позадинско споделување за %s.",
+ "%1$s shared %2$s with you" : "%1$s сподели %2$s со вас",
+ "Open %s" : "Отвори %s",
"%1$s via %2$s" : "%1$s преку %2$s",
"Unknown share type" : "Непознат вид на споделување",
"You are not allowed to share %s" : "Не сте овластени да ја споделите %s",
@@ -226,20 +230,7 @@
"Summary" : "Резиме",
"Translate" : "Преведи",
"Generate headline" : "Генерирај заглавие",
- "Education Edition" : "Едукативно издание",
- "File name is a reserved word" : "Името на датотеката е резервиран збор",
- "File name contains at least one invalid character" : "Името на датотеката соджи невалиден карактер",
- "File name is too long" : "Името на датотеката е премногу долго",
- "Users" : "Корисници",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s ја сподели папката »%2$s« и додаде:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s ја сподели папката »%2$s« и додаде",
- "»%s« added a note to a file shared with you" : "»%s« додаде белешка до датотеката што ја сподели со вас",
- "Open »%s«" : "Отвори »%s«",
- "%1$s shared »%2$s« with you" : "%1$s сподели »%2$s« со вас",
- "%1$s shared »%2$s« with you." : "%1$s сподели »%2$s« со вас.",
- "Click the button below to open it." : "Кликнете на копчето подолу за да ја отворите.",
"File is currently busy, please try again later" : "Датотеката моментално е зафатена, обидете се повторно",
- "Cannot download file" : "Не може да се преземе датотеката",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Осигурете се дека има датотека наречена \".ocdata\" во главната папка со податоци."
+ "Cannot download file" : "Не може да се преземе датотеката"
},"pluralForm" :"nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;"
} \ No newline at end of file
diff --git a/lib/l10n/mn.js b/lib/l10n/mn.js
index 1ccd1474f1d..29ae48cf228 100644
--- a/lib/l10n/mn.js
+++ b/lib/l10n/mn.js
@@ -36,11 +36,6 @@ OC.L10N.register(
"Authentication error" : "Нотолгооны алдаа",
"Storage is temporarily not available" : "Хадгалах төхөөрөмж нь түр хугацаанд ашиглах боломжгүй байна",
"Summary" : "Хураангуй",
- "Translate" : "Орчуулга",
- "File name is a reserved word" : "Файлын нэр нь нийцгүй үг",
- "File name contains at least one invalid character" : "файлын нэр нь хамгийн багадаа нэг нь хүчингүй тэмдэгт агуулж байна",
- "File name is too long" : "Файлын нэр хэтэрхий урт байна",
- "Users" : "хэрэглэгч",
- "Open »%s«" : "»%s« нээх"
+ "Translate" : "Орчуулга"
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/mn.json b/lib/l10n/mn.json
index 39d71d8d439..e47604ac8e8 100644
--- a/lib/l10n/mn.json
+++ b/lib/l10n/mn.json
@@ -34,11 +34,6 @@
"Authentication error" : "Нотолгооны алдаа",
"Storage is temporarily not available" : "Хадгалах төхөөрөмж нь түр хугацаанд ашиглах боломжгүй байна",
"Summary" : "Хураангуй",
- "Translate" : "Орчуулга",
- "File name is a reserved word" : "Файлын нэр нь нийцгүй үг",
- "File name contains at least one invalid character" : "файлын нэр нь хамгийн багадаа нэг нь хүчингүй тэмдэгт агуулж байна",
- "File name is too long" : "Файлын нэр хэтэрхий урт байна",
- "Users" : "хэрэглэгч",
- "Open »%s«" : "»%s« нээх"
+ "Translate" : "Орчуулга"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/ms_MY.js b/lib/l10n/ms_MY.js
index 35f8508eee0..a62db456f42 100644
--- a/lib/l10n/ms_MY.js
+++ b/lib/l10n/ms_MY.js
@@ -49,8 +49,6 @@ OC.L10N.register(
"Oct." : "Okt.",
"Nov." : "Nov.",
"Dec." : "Dis.",
- "Authentication error" : "Ralat pengesahan",
- "Users" : "Pengguna",
- "Open »%s«" : "Buka %s"
+ "Authentication error" : "Ralat pengesahan"
},
"nplurals=1; plural=0;");
diff --git a/lib/l10n/ms_MY.json b/lib/l10n/ms_MY.json
index 2c507965ac0..cb2e2f402ce 100644
--- a/lib/l10n/ms_MY.json
+++ b/lib/l10n/ms_MY.json
@@ -47,8 +47,6 @@
"Oct." : "Okt.",
"Nov." : "Nov.",
"Dec." : "Dis.",
- "Authentication error" : "Ralat pengesahan",
- "Users" : "Pengguna",
- "Open »%s«" : "Buka %s"
+ "Authentication error" : "Ralat pengesahan"
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/lib/l10n/nb.js b/lib/l10n/nb.js
index b705e6e7d82..d2f0b2729e4 100644
--- a/lib/l10n/nb.js
+++ b/lib/l10n/nb.js
@@ -368,20 +368,7 @@ OC.L10N.register(
"Generate headline" : "Generer overskrift",
"Summarizes text by reducing its length without losing key information." : "Oppsummerer tekst ved å redusere lengden uten å miste nøkkelinformasjon.",
"Extracts topics from a text and outputs them separated by commas." : "Trekker ut emner fra en tekst og sender dem ut atskilt med komma.",
- "Education Edition" : "Utdanningsversjon",
- "File name is a reserved word" : "Filnavnet er et reservert ord",
- "File name contains at least one invalid character" : "Filnavnet inneholder minst ett ulovlig tegn",
- "File name is too long" : "Filnavnet er for langt",
- "Users" : "Brukere",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s delte »%2$s« med deg og vil legge til:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s delte »%2$s« med deg og vil legge til",
- "»%s« added a note to a file shared with you" : "»%s« la til en melding til en fil delt med deg",
- "Open »%s«" : "Åpne »%s«",
- "%1$s shared »%2$s« with you" : "%1$s delte »%2$s« med deg",
- "%1$s shared »%2$s« with you." : "%1$s delte »%2$s« med deg.",
- "Click the button below to open it." : "Klikk på knappen nedenfor for å åpne den.",
"File is currently busy, please try again later" : "Filen er opptatt for øyeblikket, prøv igjen senere",
- "Cannot download file" : "Kan ikke laste ned fil",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Forsikre deg om at det finnes ei fil kalt \".ocdata\" på rota av datamappa."
+ "Cannot download file" : "Kan ikke laste ned fil"
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/nb.json b/lib/l10n/nb.json
index d91ca6f542b..22a46d78df6 100644
--- a/lib/l10n/nb.json
+++ b/lib/l10n/nb.json
@@ -366,20 +366,7 @@
"Generate headline" : "Generer overskrift",
"Summarizes text by reducing its length without losing key information." : "Oppsummerer tekst ved å redusere lengden uten å miste nøkkelinformasjon.",
"Extracts topics from a text and outputs them separated by commas." : "Trekker ut emner fra en tekst og sender dem ut atskilt med komma.",
- "Education Edition" : "Utdanningsversjon",
- "File name is a reserved word" : "Filnavnet er et reservert ord",
- "File name contains at least one invalid character" : "Filnavnet inneholder minst ett ulovlig tegn",
- "File name is too long" : "Filnavnet er for langt",
- "Users" : "Brukere",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s delte »%2$s« med deg og vil legge til:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s delte »%2$s« med deg og vil legge til",
- "»%s« added a note to a file shared with you" : "»%s« la til en melding til en fil delt med deg",
- "Open »%s«" : "Åpne »%s«",
- "%1$s shared »%2$s« with you" : "%1$s delte »%2$s« med deg",
- "%1$s shared »%2$s« with you." : "%1$s delte »%2$s« med deg.",
- "Click the button below to open it." : "Klikk på knappen nedenfor for å åpne den.",
"File is currently busy, please try again later" : "Filen er opptatt for øyeblikket, prøv igjen senere",
- "Cannot download file" : "Kan ikke laste ned fil",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Forsikre deg om at det finnes ei fil kalt \".ocdata\" på rota av datamappa."
+ "Cannot download file" : "Kan ikke laste ned fil"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/nl.js b/lib/l10n/nl.js
index eafb59c4a9c..66af2d8ba2b 100644
--- a/lib/l10n/nl.js
+++ b/lib/l10n/nl.js
@@ -53,6 +53,7 @@ OC.L10N.register(
"Files" : "Bestanden",
"View profile" : "Bekijk profiel",
"_%nh_::_%nh_" : ["%nh","%nh"],
+ "Local time: %s" : "Lokale tijd: %s",
"today" : "vandaag",
"tomorrow" : "morgen",
"yesterday" : "gisteren",
@@ -75,6 +76,8 @@ OC.L10N.register(
"Empty file" : "Leeg bestand",
"Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "Module met ID: %s bestaat niet. Schakel die in binnen de app-instellingen of neem contact op met je beheerder.",
"Dot files are not allowed" : "Punt-bestanden zijn niet toegestaan",
+ "%1$s (renamed)" : "%1$s (hernoemd)",
+ "renamed file" : "bestand hernoemd",
"File already exists" : "Bestand bestaat al",
"Invalid path" : "Ongeldig pad",
"Failed to create file from template" : "Kon geen bestand van het sjabloon maken",
@@ -103,6 +106,7 @@ OC.L10N.register(
"Address" : "Adres",
"Profile picture" : "Profielafbeelding",
"About" : "Over",
+ "Display name" : "Weergave naam",
"Headline" : "Hoofdlijn",
"Organisation" : "Organisatie",
"Role" : "Rol",
@@ -117,7 +121,12 @@ OC.L10N.register(
"Sharing backend %s must implement the interface OCP\\Share_Backend" : "De gedeelde achtergrond %s moet de OCP\\Share_Backend interface implementeren",
"Sharing backend %s not found" : "De gedeelde backend %s is niet gevonden",
"Sharing backend for %s not found" : "De gedeelde backend voor %s is niet gevonden",
+ "%1$s shared %2$s with you" : "%1$s deelde %2$s met jou",
+ "Open %s" : "%s openen",
"%1$s via %2$s" : "%1$s via %2$s",
+ "%1$s shared %2$s with you and wants to add:" : "%1$s deelde %2$s met jou en wil toevoegen:",
+ "%1$s shared %2$s with you and wants to add" : "%1$s deelde %2$s met jou en wil toevoegen",
+ "%s added a note to a file shared with you" : "%s heeft een notitie toegevoegd aan een bestand dat met jou werd gedeeld",
"Unknown share type" : "Onbekend type gedeelde folder",
"You are not allowed to share %s" : "Je bent niet bevoegd om %s te delen",
"Cannot increase permissions of %s" : "Kan de machtiging van %s niet verhogen.",
@@ -126,6 +135,7 @@ OC.L10N.register(
"Expiration date is in the past" : "De vervaldatum ligt in het verleden",
"_Cannot set expiration date more than %n day in the future_::_Cannot set expiration date more than %n days in the future_" : ["Kan de vervaldatum niet meer dan %s dag in de toekomst instellen","Kan de vervaldatum niet meer dan %s dagen in de toekomst instellen"],
"Sharing is only allowed with group members" : "Delen kan alleen met groepsleden",
+ "Sharing %s failed, because this item is already shared with the account %s" : "Het delen van%s is mislukt, omdat dit item al gedeeld wordt met het account %s",
"The requested share does not exist anymore" : "De toegang tot de gedeelde folder bestaat niet meer",
"Could not find category \"%s\"" : "Kan categorie \"%s\" niet vinden",
"Sunday" : "Zondag",
@@ -221,19 +231,6 @@ OC.L10N.register(
"Summary" : "Samenvatting",
"Translate" : "Vertaal",
"Result" : "Resultaat",
- "Education Edition" : "Onderwijs Editie",
- "File name is a reserved word" : "Bestandsnaam is een gereserveerd woord",
- "File name contains at least one invalid character" : "De bestandsnaam bevat in ieder geval één verboden teken",
- "File name is too long" : "De bestandsnaam is te lang",
- "Users" : "Gebruikers",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s deelde \"%2$s\" met jou en wil toevoegen:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s deelde \"%2$s\" met jou en wil toevoegen",
- "»%s« added a note to a file shared with you" : "\"%s\" voegde een notitie toe aan een bestand dat met jou is gedeeld",
- "Open »%s«" : "Open \"%s\"",
- "%1$s shared »%2$s« with you" : "%1$s deelde \"%2$s\" met jou",
- "%1$s shared »%2$s« with you." : "%1$s deelde \"%2$s\" met jou.",
- "Click the button below to open it." : "Klik de onderstaande button om te openen.",
- "File is currently busy, please try again later" : "Bestandsverwerking bezig, probeer het later opnieuw",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Zorg dat er een bestand genaamd \".ocdata\" in de hoofddirectory aanwezig is."
+ "File is currently busy, please try again later" : "Bestandsverwerking bezig, probeer het later opnieuw"
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/nl.json b/lib/l10n/nl.json
index e50767941ff..c2bb3c5831b 100644
--- a/lib/l10n/nl.json
+++ b/lib/l10n/nl.json
@@ -51,6 +51,7 @@
"Files" : "Bestanden",
"View profile" : "Bekijk profiel",
"_%nh_::_%nh_" : ["%nh","%nh"],
+ "Local time: %s" : "Lokale tijd: %s",
"today" : "vandaag",
"tomorrow" : "morgen",
"yesterday" : "gisteren",
@@ -73,6 +74,8 @@
"Empty file" : "Leeg bestand",
"Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "Module met ID: %s bestaat niet. Schakel die in binnen de app-instellingen of neem contact op met je beheerder.",
"Dot files are not allowed" : "Punt-bestanden zijn niet toegestaan",
+ "%1$s (renamed)" : "%1$s (hernoemd)",
+ "renamed file" : "bestand hernoemd",
"File already exists" : "Bestand bestaat al",
"Invalid path" : "Ongeldig pad",
"Failed to create file from template" : "Kon geen bestand van het sjabloon maken",
@@ -101,6 +104,7 @@
"Address" : "Adres",
"Profile picture" : "Profielafbeelding",
"About" : "Over",
+ "Display name" : "Weergave naam",
"Headline" : "Hoofdlijn",
"Organisation" : "Organisatie",
"Role" : "Rol",
@@ -115,7 +119,12 @@
"Sharing backend %s must implement the interface OCP\\Share_Backend" : "De gedeelde achtergrond %s moet de OCP\\Share_Backend interface implementeren",
"Sharing backend %s not found" : "De gedeelde backend %s is niet gevonden",
"Sharing backend for %s not found" : "De gedeelde backend voor %s is niet gevonden",
+ "%1$s shared %2$s with you" : "%1$s deelde %2$s met jou",
+ "Open %s" : "%s openen",
"%1$s via %2$s" : "%1$s via %2$s",
+ "%1$s shared %2$s with you and wants to add:" : "%1$s deelde %2$s met jou en wil toevoegen:",
+ "%1$s shared %2$s with you and wants to add" : "%1$s deelde %2$s met jou en wil toevoegen",
+ "%s added a note to a file shared with you" : "%s heeft een notitie toegevoegd aan een bestand dat met jou werd gedeeld",
"Unknown share type" : "Onbekend type gedeelde folder",
"You are not allowed to share %s" : "Je bent niet bevoegd om %s te delen",
"Cannot increase permissions of %s" : "Kan de machtiging van %s niet verhogen.",
@@ -124,6 +133,7 @@
"Expiration date is in the past" : "De vervaldatum ligt in het verleden",
"_Cannot set expiration date more than %n day in the future_::_Cannot set expiration date more than %n days in the future_" : ["Kan de vervaldatum niet meer dan %s dag in de toekomst instellen","Kan de vervaldatum niet meer dan %s dagen in de toekomst instellen"],
"Sharing is only allowed with group members" : "Delen kan alleen met groepsleden",
+ "Sharing %s failed, because this item is already shared with the account %s" : "Het delen van%s is mislukt, omdat dit item al gedeeld wordt met het account %s",
"The requested share does not exist anymore" : "De toegang tot de gedeelde folder bestaat niet meer",
"Could not find category \"%s\"" : "Kan categorie \"%s\" niet vinden",
"Sunday" : "Zondag",
@@ -219,19 +229,6 @@
"Summary" : "Samenvatting",
"Translate" : "Vertaal",
"Result" : "Resultaat",
- "Education Edition" : "Onderwijs Editie",
- "File name is a reserved word" : "Bestandsnaam is een gereserveerd woord",
- "File name contains at least one invalid character" : "De bestandsnaam bevat in ieder geval één verboden teken",
- "File name is too long" : "De bestandsnaam is te lang",
- "Users" : "Gebruikers",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s deelde \"%2$s\" met jou en wil toevoegen:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s deelde \"%2$s\" met jou en wil toevoegen",
- "»%s« added a note to a file shared with you" : "\"%s\" voegde een notitie toe aan een bestand dat met jou is gedeeld",
- "Open »%s«" : "Open \"%s\"",
- "%1$s shared »%2$s« with you" : "%1$s deelde \"%2$s\" met jou",
- "%1$s shared »%2$s« with you." : "%1$s deelde \"%2$s\" met jou.",
- "Click the button below to open it." : "Klik de onderstaande button om te openen.",
- "File is currently busy, please try again later" : "Bestandsverwerking bezig, probeer het later opnieuw",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Zorg dat er een bestand genaamd \".ocdata\" in de hoofddirectory aanwezig is."
+ "File is currently busy, please try again later" : "Bestandsverwerking bezig, probeer het later opnieuw"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/nn_NO.js b/lib/l10n/nn_NO.js
index 9a97c6f4bd3..16fb2f1d6fe 100644
--- a/lib/l10n/nn_NO.js
+++ b/lib/l10n/nn_NO.js
@@ -74,9 +74,6 @@ OC.L10N.register(
"A valid password must be provided" : "Du må oppgje eit gyldig passord",
"Login canceled by app" : "Innlogging avbroten av app",
"Authentication error" : "Feil i autentisering",
- "Summary" : "Oppsumering",
- "File name is too long" : "Filnamnet er for langt",
- "Users" : "Brukarar",
- "Open »%s«" : "Opna »%s«"
+ "Summary" : "Oppsumering"
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/nn_NO.json b/lib/l10n/nn_NO.json
index fffeb3e6bb6..74228b09624 100644
--- a/lib/l10n/nn_NO.json
+++ b/lib/l10n/nn_NO.json
@@ -72,9 +72,6 @@
"A valid password must be provided" : "Du må oppgje eit gyldig passord",
"Login canceled by app" : "Innlogging avbroten av app",
"Authentication error" : "Feil i autentisering",
- "Summary" : "Oppsumering",
- "File name is too long" : "Filnamnet er for langt",
- "Users" : "Brukarar",
- "Open »%s«" : "Opna »%s«"
+ "Summary" : "Oppsumering"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/oc.js b/lib/l10n/oc.js
index 15589751143..d20cfe78083 100644
--- a/lib/l10n/oc.js
+++ b/lib/l10n/oc.js
@@ -71,8 +71,6 @@ OC.L10N.register(
"Storage is temporarily not available" : "Emmagazinatge temporàriament indisponible",
"Chat" : "Messatjariá",
"Text" : "Tèxt",
- "Translate" : "Tradurre",
- "Users" : "Utilizaires",
- "Open »%s«" : "Dobrir « %s »"
+ "Translate" : "Tradurre"
},
"nplurals=2; plural=(n > 1);");
diff --git a/lib/l10n/oc.json b/lib/l10n/oc.json
index bae811f580e..41c70bf329b 100644
--- a/lib/l10n/oc.json
+++ b/lib/l10n/oc.json
@@ -69,8 +69,6 @@
"Storage is temporarily not available" : "Emmagazinatge temporàriament indisponible",
"Chat" : "Messatjariá",
"Text" : "Tèxt",
- "Translate" : "Tradurre",
- "Users" : "Utilizaires",
- "Open »%s«" : "Dobrir « %s »"
+ "Translate" : "Tradurre"
},"pluralForm" :"nplurals=2; plural=(n > 1);"
} \ No newline at end of file
diff --git a/lib/l10n/pl.js b/lib/l10n/pl.js
index 213b78d5c28..884ae246664 100644
--- a/lib/l10n/pl.js
+++ b/lib/l10n/pl.js
@@ -38,6 +38,7 @@ OC.L10N.register(
"Server version %s or higher is required." : "Wymagana jest wersja serwera %s lub wyższa.",
"Server version %s or lower is required." : "Wymagana jest wersja serwera %s lub niższa.",
"Logged in account must be an admin, a sub admin or gotten special right to access this setting" : "Zalogowane konto musi być administratorem, subadministratorem lub posiadać specjalne uprawnienia, aby uzyskać dostęp do tego ustawienia",
+ "Your current IP address doesn't allow you to perform admin actions" : "Twój obecny adres IP nie pozwala na wykonywanie działań administracyjnych",
"Logged in account must be an admin or sub admin" : "Zalogowane konto musi być administratorem lub subadministratorem",
"Logged in account must be an admin" : "Zalogowane konto musi być administratorem",
"Wiping of device %s has started" : "Rozpoczęto czyszczenie urządzenia %s",
@@ -58,7 +59,11 @@ OC.L10N.register(
"Avatar image is not square" : "Obraz awatara nie jest kwadratowy",
"Files" : "Pliki",
"View profile" : "Zobacz profil",
+ "same time" : "jednocześnie",
"_%nh_::_%nh_" : ["%nh","%nh","%nh","%ngodz."],
+ "_%nm_::_%nm_" : ["%nmin","%nmin","%nmin","%nmin"],
+ "%s ahead" : "o %s wcześniej",
+ "%s behind" : "o %s później",
"Local time: %s" : "Czas lokalny: %s",
"today" : "dzisiaj",
"tomorrow" : "jutro",
@@ -81,12 +86,32 @@ OC.L10N.register(
"seconds ago" : "przed chwilą",
"Empty file" : "Pusty plik",
"Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "Moduł o ID: %s nie istnieje. Włącz go w ustawieniach aplikacji lub skontaktuj się z administratorem.",
+ "No file conversion providers available" : "Brak dostępnych usług konwersji plików.",
+ "File is too large to convert" : "Plik jest zbyt duży, aby go przekonwertować.",
+ "Destination does not match conversion extension" : "Docelowy format nie odpowiada rozszerzeniu konwersji",
+ "Could not convert file" : "Nie można przekonwertować pliku",
+ "Destination does not exist" : "Folder docelowy nie istnieje",
+ "Destination is not creatable" : "Nie można utworzyć folderu docelowego",
"Dot files are not allowed" : "Pliki z kropką są niedozwolone",
+ "%1$s (renamed)" : "%1$s (zmieniona nazwa)",
+ "renamed file" : "zmieniona nazwa pliku",
+ "\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" jest zabronioną nazwą pliku lub folderu.",
+ "\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" jest zabronionym przedrostkiem dla nazw plików lub folderów.",
+ "\"%1$s\" is not allowed inside a file or folder name." : "\"%1$s\" nie jest dozwolone w nazwie pliku ani folderu.",
+ "\"%1$s\" is a forbidden file type." : "\"%1$s\" jest zabronionym typem pliku.",
+ "Filenames must not end with \"%1$s\"." : "Nazwa pliku nie może być zakończona znakiem \"%1$s\"",
"Invalid parent path" : "Nieprawidłowa ścieżka nadrzędna",
"File already exists" : "Plik już istnieje",
"Invalid path" : "Niewłaściwa ścieżka",
"Failed to create file from template" : "Nie udało się utworzyć pliku z szablonu",
"Templates" : "Szablony",
+ "Storage %s cannot be moved" : "Magazynu %s nie można przenieść",
+ "Moving a share (%s) into a shared folder is not allowed" : "Przenoszenie udziału (%s) do folderu współdzielonego jest niedozwolone",
+ "Moving a storage (%s) into a shared folder is not allowed" : "Przenoszenie magazynu (%s) do folderu współdzielonego jest niedozwolone",
+ "Moving a share (%s) into another share (%s) is not allowed" : "Przenoszenie udziału (%s) do innego udziału (%s) jest niedozwolone",
+ "Moving a share (%s) into another storage (%s) is not allowed" : "Przenoszenie udziału (%s) do innego magazynu (%s) jest niedozwolone",
+ "Moving a storage (%s) into a share (%s) is not allowed" : "Przenoszenie magazynu (%s) do udziału (%s) jest niedozwolone",
+ "Moving a storage (%s) into another storage (%s) is not allowed" : "Przenoszenie magazynu (%s) do innego magazynu (%s) jest niedozwolone",
"Path contains invalid segments" : "Ścieżka zawiera nieprawidłowe segmenty",
"Filename is a reserved word" : "Nazwa pliku jest słowem zastrzeżonym",
"Filename contains at least one invalid character" : "Nazwa pliku zawiera co najmniej jeden nieprawidłowy znak",
@@ -128,8 +153,12 @@ OC.L10N.register(
"Enter the database Login for %s" : "Wpisz logowanie do bazy danych dla %s",
"Enter the database name for %s" : "Podaj nazwę bazy danych dla %s",
"You cannot use dots in the database name %s" : "Nie można używać kropek w nazwie bazy danych %s",
+ "MySQL Login and/or password not valid" : "Nieprawidłowy login i/lub hasło do MySQL",
"You need to enter details of an existing account." : "Musisz wprowadzić szczegółowe dane dla istniejącego konta.",
"Oracle connection could not be established" : "Nie można nawiązać połączenia z bazą danych Oracle",
+ "Oracle Login and/or password not valid" : "Nieprawidłowy login i/lub hasło do Oracle",
+ "PostgreSQL Login and/or password not valid" : "Nieprawidłowy login i/lub hasło do PostgreSQL",
+ "Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk!" : "Mac OS X nie jest obsługiwany i %s może nie działać poprawnie na tej platformie. Używasz na własne ryzyko!",
"For the best results, please consider using a GNU/Linux server instead." : "Aby uzyskać najlepszy efekt, rozważ użycie serwera GNU/Linux.",
"It seems that this %s instance is running on a 32-bit PHP environment and the open_basedir has been configured in php.ini. This will lead to problems with files over 4 GB and is highly discouraged." : "Wydaje się, że ta instancja %s używa PHP dla 32-bitowego środowiska, ponieważ open_basedir został tak skonfigurowany w php.ini. Doprowadzi to do problemów z plikami powyżej 4 GB i jest bardzo niezalecane.",
"Please remove the open_basedir setting within your php.ini or switch to 64-bit PHP." : "Usuń ustawienie open_basedir w php.ini lub przełącz na PHP 64-bitowe.",
@@ -152,12 +181,14 @@ OC.L10N.register(
"Share recipient should not be empty" : "Odbiorca udostępnienia nie powinien być pusty",
"Share recipient is not a valid circle" : "Odbiorca udostępnienia nie jest prawidłowym kręgiem",
"Unknown share type" : "Nieznany typ udostępnienia",
+ "Share initiator must be set" : "Należy ustawić inicjatora współdzielenia",
"Cannot share with yourself" : "Nie można dzielić się ze sobą",
"Shared path must be set" : "Należy ustawić ścieżkę współdzieloną",
"Shared path must be either a file or a folder" : "Udostępniona ścieżka musi być plikiem lub katalogiem",
"You cannot share your root folder" : "Nie możesz udostępnić swojego katalogu głównego root",
"You are not allowed to share %s" : "Nie możesz udostępnić %s",
"Valid permissions are required for sharing" : "Do udostępniania wymagane są ważne uprawnienia",
+ "File shares cannot have create or delete permissions" : "Udostępnione pliki nie mogą mieć uprawnień do tworzenia ani usuwania",
"Cannot increase permissions of %s" : "Nie można zwiększyć uprawnień %s",
"Shares need at least read permissions" : "Udostępnianie wymaga co najmniej uprawnień do odczytu",
"Files cannot be shared with delete permissions" : "Pliki nie mogą zostać udostępnione z prawem do usuwania",
@@ -166,18 +197,26 @@ OC.L10N.register(
"Expiration date is enforced" : "Obowiązuje data ważności",
"_Cannot set expiration date more than %n day in the future_::_Cannot set expiration date more than %n days in the future_" : ["Nie można utworzyć daty wygaśnięcia na %n dzień do przodu","Nie można utworzyć daty wygaśnięcia na %n dni do przodu","Nie można utworzyć daty wygaśnięcia na %n dni do przodu","Nie można utworzyć daty wygaśnięcia na %n dni do przodu"],
"Sharing is only allowed with group members" : "Udostępnianie jest dozwolone tylko członkom grupy",
+ "Sharing %s failed, because this item is already shared with the account %s" : "Udostępnianie %s nie powiodło się, ponieważ ten element jest już współdzielony z kontem %s",
"Group sharing is now allowed" : "Udostępnianie grupowe jest teraz dozwolone",
"Sharing is only allowed within your own groups" : "Udostępnianie jest dozwolone wyłącznie w obrębie własnych grup",
"Path is already shared with this group" : "Ścieżka jest już udostępniona tej grupie",
"Link sharing is not allowed" : "Udostępnianie odnośników jest niedozwolone",
"Public upload is not allowed" : "Przesyłanie publiczne nie jest dozwolone",
+ "You cannot share a folder that contains other shares" : "Nie można udostępnić folderu zawierającego inne udostępnienia",
"Sharing is disabled" : "Udostępnianie jest wyłączone",
"Sharing is disabled for you" : "Udostępnianie jest dla Ciebie wyłączone",
"Cannot share with the share owner" : "Nie można udostępnić właścicielowi udziału",
"Share does not have a full ID" : "Udział nie ma pełnego identyfikatora",
"Cannot change share type" : "Nie można zmienić typu udziału",
"Can only update recipient on user shares" : "Może aktualizować odbiorców tylko w przypadku udziałów użytkownika",
+ "Cannot enable sending the password by Talk with an empty password" : "Nie można włączyć wysyłania hasła przez Talk przy pustym haśle",
+ "Cannot enable sending the password by Talk without setting a new password" : "Nie można włączyć wysyłania hasła przez Talk bez ustawienia nowego hasła",
+ "Cannot disable sending the password by Talk without setting a new password" : "Nie można wyłączyć wysyłania hasła przez Talk bez ustawienia nowego hasła",
+ "Share provider does not support accepting" : "Dostawca współdzielenia nie obsługuje przyjmowania",
+ "Cannot change target of link share" : "Nie można zmienić celu współdzielonego linku",
"Invalid share recipient" : "Nieprawidłowy odbiorca udostępnienia",
+ "Group \"%s\" does not exist" : "Grupa \"%s\" nie istnieje",
"The requested share does not exist anymore" : "Żądane udostępnienie już nie istnieje",
"The requested share comes from a disabled user" : "Żądane udostępnienie pochodzi od wyłączonego użytkownika",
"The user was not created because the user limit has been reached. Check your notifications to learn more." : "Użytkownik nie został utworzony, ponieważ osiągnięto limit użytkowników. Sprawdź swoje powiadomienia, aby dowiedzieć się więcej.",
@@ -236,6 +275,7 @@ OC.L10N.register(
"A valid Login must be provided" : "Należy podać poprawny login",
"Login contains whitespace at the beginning or at the end" : "Login zawiera spacje na początku lub na końcu",
"Login must not consist of dots only" : "Login nie może składać się wyłącznie z kropek",
+ "Username is too long" : "Nazwa użytkownika jest zbyt długa",
"Login is invalid because files already exist for this user" : "Login jest nieprawidłowy, ponieważ dla tego użytkownika istnieją już pliki",
"Account disabled" : "Konto wyłączone",
"Login canceled by app" : "Logowanie anulowane przez aplikację",
@@ -273,6 +313,7 @@ OC.L10N.register(
"Your data directory must be an absolute path." : "Katalog danych musi mieć ścieżkę absolutną.",
"Check the value of \"datadirectory\" in your configuration." : "Sprawdź wartość \"datadirectory\" w swojej konfiguracji.",
"Your data directory is invalid." : "Katalog danych jest nieprawidłowy.",
+ "Ensure there is a file called \"%1$s\" in the root of the data directory. It should have the content: \"%2$s\"" : "Upewnij się, że w katalogu głównym danych znajduje się plik o nazwie \"%1$s\". Powinien on zawierać: \"%2$s\"",
"Action \"%s\" not supported or implemented." : "Akcja \"%s\" jest niewspierana lub niezaimplementowana.",
"Authentication failed, wrong token or provider ID given" : "Uwierzytelnienie nie powiodło się, podano nieprawidłowy token lub ID dostawcy",
"Parameters missing in order to complete the request. Missing Parameters: \"%s\"" : "Brak parametrów w celu uzupełnienia żądania. Brakujące parametry: \"%s\"",
@@ -284,33 +325,114 @@ OC.L10N.register(
"Storage connection error. %s" : "Błąd połączenia z magazynem. %s",
"Storage is temporarily not available" : "Magazyn jest tymczasowo niedostępny",
"Storage connection timeout. %s" : "Limit czasu połączenia do magazynu. %s",
+ "To allow this check to run you have to make sure that your Web server can connect to itself. Therefore it must be able to resolve and connect to at least one of its `trusted_domains` or the `overwrite.cli.url`. This failure may be the result of a server-side DNS mismatch or outbound firewall rule." : "Aby umożliwić wykonanie tego sprawdzenia, upewnij się, że serwer WWW może połączyć się sam ze sobą. Musi on być w stanie rozpoznać i połączyć się przynajmniej z jedną z wartości 'trusted_domains' lub 'overwrite.cli.url'. Błąd ten może być wynikiem niezgodności DNS po stronie serwera lub reguły zapory sieciowej wychodzącej.",
"Transcribe audio" : "Transkrypcja dźwięku",
"Transcribe the things said in an audio" : "Transkrypcja wypowiedzi w formie audio",
"Audio input" : "Wejście dźwięku",
"The audio to transcribe" : "Dźwięk do transkrypcji",
"Transcription" : "Transkrypcja",
"The transcribed text" : "Tekst transkrypcji",
+ "Chat with an agent" : "Czat z agentem",
+ "Chat message" : "Wiadomość czatu",
+ "A chat message to send to the agent." : "Wiadomość czatu do wysłania do agenta.",
"Confirmation" : "Potwierdzenie",
+ "Whether to confirm previously requested actions: 0 for denial and 1 for confirmation." : "Czy potwierdzić wcześniej żądane działania: 0 — odmowa, 1 — potwierdzenie.",
+ "Conversation token" : "Token konwersacji",
+ "A token representing the conversation." : "Token reprezentujący konwersację.",
"Generated response" : "Wygenerowana odpowiedź",
+ "The response from the chat model." : "Odpowiedź z modelu czatu.",
+ "The new conversation token" : "Nowy token konwersacji",
+ "Send this along with the next interaction." : "Wyślij to razem z następną interakcją.",
+ "Requested actions by the agent" : "Żądane działania agenta",
+ "Actions that the agent would like to carry out in JSON format." : "Działania, które agent chciałby wykonać w formacie JSON.",
+ "Context write" : "Zapis kontekstu",
+ "Writes text in a given style based on the provided source material." : "Tworzy tekst w określonym stylu na podstawie dostarczonego materiału źródłowego.",
"Writing style" : "Styl pisania",
+ "Demonstrate a writing style that you would like to immitate" : "Zaprezentuj styl pisania, który chciałbyś naśladować",
"Source material" : "Materiał źródłowy",
+ "The content that would like to be rewritten in the new writing style" : "Treść, która ma zostać przepisana w nowym stylu pisania",
+ "Generated text" : "Wygenerowany tekst",
+ "The generated text with content from the source material in the given style" : "Wygenerowany tekst z treścią z materiału źródłowego w określonym stylu",
+ "Emoji generator" : "Generator emoji",
+ "Takes text and generates a representative emoji for it." : "Przyjmuje tekst i generuje pasującą emoji.",
+ "The text to generate an emoji for" : "Tekst, dla którego ma zostać wygenerowana emoji",
+ "Generated emoji" : "Wygenerowane emoji",
+ "The generated emoji based on the input text" : "Wygenerowana emoji na podstawie wprowadzonego tekstu",
+ "Generate image" : "Generuj obraz",
+ "Generate an image from a text prompt" : "Wygeneruj obraz z opisu tekstowego",
+ "Prompt" : "Polecenie",
"Describe the image you want to generate" : "Opisz obraz, który chcesz wygenerować",
"Number of images" : "Liczba obrazów",
"How many images to generate" : "Ile obrazów wygenerować",
"Output images" : "Obrazy wyjściowe",
"The generated images" : "Wygenerowane obrazy",
+ "Generate speech" : "Generuj mowę",
+ "Generate speech from a transcript" : "Wygeneruj mowę z transkryptu",
+ "Write transcript that you want the assistant to generate speech from" : "Napisz transkrypt, na podstawie którego asystent ma wygenerować mowę",
+ "Output speech" : "Wygenerowana mowa",
+ "The generated speech" : "Wygenerowana mowa",
+ "Free text to text prompt" : "Dowolny tekst jako polecenie wejściowe",
+ "Runs an arbitrary prompt through a language model that returns a reply" : "Przetwarza dowolne polecenie za pomocą modelu językowego, który zwraca odpowiedź",
+ "Describe a task that you want the assistant to do or ask a question" : "Opisz zadanie, które ma wykonać asystent, lub zadaj pytanie",
+ "Generated reply" : "Wygenerowana odpowiedź",
+ "The generated text from the assistant" : "Wygenerowany tekst od asystenta",
"Change Tone" : "Zmień ton wypowiedzi",
+ "Change the tone of a piece of text." : "Zmień ton fragmentu tekstu",
"Write a text that you want the assistant to rewrite in another tone." : "Napisz tekst, który chcesz, aby asystent napisał inaczej.",
"Desired tone" : "Pożądany ton wypowiedzi",
"In which tone should your text be rewritten?" : "W jakim tonie powinien zostać napisany Twój tekst?",
"The rewritten text in the desired tone, written by the assistant:" : "Przepisany tekst w pożądanym tonie, napisany przez asystenta:",
"Chat" : "Rozmowa",
+ "Chat with the assistant" : "Czat z asystentem",
+ "System prompt" : "Polecenie systemowe",
+ "Define rules and assumptions that the assistant should follow during the conversation." : "Określ zasady i założenia, których asystent powinien przestrzegać podczas rozmowy",
"Chat history" : "Historia rozmów",
+ "The history of chat messages before the current message, starting with a message by the user" : "Historia wiadomości czatu przed bieżącą wiadomością, zaczynając od wiadomości użytkownika",
+ "Response message" : "Wiadomość odpowiedzi",
+ "The generated response as part of the conversation" : "Wygenerowana odpowiedź jako część rozmowy",
+ "Chat with tools" : "Czat z użyciem narzędzi",
+ "Chat with the language model with tool calling support." : "Czat z modelem językowym z obsługą wywoływania narzędzi",
+ "Tool message" : "Wiadomość narzędzia",
+ "The result of tool calls in the last interaction" : "Wynik wywołań narzędzi w ostatniej interakcji",
+ "Available tools" : "Dostępne narzędzia",
+ "The available tools in JSON format" : "Dostępne narzędzia w formacie JSON",
+ "The response from the chat model" : "Odpowiedź z modelu czatu",
+ "Tool calls" : "Wywołania narzędzi",
+ "Tools call instructions from the model in JSON format" : "Instrukcje wywołań narzędzi z modelu w formacie JSON",
+ "Formalize text" : "Sformalizuj tekst",
+ "Takes a text and makes it sound more formal" : "Pobiera tekst i sprawia, że brzmi bardziej formalnie",
+ "Write a text that you want the assistant to formalize" : "Napisz tekst, który chcesz, aby asystent sformalizował",
+ "Formalized text" : "Sformalizowany tekst",
+ "The formalized text" : "Sformalizowany tekst",
+ "Generate a headline" : "Wygeneruj nagłówek",
"Generates a possible headline for a text." : "Generuje możliwy nagłówek tekstu.",
+ "Original text" : "Tekst oryginalny",
+ "The original text to generate a headline for" : "Oryginalny tekst, do którego ma zostać wygenerowany nagłówek",
+ "The generated headline" : "Wygenerowany nagłówek",
+ "Proofread" : "Korekta",
+ "Proofreads a text and lists corrections" : "Sprawdza tekst i podaje poprawki",
"Text" : "Tekst",
+ "The text to proofread" : "Tekst do korekty",
+ "Corrections" : "Poprawki",
+ "The corrections that should be made in your text" : "Poprawki, które należy wprowadzić w Twoim tekście",
+ "Reformulate text" : "Przekształć tekst",
+ "Takes a text and reformulates it" : "Pobiera tekst i przekształca go",
+ "Write a text that you want the assistant to reformulate" : "Napisz tekst, który chcesz, aby asystent przekształcił",
+ "Reformulated text" : "Przekształcony tekst",
+ "The reformulated text, written by the assistant" : "Przekształcony tekst napisany przez asystenta",
+ "Simplify text" : "Uprość tekst",
+ "Takes a text and simplifies it" : "Pobiera tekst i upraszcza go",
+ "Write a text that you want the assistant to simplify" : "Napisz tekst, który chcesz, aby asystent uprościł",
+ "Simplified text" : "Uproszczony tekst",
+ "The simplified text" : "Uproszczony tekst",
"Summarize" : "Podsumuj",
+ "Summarizes a text" : "Tworzy podsumowanie tekstu",
+ "The original text to summarize" : "Oryginalny tekst do podsumowania",
"Summary" : "Podsumowanie",
+ "The generated summary" : "Wygenerowane podsumowanie",
"Extract topics" : "Wyodrębnij tematy",
+ "Extracts topics from a text and outputs them separated by commas" : "Wydobywa tematy z tekstu i zwraca je oddzielone przecinkami",
+ "The original text to extract topics from" : "Oryginalny tekst, z którego mają zostać wydobyte tematy",
"Topics" : "Tematy",
"The list of extracted topics" : "Lista wyodrębnionych tematów",
"Translate" : "Tłumaczenie",
@@ -328,20 +450,8 @@ OC.L10N.register(
"Generate headline" : "Wygeneruj nagłówek",
"Summarizes text by reducing its length without losing key information." : "Podsumowuje tekst, zmniejszając jego długość bez utraty kluczowych informacji.",
"Extracts topics from a text and outputs them separated by commas." : "Wyodrębnia tematy z tekstu i wyświetla je oddzielone przecinkami.",
- "Education Edition" : "Edycja edukacyjna",
- "File name is a reserved word" : "Nazwa pliku jest zarezerwowana",
- "File name contains at least one invalid character" : "Nazwa pliku zawiera co najmniej jeden nieprawidłowy znak",
- "File name is too long" : "Nazwa pliku jest za długa",
- "Users" : "Użytkownicy",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s udostępnił Tobie »%2$s« i chce dodać: ",
- "%1$s shared »%2$s« with you and wants to add" : " %1$s udostępnił Tobie »%2$s« i chce dodać",
- "»%s« added a note to a file shared with you" : "»%s« dodał notatkę do udostępnionego dla Ciebie pliku",
- "Open »%s«" : "Otwórz »%s«",
- "%1$s shared »%2$s« with you" : "%1$s udostępnił Tobie »%2$s«",
- "%1$s shared »%2$s« with you." : "%1$s udostępnił Tobie »%2$s«.",
- "Click the button below to open it." : "Kliknij przycisk poniżej, aby otworzyć.",
"File is currently busy, please try again later" : "Plik jest obecnie niedostępny, spróbuj później",
"Cannot download file" : "Nie można pobrać pliku",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Upewnij się, że w katalogu \"data\" znajduje się plik o nazwie \".ocdata\"."
+ "Login is too long" : "Login jest zbyt długi"
},
"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/lib/l10n/pl.json b/lib/l10n/pl.json
index 6837f941bb7..cfdcc25a3a3 100644
--- a/lib/l10n/pl.json
+++ b/lib/l10n/pl.json
@@ -36,6 +36,7 @@
"Server version %s or higher is required." : "Wymagana jest wersja serwera %s lub wyższa.",
"Server version %s or lower is required." : "Wymagana jest wersja serwera %s lub niższa.",
"Logged in account must be an admin, a sub admin or gotten special right to access this setting" : "Zalogowane konto musi być administratorem, subadministratorem lub posiadać specjalne uprawnienia, aby uzyskać dostęp do tego ustawienia",
+ "Your current IP address doesn't allow you to perform admin actions" : "Twój obecny adres IP nie pozwala na wykonywanie działań administracyjnych",
"Logged in account must be an admin or sub admin" : "Zalogowane konto musi być administratorem lub subadministratorem",
"Logged in account must be an admin" : "Zalogowane konto musi być administratorem",
"Wiping of device %s has started" : "Rozpoczęto czyszczenie urządzenia %s",
@@ -56,7 +57,11 @@
"Avatar image is not square" : "Obraz awatara nie jest kwadratowy",
"Files" : "Pliki",
"View profile" : "Zobacz profil",
+ "same time" : "jednocześnie",
"_%nh_::_%nh_" : ["%nh","%nh","%nh","%ngodz."],
+ "_%nm_::_%nm_" : ["%nmin","%nmin","%nmin","%nmin"],
+ "%s ahead" : "o %s wcześniej",
+ "%s behind" : "o %s później",
"Local time: %s" : "Czas lokalny: %s",
"today" : "dzisiaj",
"tomorrow" : "jutro",
@@ -79,12 +84,32 @@
"seconds ago" : "przed chwilą",
"Empty file" : "Pusty plik",
"Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "Moduł o ID: %s nie istnieje. Włącz go w ustawieniach aplikacji lub skontaktuj się z administratorem.",
+ "No file conversion providers available" : "Brak dostępnych usług konwersji plików.",
+ "File is too large to convert" : "Plik jest zbyt duży, aby go przekonwertować.",
+ "Destination does not match conversion extension" : "Docelowy format nie odpowiada rozszerzeniu konwersji",
+ "Could not convert file" : "Nie można przekonwertować pliku",
+ "Destination does not exist" : "Folder docelowy nie istnieje",
+ "Destination is not creatable" : "Nie można utworzyć folderu docelowego",
"Dot files are not allowed" : "Pliki z kropką są niedozwolone",
+ "%1$s (renamed)" : "%1$s (zmieniona nazwa)",
+ "renamed file" : "zmieniona nazwa pliku",
+ "\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" jest zabronioną nazwą pliku lub folderu.",
+ "\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" jest zabronionym przedrostkiem dla nazw plików lub folderów.",
+ "\"%1$s\" is not allowed inside a file or folder name." : "\"%1$s\" nie jest dozwolone w nazwie pliku ani folderu.",
+ "\"%1$s\" is a forbidden file type." : "\"%1$s\" jest zabronionym typem pliku.",
+ "Filenames must not end with \"%1$s\"." : "Nazwa pliku nie może być zakończona znakiem \"%1$s\"",
"Invalid parent path" : "Nieprawidłowa ścieżka nadrzędna",
"File already exists" : "Plik już istnieje",
"Invalid path" : "Niewłaściwa ścieżka",
"Failed to create file from template" : "Nie udało się utworzyć pliku z szablonu",
"Templates" : "Szablony",
+ "Storage %s cannot be moved" : "Magazynu %s nie można przenieść",
+ "Moving a share (%s) into a shared folder is not allowed" : "Przenoszenie udziału (%s) do folderu współdzielonego jest niedozwolone",
+ "Moving a storage (%s) into a shared folder is not allowed" : "Przenoszenie magazynu (%s) do folderu współdzielonego jest niedozwolone",
+ "Moving a share (%s) into another share (%s) is not allowed" : "Przenoszenie udziału (%s) do innego udziału (%s) jest niedozwolone",
+ "Moving a share (%s) into another storage (%s) is not allowed" : "Przenoszenie udziału (%s) do innego magazynu (%s) jest niedozwolone",
+ "Moving a storage (%s) into a share (%s) is not allowed" : "Przenoszenie magazynu (%s) do udziału (%s) jest niedozwolone",
+ "Moving a storage (%s) into another storage (%s) is not allowed" : "Przenoszenie magazynu (%s) do innego magazynu (%s) jest niedozwolone",
"Path contains invalid segments" : "Ścieżka zawiera nieprawidłowe segmenty",
"Filename is a reserved word" : "Nazwa pliku jest słowem zastrzeżonym",
"Filename contains at least one invalid character" : "Nazwa pliku zawiera co najmniej jeden nieprawidłowy znak",
@@ -126,8 +151,12 @@
"Enter the database Login for %s" : "Wpisz logowanie do bazy danych dla %s",
"Enter the database name for %s" : "Podaj nazwę bazy danych dla %s",
"You cannot use dots in the database name %s" : "Nie można używać kropek w nazwie bazy danych %s",
+ "MySQL Login and/or password not valid" : "Nieprawidłowy login i/lub hasło do MySQL",
"You need to enter details of an existing account." : "Musisz wprowadzić szczegółowe dane dla istniejącego konta.",
"Oracle connection could not be established" : "Nie można nawiązać połączenia z bazą danych Oracle",
+ "Oracle Login and/or password not valid" : "Nieprawidłowy login i/lub hasło do Oracle",
+ "PostgreSQL Login and/or password not valid" : "Nieprawidłowy login i/lub hasło do PostgreSQL",
+ "Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk!" : "Mac OS X nie jest obsługiwany i %s może nie działać poprawnie na tej platformie. Używasz na własne ryzyko!",
"For the best results, please consider using a GNU/Linux server instead." : "Aby uzyskać najlepszy efekt, rozważ użycie serwera GNU/Linux.",
"It seems that this %s instance is running on a 32-bit PHP environment and the open_basedir has been configured in php.ini. This will lead to problems with files over 4 GB and is highly discouraged." : "Wydaje się, że ta instancja %s używa PHP dla 32-bitowego środowiska, ponieważ open_basedir został tak skonfigurowany w php.ini. Doprowadzi to do problemów z plikami powyżej 4 GB i jest bardzo niezalecane.",
"Please remove the open_basedir setting within your php.ini or switch to 64-bit PHP." : "Usuń ustawienie open_basedir w php.ini lub przełącz na PHP 64-bitowe.",
@@ -150,12 +179,14 @@
"Share recipient should not be empty" : "Odbiorca udostępnienia nie powinien być pusty",
"Share recipient is not a valid circle" : "Odbiorca udostępnienia nie jest prawidłowym kręgiem",
"Unknown share type" : "Nieznany typ udostępnienia",
+ "Share initiator must be set" : "Należy ustawić inicjatora współdzielenia",
"Cannot share with yourself" : "Nie można dzielić się ze sobą",
"Shared path must be set" : "Należy ustawić ścieżkę współdzieloną",
"Shared path must be either a file or a folder" : "Udostępniona ścieżka musi być plikiem lub katalogiem",
"You cannot share your root folder" : "Nie możesz udostępnić swojego katalogu głównego root",
"You are not allowed to share %s" : "Nie możesz udostępnić %s",
"Valid permissions are required for sharing" : "Do udostępniania wymagane są ważne uprawnienia",
+ "File shares cannot have create or delete permissions" : "Udostępnione pliki nie mogą mieć uprawnień do tworzenia ani usuwania",
"Cannot increase permissions of %s" : "Nie można zwiększyć uprawnień %s",
"Shares need at least read permissions" : "Udostępnianie wymaga co najmniej uprawnień do odczytu",
"Files cannot be shared with delete permissions" : "Pliki nie mogą zostać udostępnione z prawem do usuwania",
@@ -164,18 +195,26 @@
"Expiration date is enforced" : "Obowiązuje data ważności",
"_Cannot set expiration date more than %n day in the future_::_Cannot set expiration date more than %n days in the future_" : ["Nie można utworzyć daty wygaśnięcia na %n dzień do przodu","Nie można utworzyć daty wygaśnięcia na %n dni do przodu","Nie można utworzyć daty wygaśnięcia na %n dni do przodu","Nie można utworzyć daty wygaśnięcia na %n dni do przodu"],
"Sharing is only allowed with group members" : "Udostępnianie jest dozwolone tylko członkom grupy",
+ "Sharing %s failed, because this item is already shared with the account %s" : "Udostępnianie %s nie powiodło się, ponieważ ten element jest już współdzielony z kontem %s",
"Group sharing is now allowed" : "Udostępnianie grupowe jest teraz dozwolone",
"Sharing is only allowed within your own groups" : "Udostępnianie jest dozwolone wyłącznie w obrębie własnych grup",
"Path is already shared with this group" : "Ścieżka jest już udostępniona tej grupie",
"Link sharing is not allowed" : "Udostępnianie odnośników jest niedozwolone",
"Public upload is not allowed" : "Przesyłanie publiczne nie jest dozwolone",
+ "You cannot share a folder that contains other shares" : "Nie można udostępnić folderu zawierającego inne udostępnienia",
"Sharing is disabled" : "Udostępnianie jest wyłączone",
"Sharing is disabled for you" : "Udostępnianie jest dla Ciebie wyłączone",
"Cannot share with the share owner" : "Nie można udostępnić właścicielowi udziału",
"Share does not have a full ID" : "Udział nie ma pełnego identyfikatora",
"Cannot change share type" : "Nie można zmienić typu udziału",
"Can only update recipient on user shares" : "Może aktualizować odbiorców tylko w przypadku udziałów użytkownika",
+ "Cannot enable sending the password by Talk with an empty password" : "Nie można włączyć wysyłania hasła przez Talk przy pustym haśle",
+ "Cannot enable sending the password by Talk without setting a new password" : "Nie można włączyć wysyłania hasła przez Talk bez ustawienia nowego hasła",
+ "Cannot disable sending the password by Talk without setting a new password" : "Nie można wyłączyć wysyłania hasła przez Talk bez ustawienia nowego hasła",
+ "Share provider does not support accepting" : "Dostawca współdzielenia nie obsługuje przyjmowania",
+ "Cannot change target of link share" : "Nie można zmienić celu współdzielonego linku",
"Invalid share recipient" : "Nieprawidłowy odbiorca udostępnienia",
+ "Group \"%s\" does not exist" : "Grupa \"%s\" nie istnieje",
"The requested share does not exist anymore" : "Żądane udostępnienie już nie istnieje",
"The requested share comes from a disabled user" : "Żądane udostępnienie pochodzi od wyłączonego użytkownika",
"The user was not created because the user limit has been reached. Check your notifications to learn more." : "Użytkownik nie został utworzony, ponieważ osiągnięto limit użytkowników. Sprawdź swoje powiadomienia, aby dowiedzieć się więcej.",
@@ -234,6 +273,7 @@
"A valid Login must be provided" : "Należy podać poprawny login",
"Login contains whitespace at the beginning or at the end" : "Login zawiera spacje na początku lub na końcu",
"Login must not consist of dots only" : "Login nie może składać się wyłącznie z kropek",
+ "Username is too long" : "Nazwa użytkownika jest zbyt długa",
"Login is invalid because files already exist for this user" : "Login jest nieprawidłowy, ponieważ dla tego użytkownika istnieją już pliki",
"Account disabled" : "Konto wyłączone",
"Login canceled by app" : "Logowanie anulowane przez aplikację",
@@ -271,6 +311,7 @@
"Your data directory must be an absolute path." : "Katalog danych musi mieć ścieżkę absolutną.",
"Check the value of \"datadirectory\" in your configuration." : "Sprawdź wartość \"datadirectory\" w swojej konfiguracji.",
"Your data directory is invalid." : "Katalog danych jest nieprawidłowy.",
+ "Ensure there is a file called \"%1$s\" in the root of the data directory. It should have the content: \"%2$s\"" : "Upewnij się, że w katalogu głównym danych znajduje się plik o nazwie \"%1$s\". Powinien on zawierać: \"%2$s\"",
"Action \"%s\" not supported or implemented." : "Akcja \"%s\" jest niewspierana lub niezaimplementowana.",
"Authentication failed, wrong token or provider ID given" : "Uwierzytelnienie nie powiodło się, podano nieprawidłowy token lub ID dostawcy",
"Parameters missing in order to complete the request. Missing Parameters: \"%s\"" : "Brak parametrów w celu uzupełnienia żądania. Brakujące parametry: \"%s\"",
@@ -282,33 +323,114 @@
"Storage connection error. %s" : "Błąd połączenia z magazynem. %s",
"Storage is temporarily not available" : "Magazyn jest tymczasowo niedostępny",
"Storage connection timeout. %s" : "Limit czasu połączenia do magazynu. %s",
+ "To allow this check to run you have to make sure that your Web server can connect to itself. Therefore it must be able to resolve and connect to at least one of its `trusted_domains` or the `overwrite.cli.url`. This failure may be the result of a server-side DNS mismatch or outbound firewall rule." : "Aby umożliwić wykonanie tego sprawdzenia, upewnij się, że serwer WWW może połączyć się sam ze sobą. Musi on być w stanie rozpoznać i połączyć się przynajmniej z jedną z wartości 'trusted_domains' lub 'overwrite.cli.url'. Błąd ten może być wynikiem niezgodności DNS po stronie serwera lub reguły zapory sieciowej wychodzącej.",
"Transcribe audio" : "Transkrypcja dźwięku",
"Transcribe the things said in an audio" : "Transkrypcja wypowiedzi w formie audio",
"Audio input" : "Wejście dźwięku",
"The audio to transcribe" : "Dźwięk do transkrypcji",
"Transcription" : "Transkrypcja",
"The transcribed text" : "Tekst transkrypcji",
+ "Chat with an agent" : "Czat z agentem",
+ "Chat message" : "Wiadomość czatu",
+ "A chat message to send to the agent." : "Wiadomość czatu do wysłania do agenta.",
"Confirmation" : "Potwierdzenie",
+ "Whether to confirm previously requested actions: 0 for denial and 1 for confirmation." : "Czy potwierdzić wcześniej żądane działania: 0 — odmowa, 1 — potwierdzenie.",
+ "Conversation token" : "Token konwersacji",
+ "A token representing the conversation." : "Token reprezentujący konwersację.",
"Generated response" : "Wygenerowana odpowiedź",
+ "The response from the chat model." : "Odpowiedź z modelu czatu.",
+ "The new conversation token" : "Nowy token konwersacji",
+ "Send this along with the next interaction." : "Wyślij to razem z następną interakcją.",
+ "Requested actions by the agent" : "Żądane działania agenta",
+ "Actions that the agent would like to carry out in JSON format." : "Działania, które agent chciałby wykonać w formacie JSON.",
+ "Context write" : "Zapis kontekstu",
+ "Writes text in a given style based on the provided source material." : "Tworzy tekst w określonym stylu na podstawie dostarczonego materiału źródłowego.",
"Writing style" : "Styl pisania",
+ "Demonstrate a writing style that you would like to immitate" : "Zaprezentuj styl pisania, który chciałbyś naśladować",
"Source material" : "Materiał źródłowy",
+ "The content that would like to be rewritten in the new writing style" : "Treść, która ma zostać przepisana w nowym stylu pisania",
+ "Generated text" : "Wygenerowany tekst",
+ "The generated text with content from the source material in the given style" : "Wygenerowany tekst z treścią z materiału źródłowego w określonym stylu",
+ "Emoji generator" : "Generator emoji",
+ "Takes text and generates a representative emoji for it." : "Przyjmuje tekst i generuje pasującą emoji.",
+ "The text to generate an emoji for" : "Tekst, dla którego ma zostać wygenerowana emoji",
+ "Generated emoji" : "Wygenerowane emoji",
+ "The generated emoji based on the input text" : "Wygenerowana emoji na podstawie wprowadzonego tekstu",
+ "Generate image" : "Generuj obraz",
+ "Generate an image from a text prompt" : "Wygeneruj obraz z opisu tekstowego",
+ "Prompt" : "Polecenie",
"Describe the image you want to generate" : "Opisz obraz, który chcesz wygenerować",
"Number of images" : "Liczba obrazów",
"How many images to generate" : "Ile obrazów wygenerować",
"Output images" : "Obrazy wyjściowe",
"The generated images" : "Wygenerowane obrazy",
+ "Generate speech" : "Generuj mowę",
+ "Generate speech from a transcript" : "Wygeneruj mowę z transkryptu",
+ "Write transcript that you want the assistant to generate speech from" : "Napisz transkrypt, na podstawie którego asystent ma wygenerować mowę",
+ "Output speech" : "Wygenerowana mowa",
+ "The generated speech" : "Wygenerowana mowa",
+ "Free text to text prompt" : "Dowolny tekst jako polecenie wejściowe",
+ "Runs an arbitrary prompt through a language model that returns a reply" : "Przetwarza dowolne polecenie za pomocą modelu językowego, który zwraca odpowiedź",
+ "Describe a task that you want the assistant to do or ask a question" : "Opisz zadanie, które ma wykonać asystent, lub zadaj pytanie",
+ "Generated reply" : "Wygenerowana odpowiedź",
+ "The generated text from the assistant" : "Wygenerowany tekst od asystenta",
"Change Tone" : "Zmień ton wypowiedzi",
+ "Change the tone of a piece of text." : "Zmień ton fragmentu tekstu",
"Write a text that you want the assistant to rewrite in another tone." : "Napisz tekst, który chcesz, aby asystent napisał inaczej.",
"Desired tone" : "Pożądany ton wypowiedzi",
"In which tone should your text be rewritten?" : "W jakim tonie powinien zostać napisany Twój tekst?",
"The rewritten text in the desired tone, written by the assistant:" : "Przepisany tekst w pożądanym tonie, napisany przez asystenta:",
"Chat" : "Rozmowa",
+ "Chat with the assistant" : "Czat z asystentem",
+ "System prompt" : "Polecenie systemowe",
+ "Define rules and assumptions that the assistant should follow during the conversation." : "Określ zasady i założenia, których asystent powinien przestrzegać podczas rozmowy",
"Chat history" : "Historia rozmów",
+ "The history of chat messages before the current message, starting with a message by the user" : "Historia wiadomości czatu przed bieżącą wiadomością, zaczynając od wiadomości użytkownika",
+ "Response message" : "Wiadomość odpowiedzi",
+ "The generated response as part of the conversation" : "Wygenerowana odpowiedź jako część rozmowy",
+ "Chat with tools" : "Czat z użyciem narzędzi",
+ "Chat with the language model with tool calling support." : "Czat z modelem językowym z obsługą wywoływania narzędzi",
+ "Tool message" : "Wiadomość narzędzia",
+ "The result of tool calls in the last interaction" : "Wynik wywołań narzędzi w ostatniej interakcji",
+ "Available tools" : "Dostępne narzędzia",
+ "The available tools in JSON format" : "Dostępne narzędzia w formacie JSON",
+ "The response from the chat model" : "Odpowiedź z modelu czatu",
+ "Tool calls" : "Wywołania narzędzi",
+ "Tools call instructions from the model in JSON format" : "Instrukcje wywołań narzędzi z modelu w formacie JSON",
+ "Formalize text" : "Sformalizuj tekst",
+ "Takes a text and makes it sound more formal" : "Pobiera tekst i sprawia, że brzmi bardziej formalnie",
+ "Write a text that you want the assistant to formalize" : "Napisz tekst, który chcesz, aby asystent sformalizował",
+ "Formalized text" : "Sformalizowany tekst",
+ "The formalized text" : "Sformalizowany tekst",
+ "Generate a headline" : "Wygeneruj nagłówek",
"Generates a possible headline for a text." : "Generuje możliwy nagłówek tekstu.",
+ "Original text" : "Tekst oryginalny",
+ "The original text to generate a headline for" : "Oryginalny tekst, do którego ma zostać wygenerowany nagłówek",
+ "The generated headline" : "Wygenerowany nagłówek",
+ "Proofread" : "Korekta",
+ "Proofreads a text and lists corrections" : "Sprawdza tekst i podaje poprawki",
"Text" : "Tekst",
+ "The text to proofread" : "Tekst do korekty",
+ "Corrections" : "Poprawki",
+ "The corrections that should be made in your text" : "Poprawki, które należy wprowadzić w Twoim tekście",
+ "Reformulate text" : "Przekształć tekst",
+ "Takes a text and reformulates it" : "Pobiera tekst i przekształca go",
+ "Write a text that you want the assistant to reformulate" : "Napisz tekst, który chcesz, aby asystent przekształcił",
+ "Reformulated text" : "Przekształcony tekst",
+ "The reformulated text, written by the assistant" : "Przekształcony tekst napisany przez asystenta",
+ "Simplify text" : "Uprość tekst",
+ "Takes a text and simplifies it" : "Pobiera tekst i upraszcza go",
+ "Write a text that you want the assistant to simplify" : "Napisz tekst, który chcesz, aby asystent uprościł",
+ "Simplified text" : "Uproszczony tekst",
+ "The simplified text" : "Uproszczony tekst",
"Summarize" : "Podsumuj",
+ "Summarizes a text" : "Tworzy podsumowanie tekstu",
+ "The original text to summarize" : "Oryginalny tekst do podsumowania",
"Summary" : "Podsumowanie",
+ "The generated summary" : "Wygenerowane podsumowanie",
"Extract topics" : "Wyodrębnij tematy",
+ "Extracts topics from a text and outputs them separated by commas" : "Wydobywa tematy z tekstu i zwraca je oddzielone przecinkami",
+ "The original text to extract topics from" : "Oryginalny tekst, z którego mają zostać wydobyte tematy",
"Topics" : "Tematy",
"The list of extracted topics" : "Lista wyodrębnionych tematów",
"Translate" : "Tłumaczenie",
@@ -326,20 +448,8 @@
"Generate headline" : "Wygeneruj nagłówek",
"Summarizes text by reducing its length without losing key information." : "Podsumowuje tekst, zmniejszając jego długość bez utraty kluczowych informacji.",
"Extracts topics from a text and outputs them separated by commas." : "Wyodrębnia tematy z tekstu i wyświetla je oddzielone przecinkami.",
- "Education Edition" : "Edycja edukacyjna",
- "File name is a reserved word" : "Nazwa pliku jest zarezerwowana",
- "File name contains at least one invalid character" : "Nazwa pliku zawiera co najmniej jeden nieprawidłowy znak",
- "File name is too long" : "Nazwa pliku jest za długa",
- "Users" : "Użytkownicy",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s udostępnił Tobie »%2$s« i chce dodać: ",
- "%1$s shared »%2$s« with you and wants to add" : " %1$s udostępnił Tobie »%2$s« i chce dodać",
- "»%s« added a note to a file shared with you" : "»%s« dodał notatkę do udostępnionego dla Ciebie pliku",
- "Open »%s«" : "Otwórz »%s«",
- "%1$s shared »%2$s« with you" : "%1$s udostępnił Tobie »%2$s«",
- "%1$s shared »%2$s« with you." : "%1$s udostępnił Tobie »%2$s«.",
- "Click the button below to open it." : "Kliknij przycisk poniżej, aby otworzyć.",
"File is currently busy, please try again later" : "Plik jest obecnie niedostępny, spróbuj później",
"Cannot download file" : "Nie można pobrać pliku",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Upewnij się, że w katalogu \"data\" znajduje się plik o nazwie \".ocdata\"."
+ "Login is too long" : "Login jest zbyt długi"
},"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);"
} \ No newline at end of file
diff --git a/lib/l10n/ps.js b/lib/l10n/ps.js
index ad12839299a..8a92f63f40e 100644
--- a/lib/l10n/ps.js
+++ b/lib/l10n/ps.js
@@ -7,7 +7,6 @@ OC.L10N.register(
"Files" : "فایلونه",
"Apps" : "اپلېکشنونه",
"Settings" : "سمونې",
- "Storage is temporarily not available" : "ذخیره د لنډې مودې لپاره نشته",
- "Users" : "کارنان"
+ "Storage is temporarily not available" : "ذخیره د لنډې مودې لپاره نشته"
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/ps.json b/lib/l10n/ps.json
index 280d92e6b22..2a4c66c3e43 100644
--- a/lib/l10n/ps.json
+++ b/lib/l10n/ps.json
@@ -5,7 +5,6 @@
"Files" : "فایلونه",
"Apps" : "اپلېکشنونه",
"Settings" : "سمونې",
- "Storage is temporarily not available" : "ذخیره د لنډې مودې لپاره نشته",
- "Users" : "کارنان"
+ "Storage is temporarily not available" : "ذخیره د لنډې مودې لپاره نشته"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/pt_BR.js b/lib/l10n/pt_BR.js
index 8e242ad9340..af2d50b9d1c 100644
--- a/lib/l10n/pt_BR.js
+++ b/lib/l10n/pt_BR.js
@@ -93,6 +93,8 @@ OC.L10N.register(
"Destination does not exist" : "Destino não existe",
"Destination is not creatable" : "Destino não pode ser criado",
"Dot files are not allowed" : "Arquivos Dot não são permitidos",
+ "%1$s (renamed)" : "%1$s (renomeado)",
+ "renamed file" : "arquivo renomeado",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" é um nome de arquivo ou pasta proibido.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" é um prefixo proibido para nomes de arquivos ou pastas.",
"\"%1$s\" is not allowed inside a file or folder name." : "\"%1$s\" não é permitido dentro de um nome de arquivo ou pasta.",
@@ -141,7 +143,7 @@ OC.L10N.register(
"Profile picture" : "Foto do perfil",
"About" : "Sobre",
"Display name" : "Nome de exibição",
- "Headline" : "Título ",
+ "Headline" : "Título",
"Organisation" : "Organização",
"Role" : "Função",
"Pronouns" : "Pronomes",
@@ -273,7 +275,7 @@ OC.L10N.register(
"A valid Login must be provided" : "Um Login válido deve ser fornecido",
"Login contains whitespace at the beginning or at the end" : "O login contém espaços em branco no início ou no final",
"Login must not consist of dots only" : "O login não deve consistir apenas de pontos",
- "Login is too long" : "O login é muito longo",
+ "Username is too long" : "O nome de usuário é muito longo",
"Login is invalid because files already exist for this user" : "O login é inválido porque já existem arquivos para este usuário",
"Account disabled" : "Conta desativada",
"Login canceled by app" : "Login cancelado pelo aplicativo",
@@ -292,19 +294,19 @@ OC.L10N.register(
"This can usually be fixed by giving the web server write access to the root directory. See %s" : "Geralmente, isso pode ser corrigido dando ao servidor web acesso de gravação ao diretório raiz. Consulte %s",
"Permissions can usually be fixed by giving the web server write access to the root directory. See %s." : "Geralmente, as permissões podem ser corrigidas dando ao servidor web acesso de gravação ao diretório raiz. Consulte %s.",
"Your data directory is not writable." : "Seu diretório de dados não é gravável.",
- "Setting locale to %s failed." : "Falha ao definir a localidade para %s.",
- "Please install one of these locales on your system and restart your web server." : "Por favor, instale uma dessas localidades em seu sistema e reinicie seu servidor web.",
+ "Setting locale to %s failed." : "Falha ao definir a configuração regional para %s.",
+ "Please install one of these locales on your system and restart your web server." : "Por favor, instale uma dessas configurações regionais em seu sistema e reinicie seu servidor web.",
"PHP module %s not installed." : "Módulo PHP %s não instalado.",
"Please ask your server administrator to install the module." : "Por favor, peça ao seu administrador do servidor para instalar o módulo.",
"PHP setting \"%s\" is not set to \"%s\"." : "Configuração PHP \"%s\" não está configurado para \"%s\".",
"Adjusting this setting in php.ini will make Nextcloud run again" : "Ajustar a configuração no php.ini fará com que o Nextcloud execute novamente",
"<code>mbstring.func_overload</code> is set to <code>%s</code> instead of the expected value <code>0</code>." : "<code>mbstring.func_overload</code> está configurado para <code>%s</code> em vez do valor esperado <code>0</code>.",
- "To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini." : "Para corrigir este conjunto de problemas <code>mbstring.func_overload</code> para <code>0</code> no seu php.ini.",
+ "To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini." : "Para corrigir esse problema, defina <code>mbstring.func_overload</code> como <code>0</code> em seu php.ini.",
"PHP is apparently set up to strip inline doc blocks. This will make several core apps inaccessible." : "PHP aparentemente está configurado para retirar blocos doc inline. Isso fará com que vários aplicativos do núcleo fiquem inacessíveis.",
"This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "Isso provavelmente é causado por um cache/acelerador, como Zend OPcache ou eAccelerator.",
"PHP modules have been installed, but they are still listed as missing?" : "Módulos do PHP foram instalados, mas eles ainda estão listados como faltantes?",
"Please ask your server administrator to restart the web server." : "Por favor peça ao administrador do servidor para reiniciar o servidor web.",
- "The required %s config variable is not configured in the config.php file." : "A variável %s de configuração necessária não está configurada no arquivo config.php.",
+ "The required %s config variable is not configured in the config.php file." : "A variável de configuração %s obrigatória não está configurada no arquivo config.php.",
"Please ask your server administrator to check the Nextcloud configuration." : "Peça ao administrador do servidor para verificar a configuração do Nextcloud.",
"Your data directory is readable by other people." : "Seu diretório de dados pode ser lido por outras pessoas.",
"Please change the permissions to 0770 so that the directory cannot be listed by other people." : "Altere as permissões para 0770 para que o diretório não possa ser listado por outras pessoas.",
@@ -323,9 +325,9 @@ OC.L10N.register(
"Storage connection error. %s" : "Erro na conexão de armazenamento. %s",
"Storage is temporarily not available" : "Armazenamento temporariamente indisponível",
"Storage connection timeout. %s" : "Atingido o tempo limite de conexão ao armazenamento. %s",
- "To allow this check to run you have to make sure that your Web server can connect to itself. Therefore it must be able to resolve and connect to at least one of its `trusted_domains` or the `overwrite.cli.url`. This failure may be the result of a server-side DNS mismatch or outbound firewall rule." : "Para permitir que esta verificação seja executada, você deve certificar-se de que seu servidor Web pode se conectar a si mesmo. Portanto, ele deve ser capaz de resolver e conectar-se a pelo menos um de seus `trusted_domains` ou `overwrite.cli.url`. Essa falha pode ser o resultado de uma incompatibilidade de DNS no servidor ou de uma regra de firewall de saída.",
+ "To allow this check to run you have to make sure that your Web server can connect to itself. Therefore it must be able to resolve and connect to at least one of its `trusted_domains` or the `overwrite.cli.url`. This failure may be the result of a server-side DNS mismatch or outbound firewall rule." : "Para permitir que esta verificação seja executada, você deve certificar-se de que seu servidor web pode se conectar a si mesmo. Portanto, ele deve ser capaz de resolver e conectar a pelo menos um de seus `trusted_domains` ou `overwrite.cli.url`. Esta falha pode ser o resultado de uma incompatibilidade de DNS no servidor ou de uma regra de firewall de saída.",
"Transcribe audio" : "Transcrever áudio",
- "Transcribe the things said in an audio" : "Transcreva as coisas ditas em um áudio",
+ "Transcribe the things said in an audio" : "Transcrever o que foi dito em um áudio",
"Audio input" : "Entrada de áudio",
"The audio to transcribe" : "O áudio a ser transcrito",
"Transcription" : "Transcrição",
@@ -343,7 +345,7 @@ OC.L10N.register(
"Send this along with the next interaction." : "Envie isso junto com a próxima interação.",
"Requested actions by the agent" : "Ações solicitadas pelo agente",
"Actions that the agent would like to carry out in JSON format." : "Ações que o agente gostaria de realizar no formato JSON.",
- "Context write" : "Gravação de contexto",
+ "Context write" : "Escrita contextual",
"Writes text in a given style based on the provided source material." : "Escreve texto em um determinado estilo com base no material de origem fornecido.",
"Writing style" : "Estilo de escrita",
"Demonstrate a writing style that you would like to immitate" : "Demonstre um estilo de escrita que você gostaria de imitar",
@@ -353,7 +355,7 @@ OC.L10N.register(
"The generated text with content from the source material in the given style" : "O texto gerado com conteúdo do material de origem no estilo determinado",
"Emoji generator" : "Gerador de emojis",
"Takes text and generates a representative emoji for it." : "Pega texto e gera um emoji representativo para ele.",
- "The text to generate an emoji for" : "O texto para gerar um emoji para",
+ "The text to generate an emoji for" : "O texto para o qual gerar um emoji",
"Generated emoji" : "Emoji gerado",
"The generated emoji based on the input text" : "O emoji gerado com base no texto de entrada",
"Generate image" : "Gerar imagem",
@@ -361,9 +363,14 @@ OC.L10N.register(
"Prompt" : "Prompt",
"Describe the image you want to generate" : "Descreva a imagem que você deseja gerar",
"Number of images" : "Número de imagens",
- "How many images to generate" : "Quantas imagens gerar",
+ "How many images to generate" : "Quantas imagens devem ser geradas",
"Output images" : "Imagens de saída",
"The generated images" : "As imagens geradas",
+ "Generate speech" : "Gerar fala",
+ "Generate speech from a transcript" : "Gerar fala a partir de uma transcrição",
+ "Write transcript that you want the assistant to generate speech from" : "Escreva a transcrição a partir da qual você deseja que o assistente gere a fala",
+ "Output speech" : "Fala de saída",
+ "The generated speech" : "A fala gerada",
"Free text to text prompt" : "Prompt de texto livre para texto",
"Runs an arbitrary prompt through a language model that returns a reply" : "Usa um modelo de linguagem para gerar uma resposta a partir de um prompt.",
"Describe a task that you want the assistant to do or ask a question" : "Descreva uma tarefa que você deseja que o assistente execute ou faça uma pergunta",
@@ -375,7 +382,7 @@ OC.L10N.register(
"Desired tone" : "Tom desejado",
"In which tone should your text be rewritten?" : "Em qual tom seu texto deve ser reescrito?",
"The rewritten text in the desired tone, written by the assistant:" : "O texto reescrito no tom desejado, escrito pelo assistente:",
- "Chat" : "Conversa",
+ "Chat" : "Bate-papo",
"Chat with the assistant" : "Converse com o assistente",
"System prompt" : "Prompt do sistema",
"Define rules and assumptions that the assistant should follow during the conversation." : "Defina regras e suposições que o assistente deve seguir durante a conversa.",
@@ -386,21 +393,21 @@ OC.L10N.register(
"Chat with tools" : "Conversar com ferramentas",
"Chat with the language model with tool calling support." : "Converse com o modelo de linguagem com suporte a tool calling (\"chamadas a ferramentas\").",
"Tool message" : "Mensagem da ferramenta",
- "The result of tool calls in the last interaction" : "O resultado das chamadas de ferramentas na última interação",
+ "The result of tool calls in the last interaction" : "O resultado das chamadas a ferramentas na última interação",
"Available tools" : "Ferramentas disponíveis",
"The available tools in JSON format" : "As ferramentas disponíveis em formato JSON",
"The response from the chat model" : "A resposta do modelo de bate-papo",
- "Tool calls" : "Chamadas de ferramentas",
- "Tools call instructions from the model in JSON format" : "Instruções de chamada de ferramentas do modelo no formato JSON",
+ "Tool calls" : "Chamadas a ferramentas",
+ "Tools call instructions from the model in JSON format" : "Instruções para chamadas a ferramentas do modelo no formato JSON",
"Formalize text" : "Formalizar texto",
- "Takes a text and makes it sound more formal" : "Pega um texto e faz com que ele soe mais formal",
+ "Takes a text and makes it sound more formal" : "Pega um texto e o faz parecer mais formal",
"Write a text that you want the assistant to formalize" : "Escreva um texto que você deseja que o assistente formalize",
"Formalized text" : "Texto formalizado",
"The formalized text" : "O texto formalizado",
"Generate a headline" : "Gere um título",
- "Generates a possible headline for a text." : "Gera um título possível para um texto.",
+ "Generates a possible headline for a text." : "Gera um possível título para um texto.",
"Original text" : "Texto original",
- "The original text to generate a headline for" : "O texto original para gerar um título para",
+ "The original text to generate a headline for" : "O texto original para gerar um título",
"The generated headline" : "O título gerado",
"Proofread" : "Revisar",
"Proofreads a text and lists corrections" : "Revisa um texto e lista as correções",
@@ -410,11 +417,11 @@ OC.L10N.register(
"The corrections that should be made in your text" : "As correções que devem ser feitas em seu texto",
"Reformulate text" : "Reformular texto",
"Takes a text and reformulates it" : "Pega um texto e o reformula",
- "Write a text that you want the assistant to reformulate" : "Escrever um texto que você deseja que o assistente reformule",
+ "Write a text that you want the assistant to reformulate" : "Escreva um texto que você deseja que o assistente reformule",
"Reformulated text" : "Texto reformulado",
- "The reformulated text, written by the assistant" : "O texto reformulado, escrito pela assistente",
+ "The reformulated text, written by the assistant" : "O texto reformulado, escrito pelo assistente",
"Simplify text" : "Simplificar texto",
- "Takes a text and simplifies it" : "Pega e simplifica um texto",
+ "Takes a text and simplifies it" : "Pega um texto e o simplifica",
"Write a text that you want the assistant to simplify" : "Escreva um texto que você deseja que o assistente simplifique",
"Simplified text" : "Texto simplificado",
"The simplified text" : "O texto simplificado",
@@ -423,11 +430,11 @@ OC.L10N.register(
"The original text to summarize" : "O texto original para resumir",
"Summary" : "Resumo",
"The generated summary" : "O resumo gerado",
- "Extract topics" : "Extrair tópicos",
- "Extracts topics from a text and outputs them separated by commas" : "Extrai tópicos de um texto e os exibe separados por vírgulas",
- "The original text to extract topics from" : "O texto original para extrair tópicos de",
- "Topics" : "Tópicos",
- "The list of extracted topics" : "A lista de tópicos extraídos",
+ "Extract topics" : "Extrair temas",
+ "Extracts topics from a text and outputs them separated by commas" : "Extrai temas de um texto e os exibe separados por vírgulas",
+ "The original text to extract topics from" : "O texto original do qual extrair temas",
+ "Topics" : "Temas",
+ "The list of extracted topics" : "A lista de temas extraídos",
"Translate" : "Traduzir",
"Translate text from one language to another" : "Traduzir um texto de um idioma para outro",
"Origin text" : "Texto original",
@@ -439,24 +446,12 @@ OC.L10N.register(
"Result" : "Resultado",
"The translated text" : "O texto traduzido",
"Free prompt" : "Prompt livre",
- "Runs an arbitrary prompt through the language model." : "Executa um prompt arbitrário por meio do modelo de idioma.",
+ "Runs an arbitrary prompt through the language model." : "Executa um prompt arbitrário por meio do modelo de linguagem.",
"Generate headline" : "Gerar título",
"Summarizes text by reducing its length without losing key information." : "Resume o texto reduzindo seu comprimento sem perder informações importantes.",
- "Extracts topics from a text and outputs them separated by commas." : "Extrai tópicos de um texto e os gera separados por vírgulas.",
- "Education Edition" : "Edição Educativa",
- "File name is a reserved word" : "O nome do arquivo é uma palavra reservada",
- "File name contains at least one invalid character" : "O nome do arquivo contém pelo menos um caracter inválido",
- "File name is too long" : "O nome do arquivo é muito longo",
- "Users" : "Usuários",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s compartilhou »%2$s« com você e quer adicionar:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s compartilhou »%2$s« com você e quer adicionar",
- "»%s« added a note to a file shared with you" : "»%s« adicionou uma anotação num arquivo compartilhado com você",
- "Open »%s«" : "Abrir »%s«",
- "%1$s shared »%2$s« with you" : "%1$s compartilhou »%2$s« com você",
- "%1$s shared »%2$s« with you." : "%1$s compartilhou »%2$s« com você.",
- "Click the button below to open it." : "Clique no botão abaixo para abri-lo.",
+ "Extracts topics from a text and outputs them separated by commas." : "Extrai temas de um texto e os exibe separados por vírgulas.",
"File is currently busy, please try again later" : "O arquivo está ocupado, tente novamente mais tarde",
"Cannot download file" : "Não é possível baixar o arquivo",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Assegure-se que exista um arquivo chamado \".ocdata\" na raiz do diretório \"data\"."
+ "Login is too long" : "Login é muito longo"
},
"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/lib/l10n/pt_BR.json b/lib/l10n/pt_BR.json
index 6353e34b450..3c28e56e91d 100644
--- a/lib/l10n/pt_BR.json
+++ b/lib/l10n/pt_BR.json
@@ -91,6 +91,8 @@
"Destination does not exist" : "Destino não existe",
"Destination is not creatable" : "Destino não pode ser criado",
"Dot files are not allowed" : "Arquivos Dot não são permitidos",
+ "%1$s (renamed)" : "%1$s (renomeado)",
+ "renamed file" : "arquivo renomeado",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" é um nome de arquivo ou pasta proibido.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" é um prefixo proibido para nomes de arquivos ou pastas.",
"\"%1$s\" is not allowed inside a file or folder name." : "\"%1$s\" não é permitido dentro de um nome de arquivo ou pasta.",
@@ -139,7 +141,7 @@
"Profile picture" : "Foto do perfil",
"About" : "Sobre",
"Display name" : "Nome de exibição",
- "Headline" : "Título ",
+ "Headline" : "Título",
"Organisation" : "Organização",
"Role" : "Função",
"Pronouns" : "Pronomes",
@@ -271,7 +273,7 @@
"A valid Login must be provided" : "Um Login válido deve ser fornecido",
"Login contains whitespace at the beginning or at the end" : "O login contém espaços em branco no início ou no final",
"Login must not consist of dots only" : "O login não deve consistir apenas de pontos",
- "Login is too long" : "O login é muito longo",
+ "Username is too long" : "O nome de usuário é muito longo",
"Login is invalid because files already exist for this user" : "O login é inválido porque já existem arquivos para este usuário",
"Account disabled" : "Conta desativada",
"Login canceled by app" : "Login cancelado pelo aplicativo",
@@ -290,19 +292,19 @@
"This can usually be fixed by giving the web server write access to the root directory. See %s" : "Geralmente, isso pode ser corrigido dando ao servidor web acesso de gravação ao diretório raiz. Consulte %s",
"Permissions can usually be fixed by giving the web server write access to the root directory. See %s." : "Geralmente, as permissões podem ser corrigidas dando ao servidor web acesso de gravação ao diretório raiz. Consulte %s.",
"Your data directory is not writable." : "Seu diretório de dados não é gravável.",
- "Setting locale to %s failed." : "Falha ao definir a localidade para %s.",
- "Please install one of these locales on your system and restart your web server." : "Por favor, instale uma dessas localidades em seu sistema e reinicie seu servidor web.",
+ "Setting locale to %s failed." : "Falha ao definir a configuração regional para %s.",
+ "Please install one of these locales on your system and restart your web server." : "Por favor, instale uma dessas configurações regionais em seu sistema e reinicie seu servidor web.",
"PHP module %s not installed." : "Módulo PHP %s não instalado.",
"Please ask your server administrator to install the module." : "Por favor, peça ao seu administrador do servidor para instalar o módulo.",
"PHP setting \"%s\" is not set to \"%s\"." : "Configuração PHP \"%s\" não está configurado para \"%s\".",
"Adjusting this setting in php.ini will make Nextcloud run again" : "Ajustar a configuração no php.ini fará com que o Nextcloud execute novamente",
"<code>mbstring.func_overload</code> is set to <code>%s</code> instead of the expected value <code>0</code>." : "<code>mbstring.func_overload</code> está configurado para <code>%s</code> em vez do valor esperado <code>0</code>.",
- "To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini." : "Para corrigir este conjunto de problemas <code>mbstring.func_overload</code> para <code>0</code> no seu php.ini.",
+ "To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini." : "Para corrigir esse problema, defina <code>mbstring.func_overload</code> como <code>0</code> em seu php.ini.",
"PHP is apparently set up to strip inline doc blocks. This will make several core apps inaccessible." : "PHP aparentemente está configurado para retirar blocos doc inline. Isso fará com que vários aplicativos do núcleo fiquem inacessíveis.",
"This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "Isso provavelmente é causado por um cache/acelerador, como Zend OPcache ou eAccelerator.",
"PHP modules have been installed, but they are still listed as missing?" : "Módulos do PHP foram instalados, mas eles ainda estão listados como faltantes?",
"Please ask your server administrator to restart the web server." : "Por favor peça ao administrador do servidor para reiniciar o servidor web.",
- "The required %s config variable is not configured in the config.php file." : "A variável %s de configuração necessária não está configurada no arquivo config.php.",
+ "The required %s config variable is not configured in the config.php file." : "A variável de configuração %s obrigatória não está configurada no arquivo config.php.",
"Please ask your server administrator to check the Nextcloud configuration." : "Peça ao administrador do servidor para verificar a configuração do Nextcloud.",
"Your data directory is readable by other people." : "Seu diretório de dados pode ser lido por outras pessoas.",
"Please change the permissions to 0770 so that the directory cannot be listed by other people." : "Altere as permissões para 0770 para que o diretório não possa ser listado por outras pessoas.",
@@ -321,9 +323,9 @@
"Storage connection error. %s" : "Erro na conexão de armazenamento. %s",
"Storage is temporarily not available" : "Armazenamento temporariamente indisponível",
"Storage connection timeout. %s" : "Atingido o tempo limite de conexão ao armazenamento. %s",
- "To allow this check to run you have to make sure that your Web server can connect to itself. Therefore it must be able to resolve and connect to at least one of its `trusted_domains` or the `overwrite.cli.url`. This failure may be the result of a server-side DNS mismatch or outbound firewall rule." : "Para permitir que esta verificação seja executada, você deve certificar-se de que seu servidor Web pode se conectar a si mesmo. Portanto, ele deve ser capaz de resolver e conectar-se a pelo menos um de seus `trusted_domains` ou `overwrite.cli.url`. Essa falha pode ser o resultado de uma incompatibilidade de DNS no servidor ou de uma regra de firewall de saída.",
+ "To allow this check to run you have to make sure that your Web server can connect to itself. Therefore it must be able to resolve and connect to at least one of its `trusted_domains` or the `overwrite.cli.url`. This failure may be the result of a server-side DNS mismatch or outbound firewall rule." : "Para permitir que esta verificação seja executada, você deve certificar-se de que seu servidor web pode se conectar a si mesmo. Portanto, ele deve ser capaz de resolver e conectar a pelo menos um de seus `trusted_domains` ou `overwrite.cli.url`. Esta falha pode ser o resultado de uma incompatibilidade de DNS no servidor ou de uma regra de firewall de saída.",
"Transcribe audio" : "Transcrever áudio",
- "Transcribe the things said in an audio" : "Transcreva as coisas ditas em um áudio",
+ "Transcribe the things said in an audio" : "Transcrever o que foi dito em um áudio",
"Audio input" : "Entrada de áudio",
"The audio to transcribe" : "O áudio a ser transcrito",
"Transcription" : "Transcrição",
@@ -341,7 +343,7 @@
"Send this along with the next interaction." : "Envie isso junto com a próxima interação.",
"Requested actions by the agent" : "Ações solicitadas pelo agente",
"Actions that the agent would like to carry out in JSON format." : "Ações que o agente gostaria de realizar no formato JSON.",
- "Context write" : "Gravação de contexto",
+ "Context write" : "Escrita contextual",
"Writes text in a given style based on the provided source material." : "Escreve texto em um determinado estilo com base no material de origem fornecido.",
"Writing style" : "Estilo de escrita",
"Demonstrate a writing style that you would like to immitate" : "Demonstre um estilo de escrita que você gostaria de imitar",
@@ -351,7 +353,7 @@
"The generated text with content from the source material in the given style" : "O texto gerado com conteúdo do material de origem no estilo determinado",
"Emoji generator" : "Gerador de emojis",
"Takes text and generates a representative emoji for it." : "Pega texto e gera um emoji representativo para ele.",
- "The text to generate an emoji for" : "O texto para gerar um emoji para",
+ "The text to generate an emoji for" : "O texto para o qual gerar um emoji",
"Generated emoji" : "Emoji gerado",
"The generated emoji based on the input text" : "O emoji gerado com base no texto de entrada",
"Generate image" : "Gerar imagem",
@@ -359,9 +361,14 @@
"Prompt" : "Prompt",
"Describe the image you want to generate" : "Descreva a imagem que você deseja gerar",
"Number of images" : "Número de imagens",
- "How many images to generate" : "Quantas imagens gerar",
+ "How many images to generate" : "Quantas imagens devem ser geradas",
"Output images" : "Imagens de saída",
"The generated images" : "As imagens geradas",
+ "Generate speech" : "Gerar fala",
+ "Generate speech from a transcript" : "Gerar fala a partir de uma transcrição",
+ "Write transcript that you want the assistant to generate speech from" : "Escreva a transcrição a partir da qual você deseja que o assistente gere a fala",
+ "Output speech" : "Fala de saída",
+ "The generated speech" : "A fala gerada",
"Free text to text prompt" : "Prompt de texto livre para texto",
"Runs an arbitrary prompt through a language model that returns a reply" : "Usa um modelo de linguagem para gerar uma resposta a partir de um prompt.",
"Describe a task that you want the assistant to do or ask a question" : "Descreva uma tarefa que você deseja que o assistente execute ou faça uma pergunta",
@@ -373,7 +380,7 @@
"Desired tone" : "Tom desejado",
"In which tone should your text be rewritten?" : "Em qual tom seu texto deve ser reescrito?",
"The rewritten text in the desired tone, written by the assistant:" : "O texto reescrito no tom desejado, escrito pelo assistente:",
- "Chat" : "Conversa",
+ "Chat" : "Bate-papo",
"Chat with the assistant" : "Converse com o assistente",
"System prompt" : "Prompt do sistema",
"Define rules and assumptions that the assistant should follow during the conversation." : "Defina regras e suposições que o assistente deve seguir durante a conversa.",
@@ -384,21 +391,21 @@
"Chat with tools" : "Conversar com ferramentas",
"Chat with the language model with tool calling support." : "Converse com o modelo de linguagem com suporte a tool calling (\"chamadas a ferramentas\").",
"Tool message" : "Mensagem da ferramenta",
- "The result of tool calls in the last interaction" : "O resultado das chamadas de ferramentas na última interação",
+ "The result of tool calls in the last interaction" : "O resultado das chamadas a ferramentas na última interação",
"Available tools" : "Ferramentas disponíveis",
"The available tools in JSON format" : "As ferramentas disponíveis em formato JSON",
"The response from the chat model" : "A resposta do modelo de bate-papo",
- "Tool calls" : "Chamadas de ferramentas",
- "Tools call instructions from the model in JSON format" : "Instruções de chamada de ferramentas do modelo no formato JSON",
+ "Tool calls" : "Chamadas a ferramentas",
+ "Tools call instructions from the model in JSON format" : "Instruções para chamadas a ferramentas do modelo no formato JSON",
"Formalize text" : "Formalizar texto",
- "Takes a text and makes it sound more formal" : "Pega um texto e faz com que ele soe mais formal",
+ "Takes a text and makes it sound more formal" : "Pega um texto e o faz parecer mais formal",
"Write a text that you want the assistant to formalize" : "Escreva um texto que você deseja que o assistente formalize",
"Formalized text" : "Texto formalizado",
"The formalized text" : "O texto formalizado",
"Generate a headline" : "Gere um título",
- "Generates a possible headline for a text." : "Gera um título possível para um texto.",
+ "Generates a possible headline for a text." : "Gera um possível título para um texto.",
"Original text" : "Texto original",
- "The original text to generate a headline for" : "O texto original para gerar um título para",
+ "The original text to generate a headline for" : "O texto original para gerar um título",
"The generated headline" : "O título gerado",
"Proofread" : "Revisar",
"Proofreads a text and lists corrections" : "Revisa um texto e lista as correções",
@@ -408,11 +415,11 @@
"The corrections that should be made in your text" : "As correções que devem ser feitas em seu texto",
"Reformulate text" : "Reformular texto",
"Takes a text and reformulates it" : "Pega um texto e o reformula",
- "Write a text that you want the assistant to reformulate" : "Escrever um texto que você deseja que o assistente reformule",
+ "Write a text that you want the assistant to reformulate" : "Escreva um texto que você deseja que o assistente reformule",
"Reformulated text" : "Texto reformulado",
- "The reformulated text, written by the assistant" : "O texto reformulado, escrito pela assistente",
+ "The reformulated text, written by the assistant" : "O texto reformulado, escrito pelo assistente",
"Simplify text" : "Simplificar texto",
- "Takes a text and simplifies it" : "Pega e simplifica um texto",
+ "Takes a text and simplifies it" : "Pega um texto e o simplifica",
"Write a text that you want the assistant to simplify" : "Escreva um texto que você deseja que o assistente simplifique",
"Simplified text" : "Texto simplificado",
"The simplified text" : "O texto simplificado",
@@ -421,11 +428,11 @@
"The original text to summarize" : "O texto original para resumir",
"Summary" : "Resumo",
"The generated summary" : "O resumo gerado",
- "Extract topics" : "Extrair tópicos",
- "Extracts topics from a text and outputs them separated by commas" : "Extrai tópicos de um texto e os exibe separados por vírgulas",
- "The original text to extract topics from" : "O texto original para extrair tópicos de",
- "Topics" : "Tópicos",
- "The list of extracted topics" : "A lista de tópicos extraídos",
+ "Extract topics" : "Extrair temas",
+ "Extracts topics from a text and outputs them separated by commas" : "Extrai temas de um texto e os exibe separados por vírgulas",
+ "The original text to extract topics from" : "O texto original do qual extrair temas",
+ "Topics" : "Temas",
+ "The list of extracted topics" : "A lista de temas extraídos",
"Translate" : "Traduzir",
"Translate text from one language to another" : "Traduzir um texto de um idioma para outro",
"Origin text" : "Texto original",
@@ -437,24 +444,12 @@
"Result" : "Resultado",
"The translated text" : "O texto traduzido",
"Free prompt" : "Prompt livre",
- "Runs an arbitrary prompt through the language model." : "Executa um prompt arbitrário por meio do modelo de idioma.",
+ "Runs an arbitrary prompt through the language model." : "Executa um prompt arbitrário por meio do modelo de linguagem.",
"Generate headline" : "Gerar título",
"Summarizes text by reducing its length without losing key information." : "Resume o texto reduzindo seu comprimento sem perder informações importantes.",
- "Extracts topics from a text and outputs them separated by commas." : "Extrai tópicos de um texto e os gera separados por vírgulas.",
- "Education Edition" : "Edição Educativa",
- "File name is a reserved word" : "O nome do arquivo é uma palavra reservada",
- "File name contains at least one invalid character" : "O nome do arquivo contém pelo menos um caracter inválido",
- "File name is too long" : "O nome do arquivo é muito longo",
- "Users" : "Usuários",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s compartilhou »%2$s« com você e quer adicionar:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s compartilhou »%2$s« com você e quer adicionar",
- "»%s« added a note to a file shared with you" : "»%s« adicionou uma anotação num arquivo compartilhado com você",
- "Open »%s«" : "Abrir »%s«",
- "%1$s shared »%2$s« with you" : "%1$s compartilhou »%2$s« com você",
- "%1$s shared »%2$s« with you." : "%1$s compartilhou »%2$s« com você.",
- "Click the button below to open it." : "Clique no botão abaixo para abri-lo.",
+ "Extracts topics from a text and outputs them separated by commas." : "Extrai temas de um texto e os exibe separados por vírgulas.",
"File is currently busy, please try again later" : "O arquivo está ocupado, tente novamente mais tarde",
"Cannot download file" : "Não é possível baixar o arquivo",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Assegure-se que exista um arquivo chamado \".ocdata\" na raiz do diretório \"data\"."
+ "Login is too long" : "Login é muito longo"
},"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
} \ No newline at end of file
diff --git a/lib/l10n/pt_PT.js b/lib/l10n/pt_PT.js
index 50582277964..937cd4b983a 100644
--- a/lib/l10n/pt_PT.js
+++ b/lib/l10n/pt_PT.js
@@ -56,6 +56,8 @@ OC.L10N.register(
"Empty file" : "Ficheiro vazio",
"Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "Módulo com ID: %s não existe. Por favor ative-o nas definições da aplicação ou contacte o administrador.",
"Dot files are not allowed" : "Ficheiros dot não são permitidos",
+ "%1$s (renamed)" : "%1$s (renomeado)",
+ "renamed file" : "ficheiro renomeado",
"File already exists" : "O ficheiro já existe",
"Invalid path" : "Caminho inválido!",
"Failed to create file from template" : "Erro ao criar o ficheiro a partir do modelo",
@@ -69,6 +71,7 @@ OC.L10N.register(
"Apps" : "Apps",
"Settings" : "Definições",
"Log out" : "Sair",
+ "Accounts" : "Contas",
"Email" : "E-mail",
"Mail %s" : "Mensagem para %s",
"Phone" : "Telefone",
@@ -175,20 +178,7 @@ OC.L10N.register(
"Text" : "Texto",
"Summary" : "Resumo",
"Translate" : "Traduzir",
- "Education Edition" : "Edição Educação",
- "File name is a reserved word" : "Nome de ficheiro é uma palavra reservada",
- "File name contains at least one invalid character" : "Nome de ficheiro contém pelo menos um caráter inválido",
- "File name is too long" : "Nome do ficheiro demasiado longo",
- "Users" : "Utilizadores",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s partilhado »%2$s« consigo e quer adicionar:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s partilhado »%2$s« consigo e quer adicionar:",
- "»%s« added a note to a file shared with you" : "»%s« adicionou uma nota a um ficheiro partilhado consigo",
- "Open »%s«" : "Abrir »%s«",
- "%1$s shared »%2$s« with you" : "%1$s partilhado »%2$s« contigo",
- "%1$s shared »%2$s« with you." : "%1$s partilhado »%2$s« contigo.",
- "Click the button below to open it." : "Clicar no botão abaixo para abrir.",
"File is currently busy, please try again later" : "O ficheiro está ocupado, por favor, tente mais tarde",
- "Cannot download file" : "Não é possível transferir o ficheiro",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Garanta que existe um ficheiro chamado \".occdata\" na raiz do diretório de dados"
+ "Cannot download file" : "Não é possível transferir o ficheiro"
},
"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
diff --git a/lib/l10n/pt_PT.json b/lib/l10n/pt_PT.json
index 39d9a573a72..d8955a0796a 100644
--- a/lib/l10n/pt_PT.json
+++ b/lib/l10n/pt_PT.json
@@ -54,6 +54,8 @@
"Empty file" : "Ficheiro vazio",
"Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "Módulo com ID: %s não existe. Por favor ative-o nas definições da aplicação ou contacte o administrador.",
"Dot files are not allowed" : "Ficheiros dot não são permitidos",
+ "%1$s (renamed)" : "%1$s (renomeado)",
+ "renamed file" : "ficheiro renomeado",
"File already exists" : "O ficheiro já existe",
"Invalid path" : "Caminho inválido!",
"Failed to create file from template" : "Erro ao criar o ficheiro a partir do modelo",
@@ -67,6 +69,7 @@
"Apps" : "Apps",
"Settings" : "Definições",
"Log out" : "Sair",
+ "Accounts" : "Contas",
"Email" : "E-mail",
"Mail %s" : "Mensagem para %s",
"Phone" : "Telefone",
@@ -173,20 +176,7 @@
"Text" : "Texto",
"Summary" : "Resumo",
"Translate" : "Traduzir",
- "Education Edition" : "Edição Educação",
- "File name is a reserved word" : "Nome de ficheiro é uma palavra reservada",
- "File name contains at least one invalid character" : "Nome de ficheiro contém pelo menos um caráter inválido",
- "File name is too long" : "Nome do ficheiro demasiado longo",
- "Users" : "Utilizadores",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s partilhado »%2$s« consigo e quer adicionar:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s partilhado »%2$s« consigo e quer adicionar:",
- "»%s« added a note to a file shared with you" : "»%s« adicionou uma nota a um ficheiro partilhado consigo",
- "Open »%s«" : "Abrir »%s«",
- "%1$s shared »%2$s« with you" : "%1$s partilhado »%2$s« contigo",
- "%1$s shared »%2$s« with you." : "%1$s partilhado »%2$s« contigo.",
- "Click the button below to open it." : "Clicar no botão abaixo para abrir.",
"File is currently busy, please try again later" : "O ficheiro está ocupado, por favor, tente mais tarde",
- "Cannot download file" : "Não é possível transferir o ficheiro",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Garanta que existe um ficheiro chamado \".occdata\" na raiz do diretório de dados"
+ "Cannot download file" : "Não é possível transferir o ficheiro"
},"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
} \ No newline at end of file
diff --git a/lib/l10n/ro.js b/lib/l10n/ro.js
index f3164f7a926..2569614450c 100644
--- a/lib/l10n/ro.js
+++ b/lib/l10n/ro.js
@@ -235,20 +235,7 @@ OC.L10N.register(
"Generate headline" : "Generează titlu",
"Summarizes text by reducing its length without losing key information." : "Rezumă textul prin reducerea lungimii acestuia, fără a pierde informațiile cheie.",
"Extracts topics from a text and outputs them separated by commas." : "Extrage subiecte din text și le furnizează separate prin virgulă.",
- "Education Edition" : "Ediția pentru educație",
- "File name is a reserved word" : "Numele fișierului este un cuvânt rezervat",
- "File name contains at least one invalid character" : "Numele fișierului conține cel puțin un caracter invalid",
- "File name is too long" : "Numele fișierului este prea lung",
- "Users" : "Utilizatori",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s a partajat »%2$s« cu tine și vrea să adauge:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s a partajat »%2$s« cu tine și vrea să adauge",
- "»%s« added a note to a file shared with you" : "%s« a adaugat un comentariu la un fișier partajat cu tine",
- "Open »%s«" : "Deschide »%s«",
- "%1$s shared »%2$s« with you" : "%1$s a partajat »%2$s« cu tine",
- "%1$s shared »%2$s« with you." : "%1$sa partajat »%2$s« cu tine.",
- "Click the button below to open it." : "Apasă pe butonul de jos pentru a deschide.",
"File is currently busy, please try again later" : "Fișierul este blocat momentan, încercați din nou mai târziu",
- "Cannot download file" : "Fișierul nu se poate descărca",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asigurați-vă că fișierul \".ocdata\" există în rădăcina directorului de date."
+ "Cannot download file" : "Fișierul nu se poate descărca"
},
"nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));");
diff --git a/lib/l10n/ro.json b/lib/l10n/ro.json
index ef944c78e33..52618242974 100644
--- a/lib/l10n/ro.json
+++ b/lib/l10n/ro.json
@@ -233,20 +233,7 @@
"Generate headline" : "Generează titlu",
"Summarizes text by reducing its length without losing key information." : "Rezumă textul prin reducerea lungimii acestuia, fără a pierde informațiile cheie.",
"Extracts topics from a text and outputs them separated by commas." : "Extrage subiecte din text și le furnizează separate prin virgulă.",
- "Education Edition" : "Ediția pentru educație",
- "File name is a reserved word" : "Numele fișierului este un cuvânt rezervat",
- "File name contains at least one invalid character" : "Numele fișierului conține cel puțin un caracter invalid",
- "File name is too long" : "Numele fișierului este prea lung",
- "Users" : "Utilizatori",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s a partajat »%2$s« cu tine și vrea să adauge:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s a partajat »%2$s« cu tine și vrea să adauge",
- "»%s« added a note to a file shared with you" : "%s« a adaugat un comentariu la un fișier partajat cu tine",
- "Open »%s«" : "Deschide »%s«",
- "%1$s shared »%2$s« with you" : "%1$s a partajat »%2$s« cu tine",
- "%1$s shared »%2$s« with you." : "%1$sa partajat »%2$s« cu tine.",
- "Click the button below to open it." : "Apasă pe butonul de jos pentru a deschide.",
"File is currently busy, please try again later" : "Fișierul este blocat momentan, încercați din nou mai târziu",
- "Cannot download file" : "Fișierul nu se poate descărca",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Asigurați-vă că fișierul \".ocdata\" există în rădăcina directorului de date."
+ "Cannot download file" : "Fișierul nu se poate descărca"
},"pluralForm" :"nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));"
} \ No newline at end of file
diff --git a/lib/l10n/ru.js b/lib/l10n/ru.js
index fcf8fa5c43f..92337e27833 100644
--- a/lib/l10n/ru.js
+++ b/lib/l10n/ru.js
@@ -38,6 +38,7 @@ OC.L10N.register(
"Server version %s or higher is required." : "Требуется сервер версии %s или выше.",
"Server version %s or lower is required." : "Требуется сервер версии %s или ниже.",
"Logged in account must be an admin, a sub admin or gotten special right to access this setting" : "Для доступа к этой настройке зарегистрированная учетная запись должна быть администратором, субадминистратором или иметь специальные права",
+ "Your current IP address doesn't allow you to perform admin actions" : "Ваш текущий IP-адрес не позволяет вам выполнять действия администратора.",
"Logged in account must be an admin or sub admin" : "Зарегистрированная учетная запись должна быть администратором или субадминистратором",
"Logged in account must be an admin" : "Вошедший в систему пользователь должен быть администратором",
"Wiping of device %s has started" : "Удаление данных с устройства «%s».",
@@ -58,7 +59,11 @@ OC.L10N.register(
"Avatar image is not square" : "Изображение аватара не квадратное",
"Files" : "Файлы",
"View profile" : "Открыть профиль",
+ "same time" : "в то же время",
"_%nh_::_%nh_" : ["%nч","%nч","%nч","%nч"],
+ "_%nm_::_%nm_" : ["%nм","%nм","%n м","%n м"],
+ "%s ahead" : "%s вперёд",
+ "%s behind" : "%s позади",
"Local time: %s" : "Местное время: %s",
"today" : "сегодня",
"tomorrow" : "завтра",
@@ -86,7 +91,10 @@ OC.L10N.register(
"Destination does not match conversion extension" : "Назначение не соответствует расширению преобразования",
"Could not convert file" : "Не удалось преобразовать файл",
"Destination does not exist" : "Пункт назначения не существует",
+ "Destination is not creatable" : "Место назначения не может быть создано",
"Dot files are not allowed" : "Файлы начинающиеся с точки не допускаются",
+ "%1$s (renamed)" : "%1$s (переименовано)",
+ "renamed file" : "переименованный файл",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" это запрещенное имя файла или папки.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" является запрещенным префиксом для имен файлов или папок.",
"\"%1$s\" is not allowed inside a file or folder name." : "\"%1$s\" не допускается указывать имя файла или папки внутри него.",
@@ -97,6 +105,13 @@ OC.L10N.register(
"Invalid path" : "Некорректный путь",
"Failed to create file from template" : "Не удалось создать файл на основе шаблона",
"Templates" : "Шаблоны",
+ "Storage %s cannot be moved" : "Хранилище %s не может быть перемещено",
+ "Moving a share (%s) into a shared folder is not allowed" : "Перемещение общего ресурса (%s) в общую папку запрещено",
+ "Moving a storage (%s) into a shared folder is not allowed" : "Перемещение хранилища (%s) в общую папку запрещено",
+ "Moving a share (%s) into another share (%s) is not allowed" : "Перемещение общего ресурса (%s) в другой общий ресурс (%s) запрещено",
+ "Moving a share (%s) into another storage (%s) is not allowed" : "Перемещение общего ресурса (%s) в другое хранилище (%s) запрещено",
+ "Moving a storage (%s) into a share (%s) is not allowed" : "Перемещение хранилища (%s) в общий ресурс (%s) запрещено",
+ "Moving a storage (%s) into another storage (%s) is not allowed" : "Перемещение хранилища (%s) в другое хранилище (%s) запрещено",
"Path contains invalid segments" : "Путь содержит недопустимые сегменты",
"Filename is a reserved word" : "Имя файла - это зарезервированное слово",
"Filename contains at least one invalid character" : "Имя файла содержит как минимум один недопустимый символ",
@@ -143,6 +158,7 @@ OC.L10N.register(
"Oracle connection could not be established" : "Соединение с Oracle не может быть установлено",
"Oracle Login and/or password not valid" : "Неверный логин и/или пароль Oracle",
"PostgreSQL Login and/or password not valid" : "Неверный логин и/или пароль для PostgreSQL",
+ "Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk!" : "Mac OS X не поддерживается, и %s может работать некорректно на этой платформе. Используйте на свой страх и риск!",
"For the best results, please consider using a GNU/Linux server instead." : "Для достижения наилучших результатов, рассмотрите вариант использования сервера на GNU/Linux.",
"It seems that this %s instance is running on a 32-bit PHP environment and the open_basedir has been configured in php.ini. This will lead to problems with files over 4 GB and is highly discouraged." : "Кажется что экземпляр этого %s работает в 32-битной среде PHP и в php.ini был настроен open_basedir. Это приведёт к проблемам с файлами более 4 ГБ и настоятельно не рекомендуется.",
"Please remove the open_basedir setting within your php.ini or switch to 64-bit PHP." : "Удалите директиву open_basedir из файла php.ini или смените PHP на 64-разрядную сборку.",
@@ -152,13 +168,27 @@ OC.L10N.register(
"Sharing backend %s must implement the interface OCP\\Share_Backend" : "Бэкенд общего доступа %s должен реализовывать интерфейс OCP\\Share_Backend",
"Sharing backend %s not found" : "Механизм предоставления общего доступа %s не найден",
"Sharing backend for %s not found" : "Не найден механизм предоставления общего доступа для %s ",
+ "%1$s shared %2$s with you" : "%1$s поделился(ась) %2$s с вами",
"Open %s" : "Открыть %s",
"%1$s via %2$s" : "%1$s через %2$s",
+ "%1$s shared %2$s with you and wants to add:" : "%1$s поделился(ась) %2$s с вами и хочет добавить:",
+ "%1$s shared %2$s with you and wants to add" : "%1$s поделился(ась) %2$s с вами и хочет добавить",
+ "%s added a note to a file shared with you" : "%s добавил(а) заметку к файлу, которым поделился(ась) с вами",
"Passwords are enforced for link and mail shares" : "Для общих ссылок и почтовых рассылок применяются пароли",
+ "Share recipient is not a valid user" : "Получатель общего ресурса — некорректный пользователь",
+ "Share recipient is not a valid group" : "Получатель общего ресурса — некорректная группа",
+ "Share recipient should be empty" : "Получатель общего ресурса должен быть пустым",
+ "Share recipient should not be empty" : "Получатель общего ресурса не должен быть пустым",
+ "Share recipient is not a valid circle" : "Получатель общего ресурса — некорректный круг",
"Unknown share type" : "Общий доступ неизвестного типа",
+ "Share initiator must be set" : "Должен быть задан инициатор общего ресурса",
"Cannot share with yourself" : "Не могу поделиться с самим собой",
+ "Shared path must be set" : "Должен быть указан путь к общему ресурсу",
+ "Shared path must be either a file or a folder" : "Путь должен указывать на файл или папку",
"You cannot share your root folder" : "Вы не можете предоставить общий доступ к своей корневой папке",
"You are not allowed to share %s" : "Вам не разрешено делиться %s",
+ "Valid permissions are required for sharing" : "Для общего ресурса необходимы корректные права",
+ "File shares cannot have create or delete permissions" : "Для файловых общих ресурсов нельзя задавать права доступа на создание или удаление",
"Cannot increase permissions of %s" : "Не удалось повысить права доступа %s",
"Shares need at least read permissions" : "Общим ресурсам требуются как минимум разрешения на чтение",
"Files cannot be shared with delete permissions" : "Права на удаление файлов не позволяют открывать общий доступ к ним",
@@ -173,6 +203,7 @@ OC.L10N.register(
"Path is already shared with this group" : "Путь уже является общим для этой группы",
"Link sharing is not allowed" : "Обмен ссылками запрещен",
"Public upload is not allowed" : "Публичная загрузка данных запрещена",
+ "You cannot share a folder that contains other shares" : "Нельзя делиться папкой, содержащей другие общие ресурсы",
"Sharing is disabled" : "Общий доступ отключен",
"Sharing is disabled for you" : "Общий доступ для вас отключен",
"Cannot share with the share owner" : "Невозможно поделиться с владельцем общего доступа",
@@ -184,6 +215,7 @@ OC.L10N.register(
"Cannot disable sending the password by Talk without setting a new password" : "Невозможно отключить отправку пароля по телефону без установки нового пароля",
"Share provider does not support accepting" : "Поставщик общего доступа не поддерживает прием",
"Cannot change target of link share" : "Невозможно изменить цель публикации ссылки",
+ "Invalid share recipient" : "Некорректный получатель общего ресурса",
"Group \"%s\" does not exist" : "Группа \"%s\" не существует",
"The requested share does not exist anymore" : "Запрошенный общий ресурс более не существует.",
"The requested share comes from a disabled user" : "Запрос на общий доступ поступает от отключенного пользователя",
@@ -243,6 +275,7 @@ OC.L10N.register(
"A valid Login must be provided" : "Необходимо указать действительный логин для входа в систему",
"Login contains whitespace at the beginning or at the end" : "Имя пользователя содержит пробелы в начале или в конце",
"Login must not consist of dots only" : "Логин не должен состоять только из точек",
+ "Username is too long" : "Имя пользователя слишком длинное",
"Login is invalid because files already exist for this user" : "Логин недействителен, поскольку файлы для этого пользователя уже существуют",
"Account disabled" : "Учетная запись отключена",
"Login canceled by app" : "Вход отменен приложением",
@@ -299,10 +332,19 @@ OC.L10N.register(
"The audio to transcribe" : "Аудио для расшифровки",
"Transcription" : "Транскрипция",
"The transcribed text" : "Расшифрованный текст",
+ "Chat with an agent" : "Чат с агентом",
"Chat message" : "Сообщение в чате",
+ "A chat message to send to the agent." : "Сообщение для отправки агенту",
"Confirmation" : "Подтверждение",
+ "Whether to confirm previously requested actions: 0 for denial and 1 for confirmation." : "Подтвердить ранее запрошенные действия: 0 — отказ, 1 — подтверждение.",
+ "Conversation token" : "Токен беседы",
+ "A token representing the conversation." : "Токен, представляющий беседу.",
"Generated response" : "Сгенерированный ответ",
"The response from the chat model." : "Ответ от модели чата.",
+ "The new conversation token" : "Новый токен беседы",
+ "Send this along with the next interaction." : "Отправьте его при следующем взаимодействии.",
+ "Requested actions by the agent" : "Запрошенные действия от агента",
+ "Actions that the agent would like to carry out in JSON format." : "Действия, которые агент хотел бы выполнить в формате JSON.",
"Context write" : "Контекстная запись",
"Writes text in a given style based on the provided source material." : "Пишет текст в заданном стиле на основе предоставленного исходного материала.",
"Writing style" : "Стиль письма",
@@ -313,18 +355,33 @@ OC.L10N.register(
"The generated text with content from the source material in the given style" : "Сгенерированный текст с содержимым из исходного материала в заданном стиле",
"Emoji generator" : "Генератор Emoji",
"Takes text and generates a representative emoji for it." : "Берет текст и генерирует для него репрезентативный смайлик.",
+ "The text to generate an emoji for" : "Текст для создания эмодзи",
+ "Generated emoji" : "Созданный эмодзи",
+ "The generated emoji based on the input text" : "Эмодзи, созданный на основе введённого текста",
"Generate image" : "Генерировать изображение",
"Generate an image from a text prompt" : "Создайте изображение из текстовой подсказки",
+ "Prompt" : "Подсказка",
"Describe the image you want to generate" : "Опишите изображение, которое вы хотите создать",
"Number of images" : "Количество изображений",
"How many images to generate" : "Сколько изображений генерировать",
"Output images" : "Выходные изображения",
"The generated images" : "Сгенерированные изображения",
+ "Generate speech" : "Сгенерировать речь",
+ "Generate speech from a transcript" : "Сгенерировать речь из транскрипта",
+ "Write transcript that you want the assistant to generate speech from" : "Введите транскрипт, по которому ассистент должен сгенерировать речь",
+ "Output speech" : "Выходное аудио",
+ "The generated speech" : "Сгенерированная речь",
"Free text to text prompt" : "Произвольное преобразование текста в текстовую подсказку",
"Runs an arbitrary prompt through a language model that returns a reply" : "Запускает произвольный запрос с помощью языковой модели, которая возвращает ответ",
"Describe a task that you want the assistant to do or ask a question" : "Опишите задачу, которую вы хотите поручить ассистенту, или задайте вопрос",
"Generated reply" : "Сгенерированный ответ",
"The generated text from the assistant" : "Сгенерированный текст от помощника",
+ "Change Tone" : "Сменить тон",
+ "Change the tone of a piece of text." : "Изменить тон текста",
+ "Write a text that you want the assistant to rewrite in another tone." : "Напишите текст, чтобы ассистент переписал его в другом тоне.",
+ "Desired tone" : "Желаемый тон",
+ "In which tone should your text be rewritten?" : "В каком тоне следует переписать ваш текст?",
+ "The rewritten text in the desired tone, written by the assistant:" : "Переписанный текст в нужном тоне, написанный ассистентом:",
"Chat" : "Разговор",
"Chat with the assistant" : "Пообщайтесь с ассистентом",
"System prompt" : "Системная подсказка",
@@ -333,7 +390,15 @@ OC.L10N.register(
"The history of chat messages before the current message, starting with a message by the user" : "История сообщений в чате до текущего сообщения, начиная с сообщения пользователя",
"Response message" : "Ответное сообщение",
"The generated response as part of the conversation" : "Сгенерированный ответ в ходе беседы",
+ "Chat with tools" : "Чат с инструментами",
+ "Chat with the language model with tool calling support." : "Чат с языковой моделью с поддержкой вызова инструментов.",
+ "Tool message" : "Сообщение инструмента",
+ "The result of tool calls in the last interaction" : "Результат вызова инструментов в последнем взаимодействии",
+ "Available tools" : "Доступные инструменты",
+ "The available tools in JSON format" : "Доступные инструменты в формате JSON",
"The response from the chat model" : "Ответ от чат-модели",
+ "Tool calls" : "Вызовы инструментов",
+ "Tools call instructions from the model in JSON format" : "Инструкции по вызову инструментов от модели в формате JSON",
"Formalize text" : "Формализовать текст",
"Takes a text and makes it sound more formal" : "Берется текст и делает его звучание более формальным",
"Write a text that you want the assistant to formalize" : "Напишите текст, который вы хотите, чтобы ассистент оформил официально",
@@ -344,7 +409,12 @@ OC.L10N.register(
"Original text" : "Оригинальный текст",
"The original text to generate a headline for" : "Исходный текст для создания заголовка для",
"The generated headline" : "Сгенерированный заголовок",
+ "Proofread" : "Проверка правописания",
+ "Proofreads a text and lists corrections" : "Проверяет текст и показывает исправления",
"Text" : "Текст",
+ "The text to proofread" : "Текст для проверки",
+ "Corrections" : "Исправления",
+ "The corrections that should be made in your text" : "Исправления, которые следует внести в ваш текст",
"Reformulate text" : "Переформулировать текст",
"Takes a text and reformulates it" : "Берет текст и переформулирует его",
"Write a text that you want the assistant to reformulate" : "Напишите текст, который вы хотите, чтобы ассистент переформулировал",
@@ -380,20 +450,8 @@ OC.L10N.register(
"Generate headline" : "Сгенерировать заголовок",
"Summarizes text by reducing its length without losing key information." : "Обобщает текст, сокращая его длину без потери ключевой информации.",
"Extracts topics from a text and outputs them separated by commas." : "Извлекает темы из текста и выводит их через запятую.",
- "Education Edition" : "Набор приложений для образовательных учреждений",
- "File name is a reserved word" : "Имя файла является зарезервированным словом",
- "File name contains at least one invalid character" : "Имя файла содержит по крайней мере один недопустимый символ",
- "File name is too long" : "Имя файла слишком длинное.",
- "Users" : "Пользователи",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s предоставил(а) вам доступ к «%2$s» и хочет добавить:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s предоставил(а) вам доступ к «%2$s» и хочет добавить",
- "»%s« added a note to a file shared with you" : "%s добавил(а) примечание к файлу, к которому вам открыт доступ",
- "Open »%s«" : "Открыть «%s»",
- "%1$s shared »%2$s« with you" : "%1$s предоставил(а) вам доступ к «%2$s»",
- "%1$s shared »%2$s« with you." : "%1$s предоставил(а) вам доступ к «%2$s».",
- "Click the button below to open it." : "Нажмите расположенную ниже кнопку для перехода к полученному общему ресурсу.",
"File is currently busy, please try again later" : "Файл в данный момент используется, повторите попытку позже.",
"Cannot download file" : "Не удалось скачать файл",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Убедитесь, что в корне каталога данных присутствует файл «.ocdata»."
+ "Login is too long" : "Имя пользователя слишком длинное"
},
"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/lib/l10n/ru.json b/lib/l10n/ru.json
index ccf04f6ee23..590ad80b5b7 100644
--- a/lib/l10n/ru.json
+++ b/lib/l10n/ru.json
@@ -36,6 +36,7 @@
"Server version %s or higher is required." : "Требуется сервер версии %s или выше.",
"Server version %s or lower is required." : "Требуется сервер версии %s или ниже.",
"Logged in account must be an admin, a sub admin or gotten special right to access this setting" : "Для доступа к этой настройке зарегистрированная учетная запись должна быть администратором, субадминистратором или иметь специальные права",
+ "Your current IP address doesn't allow you to perform admin actions" : "Ваш текущий IP-адрес не позволяет вам выполнять действия администратора.",
"Logged in account must be an admin or sub admin" : "Зарегистрированная учетная запись должна быть администратором или субадминистратором",
"Logged in account must be an admin" : "Вошедший в систему пользователь должен быть администратором",
"Wiping of device %s has started" : "Удаление данных с устройства «%s».",
@@ -56,7 +57,11 @@
"Avatar image is not square" : "Изображение аватара не квадратное",
"Files" : "Файлы",
"View profile" : "Открыть профиль",
+ "same time" : "в то же время",
"_%nh_::_%nh_" : ["%nч","%nч","%nч","%nч"],
+ "_%nm_::_%nm_" : ["%nм","%nм","%n м","%n м"],
+ "%s ahead" : "%s вперёд",
+ "%s behind" : "%s позади",
"Local time: %s" : "Местное время: %s",
"today" : "сегодня",
"tomorrow" : "завтра",
@@ -84,7 +89,10 @@
"Destination does not match conversion extension" : "Назначение не соответствует расширению преобразования",
"Could not convert file" : "Не удалось преобразовать файл",
"Destination does not exist" : "Пункт назначения не существует",
+ "Destination is not creatable" : "Место назначения не может быть создано",
"Dot files are not allowed" : "Файлы начинающиеся с точки не допускаются",
+ "%1$s (renamed)" : "%1$s (переименовано)",
+ "renamed file" : "переименованный файл",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" это запрещенное имя файла или папки.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" является запрещенным префиксом для имен файлов или папок.",
"\"%1$s\" is not allowed inside a file or folder name." : "\"%1$s\" не допускается указывать имя файла или папки внутри него.",
@@ -95,6 +103,13 @@
"Invalid path" : "Некорректный путь",
"Failed to create file from template" : "Не удалось создать файл на основе шаблона",
"Templates" : "Шаблоны",
+ "Storage %s cannot be moved" : "Хранилище %s не может быть перемещено",
+ "Moving a share (%s) into a shared folder is not allowed" : "Перемещение общего ресурса (%s) в общую папку запрещено",
+ "Moving a storage (%s) into a shared folder is not allowed" : "Перемещение хранилища (%s) в общую папку запрещено",
+ "Moving a share (%s) into another share (%s) is not allowed" : "Перемещение общего ресурса (%s) в другой общий ресурс (%s) запрещено",
+ "Moving a share (%s) into another storage (%s) is not allowed" : "Перемещение общего ресурса (%s) в другое хранилище (%s) запрещено",
+ "Moving a storage (%s) into a share (%s) is not allowed" : "Перемещение хранилища (%s) в общий ресурс (%s) запрещено",
+ "Moving a storage (%s) into another storage (%s) is not allowed" : "Перемещение хранилища (%s) в другое хранилище (%s) запрещено",
"Path contains invalid segments" : "Путь содержит недопустимые сегменты",
"Filename is a reserved word" : "Имя файла - это зарезервированное слово",
"Filename contains at least one invalid character" : "Имя файла содержит как минимум один недопустимый символ",
@@ -141,6 +156,7 @@
"Oracle connection could not be established" : "Соединение с Oracle не может быть установлено",
"Oracle Login and/or password not valid" : "Неверный логин и/или пароль Oracle",
"PostgreSQL Login and/or password not valid" : "Неверный логин и/или пароль для PostgreSQL",
+ "Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk!" : "Mac OS X не поддерживается, и %s может работать некорректно на этой платформе. Используйте на свой страх и риск!",
"For the best results, please consider using a GNU/Linux server instead." : "Для достижения наилучших результатов, рассмотрите вариант использования сервера на GNU/Linux.",
"It seems that this %s instance is running on a 32-bit PHP environment and the open_basedir has been configured in php.ini. This will lead to problems with files over 4 GB and is highly discouraged." : "Кажется что экземпляр этого %s работает в 32-битной среде PHP и в php.ini был настроен open_basedir. Это приведёт к проблемам с файлами более 4 ГБ и настоятельно не рекомендуется.",
"Please remove the open_basedir setting within your php.ini or switch to 64-bit PHP." : "Удалите директиву open_basedir из файла php.ini или смените PHP на 64-разрядную сборку.",
@@ -150,13 +166,27 @@
"Sharing backend %s must implement the interface OCP\\Share_Backend" : "Бэкенд общего доступа %s должен реализовывать интерфейс OCP\\Share_Backend",
"Sharing backend %s not found" : "Механизм предоставления общего доступа %s не найден",
"Sharing backend for %s not found" : "Не найден механизм предоставления общего доступа для %s ",
+ "%1$s shared %2$s with you" : "%1$s поделился(ась) %2$s с вами",
"Open %s" : "Открыть %s",
"%1$s via %2$s" : "%1$s через %2$s",
+ "%1$s shared %2$s with you and wants to add:" : "%1$s поделился(ась) %2$s с вами и хочет добавить:",
+ "%1$s shared %2$s with you and wants to add" : "%1$s поделился(ась) %2$s с вами и хочет добавить",
+ "%s added a note to a file shared with you" : "%s добавил(а) заметку к файлу, которым поделился(ась) с вами",
"Passwords are enforced for link and mail shares" : "Для общих ссылок и почтовых рассылок применяются пароли",
+ "Share recipient is not a valid user" : "Получатель общего ресурса — некорректный пользователь",
+ "Share recipient is not a valid group" : "Получатель общего ресурса — некорректная группа",
+ "Share recipient should be empty" : "Получатель общего ресурса должен быть пустым",
+ "Share recipient should not be empty" : "Получатель общего ресурса не должен быть пустым",
+ "Share recipient is not a valid circle" : "Получатель общего ресурса — некорректный круг",
"Unknown share type" : "Общий доступ неизвестного типа",
+ "Share initiator must be set" : "Должен быть задан инициатор общего ресурса",
"Cannot share with yourself" : "Не могу поделиться с самим собой",
+ "Shared path must be set" : "Должен быть указан путь к общему ресурсу",
+ "Shared path must be either a file or a folder" : "Путь должен указывать на файл или папку",
"You cannot share your root folder" : "Вы не можете предоставить общий доступ к своей корневой папке",
"You are not allowed to share %s" : "Вам не разрешено делиться %s",
+ "Valid permissions are required for sharing" : "Для общего ресурса необходимы корректные права",
+ "File shares cannot have create or delete permissions" : "Для файловых общих ресурсов нельзя задавать права доступа на создание или удаление",
"Cannot increase permissions of %s" : "Не удалось повысить права доступа %s",
"Shares need at least read permissions" : "Общим ресурсам требуются как минимум разрешения на чтение",
"Files cannot be shared with delete permissions" : "Права на удаление файлов не позволяют открывать общий доступ к ним",
@@ -171,6 +201,7 @@
"Path is already shared with this group" : "Путь уже является общим для этой группы",
"Link sharing is not allowed" : "Обмен ссылками запрещен",
"Public upload is not allowed" : "Публичная загрузка данных запрещена",
+ "You cannot share a folder that contains other shares" : "Нельзя делиться папкой, содержащей другие общие ресурсы",
"Sharing is disabled" : "Общий доступ отключен",
"Sharing is disabled for you" : "Общий доступ для вас отключен",
"Cannot share with the share owner" : "Невозможно поделиться с владельцем общего доступа",
@@ -182,6 +213,7 @@
"Cannot disable sending the password by Talk without setting a new password" : "Невозможно отключить отправку пароля по телефону без установки нового пароля",
"Share provider does not support accepting" : "Поставщик общего доступа не поддерживает прием",
"Cannot change target of link share" : "Невозможно изменить цель публикации ссылки",
+ "Invalid share recipient" : "Некорректный получатель общего ресурса",
"Group \"%s\" does not exist" : "Группа \"%s\" не существует",
"The requested share does not exist anymore" : "Запрошенный общий ресурс более не существует.",
"The requested share comes from a disabled user" : "Запрос на общий доступ поступает от отключенного пользователя",
@@ -241,6 +273,7 @@
"A valid Login must be provided" : "Необходимо указать действительный логин для входа в систему",
"Login contains whitespace at the beginning or at the end" : "Имя пользователя содержит пробелы в начале или в конце",
"Login must not consist of dots only" : "Логин не должен состоять только из точек",
+ "Username is too long" : "Имя пользователя слишком длинное",
"Login is invalid because files already exist for this user" : "Логин недействителен, поскольку файлы для этого пользователя уже существуют",
"Account disabled" : "Учетная запись отключена",
"Login canceled by app" : "Вход отменен приложением",
@@ -297,10 +330,19 @@
"The audio to transcribe" : "Аудио для расшифровки",
"Transcription" : "Транскрипция",
"The transcribed text" : "Расшифрованный текст",
+ "Chat with an agent" : "Чат с агентом",
"Chat message" : "Сообщение в чате",
+ "A chat message to send to the agent." : "Сообщение для отправки агенту",
"Confirmation" : "Подтверждение",
+ "Whether to confirm previously requested actions: 0 for denial and 1 for confirmation." : "Подтвердить ранее запрошенные действия: 0 — отказ, 1 — подтверждение.",
+ "Conversation token" : "Токен беседы",
+ "A token representing the conversation." : "Токен, представляющий беседу.",
"Generated response" : "Сгенерированный ответ",
"The response from the chat model." : "Ответ от модели чата.",
+ "The new conversation token" : "Новый токен беседы",
+ "Send this along with the next interaction." : "Отправьте его при следующем взаимодействии.",
+ "Requested actions by the agent" : "Запрошенные действия от агента",
+ "Actions that the agent would like to carry out in JSON format." : "Действия, которые агент хотел бы выполнить в формате JSON.",
"Context write" : "Контекстная запись",
"Writes text in a given style based on the provided source material." : "Пишет текст в заданном стиле на основе предоставленного исходного материала.",
"Writing style" : "Стиль письма",
@@ -311,18 +353,33 @@
"The generated text with content from the source material in the given style" : "Сгенерированный текст с содержимым из исходного материала в заданном стиле",
"Emoji generator" : "Генератор Emoji",
"Takes text and generates a representative emoji for it." : "Берет текст и генерирует для него репрезентативный смайлик.",
+ "The text to generate an emoji for" : "Текст для создания эмодзи",
+ "Generated emoji" : "Созданный эмодзи",
+ "The generated emoji based on the input text" : "Эмодзи, созданный на основе введённого текста",
"Generate image" : "Генерировать изображение",
"Generate an image from a text prompt" : "Создайте изображение из текстовой подсказки",
+ "Prompt" : "Подсказка",
"Describe the image you want to generate" : "Опишите изображение, которое вы хотите создать",
"Number of images" : "Количество изображений",
"How many images to generate" : "Сколько изображений генерировать",
"Output images" : "Выходные изображения",
"The generated images" : "Сгенерированные изображения",
+ "Generate speech" : "Сгенерировать речь",
+ "Generate speech from a transcript" : "Сгенерировать речь из транскрипта",
+ "Write transcript that you want the assistant to generate speech from" : "Введите транскрипт, по которому ассистент должен сгенерировать речь",
+ "Output speech" : "Выходное аудио",
+ "The generated speech" : "Сгенерированная речь",
"Free text to text prompt" : "Произвольное преобразование текста в текстовую подсказку",
"Runs an arbitrary prompt through a language model that returns a reply" : "Запускает произвольный запрос с помощью языковой модели, которая возвращает ответ",
"Describe a task that you want the assistant to do or ask a question" : "Опишите задачу, которую вы хотите поручить ассистенту, или задайте вопрос",
"Generated reply" : "Сгенерированный ответ",
"The generated text from the assistant" : "Сгенерированный текст от помощника",
+ "Change Tone" : "Сменить тон",
+ "Change the tone of a piece of text." : "Изменить тон текста",
+ "Write a text that you want the assistant to rewrite in another tone." : "Напишите текст, чтобы ассистент переписал его в другом тоне.",
+ "Desired tone" : "Желаемый тон",
+ "In which tone should your text be rewritten?" : "В каком тоне следует переписать ваш текст?",
+ "The rewritten text in the desired tone, written by the assistant:" : "Переписанный текст в нужном тоне, написанный ассистентом:",
"Chat" : "Разговор",
"Chat with the assistant" : "Пообщайтесь с ассистентом",
"System prompt" : "Системная подсказка",
@@ -331,7 +388,15 @@
"The history of chat messages before the current message, starting with a message by the user" : "История сообщений в чате до текущего сообщения, начиная с сообщения пользователя",
"Response message" : "Ответное сообщение",
"The generated response as part of the conversation" : "Сгенерированный ответ в ходе беседы",
+ "Chat with tools" : "Чат с инструментами",
+ "Chat with the language model with tool calling support." : "Чат с языковой моделью с поддержкой вызова инструментов.",
+ "Tool message" : "Сообщение инструмента",
+ "The result of tool calls in the last interaction" : "Результат вызова инструментов в последнем взаимодействии",
+ "Available tools" : "Доступные инструменты",
+ "The available tools in JSON format" : "Доступные инструменты в формате JSON",
"The response from the chat model" : "Ответ от чат-модели",
+ "Tool calls" : "Вызовы инструментов",
+ "Tools call instructions from the model in JSON format" : "Инструкции по вызову инструментов от модели в формате JSON",
"Formalize text" : "Формализовать текст",
"Takes a text and makes it sound more formal" : "Берется текст и делает его звучание более формальным",
"Write a text that you want the assistant to formalize" : "Напишите текст, который вы хотите, чтобы ассистент оформил официально",
@@ -342,7 +407,12 @@
"Original text" : "Оригинальный текст",
"The original text to generate a headline for" : "Исходный текст для создания заголовка для",
"The generated headline" : "Сгенерированный заголовок",
+ "Proofread" : "Проверка правописания",
+ "Proofreads a text and lists corrections" : "Проверяет текст и показывает исправления",
"Text" : "Текст",
+ "The text to proofread" : "Текст для проверки",
+ "Corrections" : "Исправления",
+ "The corrections that should be made in your text" : "Исправления, которые следует внести в ваш текст",
"Reformulate text" : "Переформулировать текст",
"Takes a text and reformulates it" : "Берет текст и переформулирует его",
"Write a text that you want the assistant to reformulate" : "Напишите текст, который вы хотите, чтобы ассистент переформулировал",
@@ -378,20 +448,8 @@
"Generate headline" : "Сгенерировать заголовок",
"Summarizes text by reducing its length without losing key information." : "Обобщает текст, сокращая его длину без потери ключевой информации.",
"Extracts topics from a text and outputs them separated by commas." : "Извлекает темы из текста и выводит их через запятую.",
- "Education Edition" : "Набор приложений для образовательных учреждений",
- "File name is a reserved word" : "Имя файла является зарезервированным словом",
- "File name contains at least one invalid character" : "Имя файла содержит по крайней мере один недопустимый символ",
- "File name is too long" : "Имя файла слишком длинное.",
- "Users" : "Пользователи",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s предоставил(а) вам доступ к «%2$s» и хочет добавить:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s предоставил(а) вам доступ к «%2$s» и хочет добавить",
- "»%s« added a note to a file shared with you" : "%s добавил(а) примечание к файлу, к которому вам открыт доступ",
- "Open »%s«" : "Открыть «%s»",
- "%1$s shared »%2$s« with you" : "%1$s предоставил(а) вам доступ к «%2$s»",
- "%1$s shared »%2$s« with you." : "%1$s предоставил(а) вам доступ к «%2$s».",
- "Click the button below to open it." : "Нажмите расположенную ниже кнопку для перехода к полученному общему ресурсу.",
"File is currently busy, please try again later" : "Файл в данный момент используется, повторите попытку позже.",
"Cannot download file" : "Не удалось скачать файл",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Убедитесь, что в корне каталога данных присутствует файл «.ocdata»."
+ "Login is too long" : "Имя пользователя слишком длинное"
},"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);"
} \ No newline at end of file
diff --git a/lib/l10n/sc.js b/lib/l10n/sc.js
index 309cad1a78c..62751349b35 100644
--- a/lib/l10n/sc.js
+++ b/lib/l10n/sc.js
@@ -201,19 +201,6 @@ OC.L10N.register(
"Translate" : "Borta",
"Result" : "Resurtadu",
"Generate headline" : "Gènera unu tìtulu",
- "Education Edition" : "Editzione didàtica",
- "File name is a reserved word" : "Su nùmene de s'archìviu est unu faeddu riservadu",
- "File name contains at least one invalid character" : "Su nùmene de s'archìviu cuntenet a su mancu unu caràtere imbàlidu",
- "File name is too long" : "Su nùmene de s'archìviu est tropu longu",
- "Users" : "Utentes",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s at cumpartzidu »%2$s« cun tegus e bolet agiùnghere:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s at cumpartzidu »%2$s« cun tegus e bolet agiùnghere",
- "»%s« added a note to a file shared with you" : "»%s« at agiuntu una nota a un'archìviu cumpartzidu cun tegus",
- "Open »%s«" : "Aberi »%s«",
- "%1$s shared »%2$s« with you" : "%1$s at cumpartzidu »%2$s cun tegus",
- "%1$s shared »%2$s« with you." : "%1$s at cumpartzidu »%2$s cun tegus.",
- "Click the button below to open it." : "Incarca su butone a suta pro dd'abèrrere.",
- "File is currently busy, please try again later" : "Pro immoe s'archìviu est impreadu, torra a proare a coa",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Assegura•ti chi in sa cartella de datos de orìgine nche siat un'archìviu cun nùmene \".ocdata\"."
+ "File is currently busy, please try again later" : "Pro immoe s'archìviu est impreadu, torra a proare a coa"
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/sc.json b/lib/l10n/sc.json
index 890da5262d5..e955b950eeb 100644
--- a/lib/l10n/sc.json
+++ b/lib/l10n/sc.json
@@ -199,19 +199,6 @@
"Translate" : "Borta",
"Result" : "Resurtadu",
"Generate headline" : "Gènera unu tìtulu",
- "Education Edition" : "Editzione didàtica",
- "File name is a reserved word" : "Su nùmene de s'archìviu est unu faeddu riservadu",
- "File name contains at least one invalid character" : "Su nùmene de s'archìviu cuntenet a su mancu unu caràtere imbàlidu",
- "File name is too long" : "Su nùmene de s'archìviu est tropu longu",
- "Users" : "Utentes",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s at cumpartzidu »%2$s« cun tegus e bolet agiùnghere:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s at cumpartzidu »%2$s« cun tegus e bolet agiùnghere",
- "»%s« added a note to a file shared with you" : "»%s« at agiuntu una nota a un'archìviu cumpartzidu cun tegus",
- "Open »%s«" : "Aberi »%s«",
- "%1$s shared »%2$s« with you" : "%1$s at cumpartzidu »%2$s cun tegus",
- "%1$s shared »%2$s« with you." : "%1$s at cumpartzidu »%2$s cun tegus.",
- "Click the button below to open it." : "Incarca su butone a suta pro dd'abèrrere.",
- "File is currently busy, please try again later" : "Pro immoe s'archìviu est impreadu, torra a proare a coa",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Assegura•ti chi in sa cartella de datos de orìgine nche siat un'archìviu cun nùmene \".ocdata\"."
+ "File is currently busy, please try again later" : "Pro immoe s'archìviu est impreadu, torra a proare a coa"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/si.js b/lib/l10n/si.js
index 30bcd4d5772..4c582530b60 100644
--- a/lib/l10n/si.js
+++ b/lib/l10n/si.js
@@ -63,8 +63,6 @@ OC.L10N.register(
"November" : "නොවැම්බර්",
"December" : "දෙසැම්බර්",
"Summary" : "සාරාංශය",
- "Translate" : "පරිවර්තනය",
- "File name is too long" : "ගොනුවේ නම දිග වැඩිය",
- "Users" : "පරිශීලකයින්"
+ "Translate" : "පරිවර්තනය"
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/si.json b/lib/l10n/si.json
index 87e5644d70b..79483e78d71 100644
--- a/lib/l10n/si.json
+++ b/lib/l10n/si.json
@@ -61,8 +61,6 @@
"November" : "නොවැම්බර්",
"December" : "දෙසැම්බර්",
"Summary" : "සාරාංශය",
- "Translate" : "පරිවර්තනය",
- "File name is too long" : "ගොනුවේ නම දිග වැඩිය",
- "Users" : "පරිශීලකයින්"
+ "Translate" : "පරිවර්තනය"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/sk.js b/lib/l10n/sk.js
index 5e4220e4f19..953d6868b4f 100644
--- a/lib/l10n/sk.js
+++ b/lib/l10n/sk.js
@@ -441,20 +441,7 @@ OC.L10N.register(
"Generate headline" : "Generovať nadpis",
"Summarizes text by reducing its length without losing key information." : "Zhrňuje text tým, že znižuje jeho dĺžku bez straty kľúčových informácií.",
"Extracts topics from a text and outputs them separated by commas." : "Extrahuje témy z textu a vypisuje ich oddelené čiarkami.",
- "Education Edition" : "Edícia pre výuku",
- "File name is a reserved word" : "Názov súboru je rezervované slovo.",
- "File name contains at least one invalid character" : "Názov súboru obsahuje nepovolené znaky.",
- "File name is too long" : "Meno súboru je veľmi dlhé.",
- "Users" : "Používatelia",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s vám sprístupnil »%2$s« s poznámkou:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s vám sprístupnil »%2$s« s poznámkou",
- "»%s« added a note to a file shared with you" : "»%s« pridal poznámku k súboru ktorý s Vami zdieľa",
- "Open »%s«" : "Otvoriť »%s«",
- "%1$s shared »%2$s« with you" : "%1$s vám sprístupnil »%2$s«",
- "%1$s shared »%2$s« with you." : "%1$s vám sprístupnil »%2$s«.",
- "Click the button below to open it." : "Pre otvorenie klienta kliknite na tlačítko nižšie.",
"File is currently busy, please try again later" : "Súbor sa práve používa, skúste prosím neskôr",
- "Cannot download file" : "Nemožno stiahnuť súbor",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Uistite sa, že v koreňovom adresári sa nachádza súbor s názvom \".ocdata\"."
+ "Cannot download file" : "Nemožno stiahnuť súbor"
},
"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/lib/l10n/sk.json b/lib/l10n/sk.json
index a5b8b58ccd0..9e7039f84f6 100644
--- a/lib/l10n/sk.json
+++ b/lib/l10n/sk.json
@@ -439,20 +439,7 @@
"Generate headline" : "Generovať nadpis",
"Summarizes text by reducing its length without losing key information." : "Zhrňuje text tým, že znižuje jeho dĺžku bez straty kľúčových informácií.",
"Extracts topics from a text and outputs them separated by commas." : "Extrahuje témy z textu a vypisuje ich oddelené čiarkami.",
- "Education Edition" : "Edícia pre výuku",
- "File name is a reserved word" : "Názov súboru je rezervované slovo.",
- "File name contains at least one invalid character" : "Názov súboru obsahuje nepovolené znaky.",
- "File name is too long" : "Meno súboru je veľmi dlhé.",
- "Users" : "Používatelia",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s vám sprístupnil »%2$s« s poznámkou:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s vám sprístupnil »%2$s« s poznámkou",
- "»%s« added a note to a file shared with you" : "»%s« pridal poznámku k súboru ktorý s Vami zdieľa",
- "Open »%s«" : "Otvoriť »%s«",
- "%1$s shared »%2$s« with you" : "%1$s vám sprístupnil »%2$s«",
- "%1$s shared »%2$s« with you." : "%1$s vám sprístupnil »%2$s«.",
- "Click the button below to open it." : "Pre otvorenie klienta kliknite na tlačítko nižšie.",
"File is currently busy, please try again later" : "Súbor sa práve používa, skúste prosím neskôr",
- "Cannot download file" : "Nemožno stiahnuť súbor",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Uistite sa, že v koreňovom adresári sa nachádza súbor s názvom \".ocdata\"."
+ "Cannot download file" : "Nemožno stiahnuť súbor"
},"pluralForm" :"nplurals=4; plural=(n % 1 == 0 && n == 1 ? 0 : n % 1 == 0 && n >= 2 && n <= 4 ? 1 : n % 1 != 0 ? 2: 3);"
} \ No newline at end of file
diff --git a/lib/l10n/sl.js b/lib/l10n/sl.js
index 8677c681bcc..0fc382e07cd 100644
--- a/lib/l10n/sl.js
+++ b/lib/l10n/sl.js
@@ -75,6 +75,7 @@ OC.L10N.register(
"Empty file" : "Prazna datoteka",
"Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "Modul z ID: %s ne obstaja. Omogočite ga med nastavitvami, ali pa stopite v stik s skrbnikom sistema.",
"Dot files are not allowed" : "Skrite datoteke niso dovoljene",
+ "Filenames must not end with \"%1$s\"." : "Imena datotek se naj ne končajo s \"%1$s\".",
"File already exists" : "Datoteka že obstaja",
"Invalid path" : "Neveljavna pot",
"Failed to create file from template" : "Ustvarjanje datoteke iz predloge je spodletelo",
@@ -229,20 +230,7 @@ OC.L10N.register(
"Translate" : "Prevedi",
"Target language" : "Ciljni jezik",
"Result" : "Rezultat",
- "Education Edition" : "Izobraževalna različica",
- "File name is a reserved word" : "Ime datoteke je zadržana beseda",
- "File name contains at least one invalid character" : "Ime datoteke vsebuje vsaj en nedovoljen znak.",
- "File name is too long" : "Ime datoteke je predolgo",
- "Users" : "Uporabniki",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s vam omogoča souporabo »%2$s« in želi dodati:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s vam omogoča souporabo »%2$s« in želi dodati",
- "»%s« added a note to a file shared with you" : "»%s« doda opombo k datoteki v souporabi",
- "Open »%s«" : "Odpri »%s«",
- "%1$s shared »%2$s« with you" : "%1$s vam omogoča souporabo »%2$s«",
- "%1$s shared »%2$s« with you." : "%1$s vam omogoča souporabo »%2$s«.",
- "Click the button below to open it." : "Kliknite na gumb za odpiranje.",
"File is currently busy, please try again later" : "Datoteka je trenutno v uporabi. Poskusite znova kasneje.",
- "Cannot download file" : "Datoteke ni mogoče prejeti",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Prepričajte se, da je datoteka ».ocdata« v korenu podatkovne mape."
+ "Cannot download file" : "Datoteke ni mogoče prejeti"
},
"nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);");
diff --git a/lib/l10n/sl.json b/lib/l10n/sl.json
index 39c6044b937..ff70b64f2c8 100644
--- a/lib/l10n/sl.json
+++ b/lib/l10n/sl.json
@@ -73,6 +73,7 @@
"Empty file" : "Prazna datoteka",
"Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "Modul z ID: %s ne obstaja. Omogočite ga med nastavitvami, ali pa stopite v stik s skrbnikom sistema.",
"Dot files are not allowed" : "Skrite datoteke niso dovoljene",
+ "Filenames must not end with \"%1$s\"." : "Imena datotek se naj ne končajo s \"%1$s\".",
"File already exists" : "Datoteka že obstaja",
"Invalid path" : "Neveljavna pot",
"Failed to create file from template" : "Ustvarjanje datoteke iz predloge je spodletelo",
@@ -227,20 +228,7 @@
"Translate" : "Prevedi",
"Target language" : "Ciljni jezik",
"Result" : "Rezultat",
- "Education Edition" : "Izobraževalna različica",
- "File name is a reserved word" : "Ime datoteke je zadržana beseda",
- "File name contains at least one invalid character" : "Ime datoteke vsebuje vsaj en nedovoljen znak.",
- "File name is too long" : "Ime datoteke je predolgo",
- "Users" : "Uporabniki",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s vam omogoča souporabo »%2$s« in želi dodati:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s vam omogoča souporabo »%2$s« in želi dodati",
- "»%s« added a note to a file shared with you" : "»%s« doda opombo k datoteki v souporabi",
- "Open »%s«" : "Odpri »%s«",
- "%1$s shared »%2$s« with you" : "%1$s vam omogoča souporabo »%2$s«",
- "%1$s shared »%2$s« with you." : "%1$s vam omogoča souporabo »%2$s«.",
- "Click the button below to open it." : "Kliknite na gumb za odpiranje.",
"File is currently busy, please try again later" : "Datoteka je trenutno v uporabi. Poskusite znova kasneje.",
- "Cannot download file" : "Datoteke ni mogoče prejeti",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Prepričajte se, da je datoteka ».ocdata« v korenu podatkovne mape."
+ "Cannot download file" : "Datoteke ni mogoče prejeti"
},"pluralForm" :"nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);"
} \ No newline at end of file
diff --git a/lib/l10n/sq.js b/lib/l10n/sq.js
index 802ea4a6cdc..88cd173e587 100644
--- a/lib/l10n/sq.js
+++ b/lib/l10n/sq.js
@@ -140,14 +140,6 @@ OC.L10N.register(
"Summary" : "Përmbledhje",
"Translate" : "Përkthe",
"Result" : "Rezultatet",
- "Education Edition" : "Variant Edukativ",
- "File name is a reserved word" : "Emri i kartelës është një emër i rezervuar",
- "File name contains at least one invalid character" : "Emri i kartelës përmban të paktën një shenjë të pavlefshme",
- "File name is too long" : "Emri i kartelës është shumë i gjatë",
- "Users" : "Përdorues",
- "Open »%s«" : "Hap»1 %s«",
- "Click the button below to open it." : "Kliko butonin më poshtë për të hapur atë.",
- "File is currently busy, please try again later" : "Kartela tani është e zënë, ju lutemi, riprovoni më vonë.",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Sigurohu që ekziston një skedar i quajtur \".ocdata\" në rrënjën e direktorisë së të dhënave."
+ "File is currently busy, please try again later" : "Kartela tani është e zënë, ju lutemi, riprovoni më vonë."
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/sq.json b/lib/l10n/sq.json
index 8a0916ab53d..5bd5c701aba 100644
--- a/lib/l10n/sq.json
+++ b/lib/l10n/sq.json
@@ -138,14 +138,6 @@
"Summary" : "Përmbledhje",
"Translate" : "Përkthe",
"Result" : "Rezultatet",
- "Education Edition" : "Variant Edukativ",
- "File name is a reserved word" : "Emri i kartelës është një emër i rezervuar",
- "File name contains at least one invalid character" : "Emri i kartelës përmban të paktën një shenjë të pavlefshme",
- "File name is too long" : "Emri i kartelës është shumë i gjatë",
- "Users" : "Përdorues",
- "Open »%s«" : "Hap»1 %s«",
- "Click the button below to open it." : "Kliko butonin më poshtë për të hapur atë.",
- "File is currently busy, please try again later" : "Kartela tani është e zënë, ju lutemi, riprovoni më vonë.",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Sigurohu që ekziston një skedar i quajtur \".ocdata\" në rrënjën e direktorisë së të dhënave."
+ "File is currently busy, please try again later" : "Kartela tani është e zënë, ju lutemi, riprovoni më vonë."
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/sr.js b/lib/l10n/sr.js
index 187721eeb2a..bea3ea369a6 100644
--- a/lib/l10n/sr.js
+++ b/lib/l10n/sr.js
@@ -93,6 +93,8 @@ OC.L10N.register(
"Destination does not exist" : "Одредиште не постоји",
"Destination is not creatable" : "Одредиште не може да се креира",
"Dot files are not allowed" : "Фајлови са почетном тачком нису дозвољени",
+ "%1$s (renamed)" : "%1$s (преименован)",
+ "renamed file" : "преименован фајл",
"\"%1$s\" is a forbidden file or folder name." : "„%1$s” је забрањено име фајла или фолдера.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "„%1$s” је забрањени префикс имена фајла или фолдера.",
"\"%1$s\" is not allowed inside a file or folder name." : "„%1$s” није дозвољено у имену фајла или фолдера.",
@@ -273,7 +275,7 @@ OC.L10N.register(
"A valid Login must be provided" : "Морате да унесете исправно име за пријаву",
"Login contains whitespace at the beginning or at the end" : "Име за пријаву садржи белине на почетку или на крају",
"Login must not consist of dots only" : "Име за пријаву не може да се састоји само од тачака",
- "Login is too long" : "Име за пријаву је сувише дугачко",
+ "Username is too long" : "Корисничко име је сувише дугачко",
"Login is invalid because files already exist for this user" : "Име за пријаву није исправно пошто већ постоје фајлови овог корисника",
"Account disabled" : "Налог је искључен",
"Login canceled by app" : "Пријава отказана од стране апликације",
@@ -364,6 +366,11 @@ OC.L10N.register(
"How many images to generate" : "Колико слика желите да се генерише",
"Output images" : "Излазне слике",
"The generated images" : "Генерисане слике",
+ "Generate speech" : "Генериши говор",
+ "Generate speech from a transcript" : "Генерише говор из транскрипта",
+ "Write transcript that you want the assistant to generate speech from" : "Напишите транскрипт из којег желите да асистент генерише говор",
+ "Output speech" : "Излазни говор",
+ "The generated speech" : "Генерисани говор",
"Free text to text prompt" : "Произвољни текст као унос",
"Runs an arbitrary prompt through a language model that returns a reply" : "Извршава произвољни захтев кроз језички модел који затим враћа одговор",
"Describe a task that you want the assistant to do or ask a question" : "Опишите задатак који желите да обави асистент или поставите питање",
@@ -443,20 +450,8 @@ OC.L10N.register(
"Generate headline" : "Генериши линију наслова",
"Summarizes text by reducing its length without losing key information." : "Резимира текст тако што га скраћује без губитка кључних информација.",
"Extracts topics from a text and outputs them separated by commas." : "Издваја теме из текста и исписује их раздвојене запетама.",
- "Education Edition" : "Образовно издање",
- "File name is a reserved word" : "Назив фајла је резервисана реч",
- "File name contains at least one invalid character" : "Назив фајла садржи бар један недозвољен знак",
- "File name is too long" : "Назив фајла је предугачак",
- "Users" : "Корисници",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s је поделио „%2$s“ са Вама и жели да дода:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s је поделио „%2$s“ са Вама и жели да дода",
- "»%s« added a note to a file shared with you" : "\"%s\" је додао белешку на фајл који дели са Вама",
- "Open »%s«" : "Отвори „%s“",
- "%1$s shared »%2$s« with you" : "%1$s је поделио „%2$s“ са Вама",
- "%1$s shared »%2$s« with you." : "%1$s је поделио „%2$s“ са Вама.",
- "Click the button below to open it." : "Кликните дугме испод да га отворите.",
"File is currently busy, please try again later" : "Фајл је тренутно заузет, покушајте поново касније",
"Cannot download file" : "Фајл не може да се преузме",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Уверите се да фајл \".ocdata\" постоји у корену директоријума са подацима."
+ "Login is too long" : "Име за пријаву је сувише дугачко"
},
"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/lib/l10n/sr.json b/lib/l10n/sr.json
index fc38faab174..a9b9e940482 100644
--- a/lib/l10n/sr.json
+++ b/lib/l10n/sr.json
@@ -91,6 +91,8 @@
"Destination does not exist" : "Одредиште не постоји",
"Destination is not creatable" : "Одредиште не може да се креира",
"Dot files are not allowed" : "Фајлови са почетном тачком нису дозвољени",
+ "%1$s (renamed)" : "%1$s (преименован)",
+ "renamed file" : "преименован фајл",
"\"%1$s\" is a forbidden file or folder name." : "„%1$s” је забрањено име фајла или фолдера.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "„%1$s” је забрањени префикс имена фајла или фолдера.",
"\"%1$s\" is not allowed inside a file or folder name." : "„%1$s” није дозвољено у имену фајла или фолдера.",
@@ -271,7 +273,7 @@
"A valid Login must be provided" : "Морате да унесете исправно име за пријаву",
"Login contains whitespace at the beginning or at the end" : "Име за пријаву садржи белине на почетку или на крају",
"Login must not consist of dots only" : "Име за пријаву не може да се састоји само од тачака",
- "Login is too long" : "Име за пријаву је сувише дугачко",
+ "Username is too long" : "Корисничко име је сувише дугачко",
"Login is invalid because files already exist for this user" : "Име за пријаву није исправно пошто већ постоје фајлови овог корисника",
"Account disabled" : "Налог је искључен",
"Login canceled by app" : "Пријава отказана од стране апликације",
@@ -362,6 +364,11 @@
"How many images to generate" : "Колико слика желите да се генерише",
"Output images" : "Излазне слике",
"The generated images" : "Генерисане слике",
+ "Generate speech" : "Генериши говор",
+ "Generate speech from a transcript" : "Генерише говор из транскрипта",
+ "Write transcript that you want the assistant to generate speech from" : "Напишите транскрипт из којег желите да асистент генерише говор",
+ "Output speech" : "Излазни говор",
+ "The generated speech" : "Генерисани говор",
"Free text to text prompt" : "Произвољни текст као унос",
"Runs an arbitrary prompt through a language model that returns a reply" : "Извршава произвољни захтев кроз језички модел који затим враћа одговор",
"Describe a task that you want the assistant to do or ask a question" : "Опишите задатак који желите да обави асистент или поставите питање",
@@ -441,20 +448,8 @@
"Generate headline" : "Генериши линију наслова",
"Summarizes text by reducing its length without losing key information." : "Резимира текст тако што га скраћује без губитка кључних информација.",
"Extracts topics from a text and outputs them separated by commas." : "Издваја теме из текста и исписује их раздвојене запетама.",
- "Education Edition" : "Образовно издање",
- "File name is a reserved word" : "Назив фајла је резервисана реч",
- "File name contains at least one invalid character" : "Назив фајла садржи бар један недозвољен знак",
- "File name is too long" : "Назив фајла је предугачак",
- "Users" : "Корисници",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s је поделио „%2$s“ са Вама и жели да дода:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s је поделио „%2$s“ са Вама и жели да дода",
- "»%s« added a note to a file shared with you" : "\"%s\" је додао белешку на фајл који дели са Вама",
- "Open »%s«" : "Отвори „%s“",
- "%1$s shared »%2$s« with you" : "%1$s је поделио „%2$s“ са Вама",
- "%1$s shared »%2$s« with you." : "%1$s је поделио „%2$s“ са Вама.",
- "Click the button below to open it." : "Кликните дугме испод да га отворите.",
"File is currently busy, please try again later" : "Фајл је тренутно заузет, покушајте поново касније",
"Cannot download file" : "Фајл не може да се преузме",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Уверите се да фајл \".ocdata\" постоји у корену директоријума са подацима."
+ "Login is too long" : "Име за пријаву је сувише дугачко"
},"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);"
} \ No newline at end of file
diff --git a/lib/l10n/sv.js b/lib/l10n/sv.js
index bc31d5b4acd..77c836b42d3 100644
--- a/lib/l10n/sv.js
+++ b/lib/l10n/sv.js
@@ -93,6 +93,8 @@ OC.L10N.register(
"Destination does not exist" : "Destinationen finns inte",
"Destination is not creatable" : "Destinationen går inte att skapa",
"Dot files are not allowed" : "Dot-filer är inte tillåtna",
+ "%1$s (renamed)" : "%1$s (omdöpt)",
+ "renamed file" : "omdöpt fil",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" är ett förbjudet fil- eller mappnamn.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" är ett förbjudet prefix för fil- eller mappnamn.",
"\"%1$s\" is not allowed inside a file or folder name." : "\"%1$s\" är inte tillåtet i ett fil- eller mappnamn.",
@@ -273,7 +275,7 @@ OC.L10N.register(
"A valid Login must be provided" : "En giltig inloggning måste anges",
"Login contains whitespace at the beginning or at the end" : "Inloggningen innehåller blanksteg i början eller slutet",
"Login must not consist of dots only" : "Inloggningen får inte innehålla enbart punkter",
- "Login is too long" : "Inloggningen är för lång",
+ "Username is too long" : "Användarnamnet är för långt",
"Login is invalid because files already exist for this user" : "Inloggningen är ogiltigt eftersom det redan finns filer för den här användaren",
"Account disabled" : "Konto inaktiverat",
"Login canceled by app" : "Inloggningen avbruten av appen",
@@ -364,6 +366,11 @@ OC.L10N.register(
"How many images to generate" : "Hur många bilder som ska genereras",
"Output images" : "Skapade bilder",
"The generated images" : "De genererade bilderna",
+ "Generate speech" : "Generera tal",
+ "Generate speech from a transcript" : "Generera tal från en transkription",
+ "Write transcript that you want the assistant to generate speech from" : "Skriv den transkription som du vill att assistenten ska generera tal från",
+ "Output speech" : "Genererat tal",
+ "The generated speech" : "Det genererade talet",
"Free text to text prompt" : "Fritext till text prompt",
"Runs an arbitrary prompt through a language model that returns a reply" : "Kör en godtycklig prompt genom en språkmodell som returnerar ett svar",
"Describe a task that you want the assistant to do or ask a question" : "Beskriv en uppgift som du vill att assistenten ska göra eller ställ en fråga",
@@ -443,20 +450,8 @@ OC.L10N.register(
"Generate headline" : "Skapa rubrik",
"Summarizes text by reducing its length without losing key information." : "Sammanfattar text genom att minska dess längd utan att förlora viktig information.",
"Extracts topics from a text and outputs them separated by commas." : "Extraherar ämnen från en text och matar ut dem separerade med kommatecken.",
- "Education Edition" : "Utbildningspaket",
- "File name is a reserved word" : "Filnamnet är ett reserverat ord",
- "File name contains at least one invalid character" : "Filnamnet innehåller minst ett ogiltigt tecken",
- "File name is too long" : "Filnamnet är för långt",
- "Users" : "Användare",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s delade \"%2$s\" med dig och vill lägga till:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s delade \"%2$s\" med dig och vill lägga till",
- "»%s« added a note to a file shared with you" : "\"%s\" lade till en kommentar till en fil som delats med dig",
- "Open »%s«" : "Öppna \"%s\"",
- "%1$s shared »%2$s« with you" : "%1$s delade \"%2$s\" med dig",
- "%1$s shared »%2$s« with you." : "%1$s delade \"%2$s\" med dig.",
- "Click the button below to open it." : "Klicka på knappen nedan för att öppna det.",
"File is currently busy, please try again later" : "Filen är för tillfället upptagen, försök igen senare",
"Cannot download file" : "Kan inte ladda ner fil",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Säkerställ att du har filen \".ocdata\" i huvudkatalogen för din data."
+ "Login is too long" : "Inloggningen är för lång"
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/sv.json b/lib/l10n/sv.json
index cc1b5183b80..f4eb5f933f3 100644
--- a/lib/l10n/sv.json
+++ b/lib/l10n/sv.json
@@ -91,6 +91,8 @@
"Destination does not exist" : "Destinationen finns inte",
"Destination is not creatable" : "Destinationen går inte att skapa",
"Dot files are not allowed" : "Dot-filer är inte tillåtna",
+ "%1$s (renamed)" : "%1$s (omdöpt)",
+ "renamed file" : "omdöpt fil",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" är ett förbjudet fil- eller mappnamn.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" är ett förbjudet prefix för fil- eller mappnamn.",
"\"%1$s\" is not allowed inside a file or folder name." : "\"%1$s\" är inte tillåtet i ett fil- eller mappnamn.",
@@ -271,7 +273,7 @@
"A valid Login must be provided" : "En giltig inloggning måste anges",
"Login contains whitespace at the beginning or at the end" : "Inloggningen innehåller blanksteg i början eller slutet",
"Login must not consist of dots only" : "Inloggningen får inte innehålla enbart punkter",
- "Login is too long" : "Inloggningen är för lång",
+ "Username is too long" : "Användarnamnet är för långt",
"Login is invalid because files already exist for this user" : "Inloggningen är ogiltigt eftersom det redan finns filer för den här användaren",
"Account disabled" : "Konto inaktiverat",
"Login canceled by app" : "Inloggningen avbruten av appen",
@@ -362,6 +364,11 @@
"How many images to generate" : "Hur många bilder som ska genereras",
"Output images" : "Skapade bilder",
"The generated images" : "De genererade bilderna",
+ "Generate speech" : "Generera tal",
+ "Generate speech from a transcript" : "Generera tal från en transkription",
+ "Write transcript that you want the assistant to generate speech from" : "Skriv den transkription som du vill att assistenten ska generera tal från",
+ "Output speech" : "Genererat tal",
+ "The generated speech" : "Det genererade talet",
"Free text to text prompt" : "Fritext till text prompt",
"Runs an arbitrary prompt through a language model that returns a reply" : "Kör en godtycklig prompt genom en språkmodell som returnerar ett svar",
"Describe a task that you want the assistant to do or ask a question" : "Beskriv en uppgift som du vill att assistenten ska göra eller ställ en fråga",
@@ -441,20 +448,8 @@
"Generate headline" : "Skapa rubrik",
"Summarizes text by reducing its length without losing key information." : "Sammanfattar text genom att minska dess längd utan att förlora viktig information.",
"Extracts topics from a text and outputs them separated by commas." : "Extraherar ämnen från en text och matar ut dem separerade med kommatecken.",
- "Education Edition" : "Utbildningspaket",
- "File name is a reserved word" : "Filnamnet är ett reserverat ord",
- "File name contains at least one invalid character" : "Filnamnet innehåller minst ett ogiltigt tecken",
- "File name is too long" : "Filnamnet är för långt",
- "Users" : "Användare",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s delade \"%2$s\" med dig och vill lägga till:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s delade \"%2$s\" med dig och vill lägga till",
- "»%s« added a note to a file shared with you" : "\"%s\" lade till en kommentar till en fil som delats med dig",
- "Open »%s«" : "Öppna \"%s\"",
- "%1$s shared »%2$s« with you" : "%1$s delade \"%2$s\" med dig",
- "%1$s shared »%2$s« with you." : "%1$s delade \"%2$s\" med dig.",
- "Click the button below to open it." : "Klicka på knappen nedan för att öppna det.",
"File is currently busy, please try again later" : "Filen är för tillfället upptagen, försök igen senare",
"Cannot download file" : "Kan inte ladda ner fil",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Säkerställ att du har filen \".ocdata\" i huvudkatalogen för din data."
+ "Login is too long" : "Inloggningen är för lång"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/sw.js b/lib/l10n/sw.js
new file mode 100644
index 00000000000..1e14a7e863a
--- /dev/null
+++ b/lib/l10n/sw.js
@@ -0,0 +1,41 @@
+OC.L10N.register(
+ "lib",
+ {
+ "Authentication" : "Uthibitisho",
+ "Unknown filetype" : "Aina ya faili haijulikani",
+ "Invalid image" : "Taswira si halisi",
+ "Files" : "Mafaili",
+ "View profile" : "Angalia wasifu",
+ "Local time: %s" : "Muda wa kawaida: %s",
+ "_%n year ago_::_%n years ago_" : ["%n year ago","%n years ago"],
+ "seconds ago" : "sukunde zilizopita",
+ "%1$s (renamed)" : "%1$s (iliyopew jina jipya)",
+ "renamed file" : "Faili iliyopewa jina jipya",
+ "Filenames must not end with \"%1$s\"." : "Majina ya faili hayapaswi kuishia na \"%1$s\"",
+ "File already exists" : "Faili lipo tayari",
+ "Templates" : "Violezo",
+ "Apps" : "Maombi",
+ "Settings" : "Mipangilio",
+ "Log out" : "Ondoka",
+ "Accounts" : "Akaunti",
+ "Email" : "Barua pepe",
+ "Phone" : "Simu",
+ "Twitter" : "Twitter",
+ "Website" : "Wavuti",
+ "Address" : "Anwani",
+ "About" : "Kuhusu",
+ "Additional settings" : "Mipangilio ya nyongeza",
+ "Sunday" : "Jumapili",
+ "Monday" : "Jumatatu",
+ "Tuesday" : "Jumanne",
+ "Wednesday" : "Jumatano",
+ "Thursday" : "Alhamisi",
+ "Friday" : "Ijumaa",
+ "Saturday" : "Jumamosi",
+ "Storage is temporarily not available" : "Uhifadhi haupo kwa muda",
+ "Confirmation" : "Uthibitisho",
+ "Text" : "Maandishi",
+ "Summary" : "Muhtasari",
+ "Translate" : "Tafsiri"
+},
+"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/sw.json b/lib/l10n/sw.json
new file mode 100644
index 00000000000..a4d0bdc97d8
--- /dev/null
+++ b/lib/l10n/sw.json
@@ -0,0 +1,39 @@
+{ "translations": {
+ "Authentication" : "Uthibitisho",
+ "Unknown filetype" : "Aina ya faili haijulikani",
+ "Invalid image" : "Taswira si halisi",
+ "Files" : "Mafaili",
+ "View profile" : "Angalia wasifu",
+ "Local time: %s" : "Muda wa kawaida: %s",
+ "_%n year ago_::_%n years ago_" : ["%n year ago","%n years ago"],
+ "seconds ago" : "sukunde zilizopita",
+ "%1$s (renamed)" : "%1$s (iliyopew jina jipya)",
+ "renamed file" : "Faili iliyopewa jina jipya",
+ "Filenames must not end with \"%1$s\"." : "Majina ya faili hayapaswi kuishia na \"%1$s\"",
+ "File already exists" : "Faili lipo tayari",
+ "Templates" : "Violezo",
+ "Apps" : "Maombi",
+ "Settings" : "Mipangilio",
+ "Log out" : "Ondoka",
+ "Accounts" : "Akaunti",
+ "Email" : "Barua pepe",
+ "Phone" : "Simu",
+ "Twitter" : "Twitter",
+ "Website" : "Wavuti",
+ "Address" : "Anwani",
+ "About" : "Kuhusu",
+ "Additional settings" : "Mipangilio ya nyongeza",
+ "Sunday" : "Jumapili",
+ "Monday" : "Jumatatu",
+ "Tuesday" : "Jumanne",
+ "Wednesday" : "Jumatano",
+ "Thursday" : "Alhamisi",
+ "Friday" : "Ijumaa",
+ "Saturday" : "Jumamosi",
+ "Storage is temporarily not available" : "Uhifadhi haupo kwa muda",
+ "Confirmation" : "Uthibitisho",
+ "Text" : "Maandishi",
+ "Summary" : "Muhtasari",
+ "Translate" : "Tafsiri"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+} \ No newline at end of file
diff --git a/lib/l10n/ta.js b/lib/l10n/ta.js
index 7caacb6a45c..9bd1c00a94b 100644
--- a/lib/l10n/ta.js
+++ b/lib/l10n/ta.js
@@ -57,7 +57,6 @@ OC.L10N.register(
"Application is not enabled" : "செயலி இயலுமைப்படுத்தப்படவில்லை",
"Authentication error" : "அத்தாட்சிப்படுத்தலில் வழு",
"Token expired. Please reload page." : "அடையாளவில்லை காலாவதியாகிவிட்டது. தயவுசெய்து பக்கத்தை மீள் ஏற்றுக.",
- "Translate" : "Translate",
- "Users" : "பயனாளர்"
+ "Translate" : "Translate"
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/ta.json b/lib/l10n/ta.json
index 39d16e4d163..dce148ee855 100644
--- a/lib/l10n/ta.json
+++ b/lib/l10n/ta.json
@@ -55,7 +55,6 @@
"Application is not enabled" : "செயலி இயலுமைப்படுத்தப்படவில்லை",
"Authentication error" : "அத்தாட்சிப்படுத்தலில் வழு",
"Token expired. Please reload page." : "அடையாளவில்லை காலாவதியாகிவிட்டது. தயவுசெய்து பக்கத்தை மீள் ஏற்றுக.",
- "Translate" : "Translate",
- "Users" : "பயனாளர்"
+ "Translate" : "Translate"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/th.js b/lib/l10n/th.js
index 0c91b048f55..234675da5d7 100644
--- a/lib/l10n/th.js
+++ b/lib/l10n/th.js
@@ -152,11 +152,6 @@ OC.L10N.register(
"Storage connection timeout. %s" : "หมดเวลาการเชื่อมต่อพื้นที่จัดเก็บข้อมูล %s",
"Text" : "ข้อความ",
"Translate" : "แปลภาษา",
- "File name is a reserved word" : "ชื่อแฟ้มเป็นคำสงวน",
- "File name contains at least one invalid character" : "ชื่อไฟล์มีตัวอักษรที่ไม่ถูกต้องอย่างน้อย 1 ตัว",
- "File name is too long" : "ชื่อไฟล์ยาวเกินไป",
- "Users" : "ผู้ใช้งาน",
- "Open »%s«" : "เปิด »%s«",
"File is currently busy, please try again later" : "ไฟล์กำลังใช้งานอยู่ โปรดลองอีกครั้งในภายหลัง"
},
"nplurals=1; plural=0;");
diff --git a/lib/l10n/th.json b/lib/l10n/th.json
index 3ea5d0c562b..cc2c80d0e95 100644
--- a/lib/l10n/th.json
+++ b/lib/l10n/th.json
@@ -150,11 +150,6 @@
"Storage connection timeout. %s" : "หมดเวลาการเชื่อมต่อพื้นที่จัดเก็บข้อมูล %s",
"Text" : "ข้อความ",
"Translate" : "แปลภาษา",
- "File name is a reserved word" : "ชื่อแฟ้มเป็นคำสงวน",
- "File name contains at least one invalid character" : "ชื่อไฟล์มีตัวอักษรที่ไม่ถูกต้องอย่างน้อย 1 ตัว",
- "File name is too long" : "ชื่อไฟล์ยาวเกินไป",
- "Users" : "ผู้ใช้งาน",
- "Open »%s«" : "เปิด »%s«",
"File is currently busy, please try again later" : "ไฟล์กำลังใช้งานอยู่ โปรดลองอีกครั้งในภายหลัง"
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/lib/l10n/tr.js b/lib/l10n/tr.js
index a03970a1c3b..5f28ef658ab 100644
--- a/lib/l10n/tr.js
+++ b/lib/l10n/tr.js
@@ -83,7 +83,7 @@ OC.L10N.register(
"_in %n minute_::_in %n minutes_" : ["%n dakika içinde","%n dakika içinde"],
"_%n minute ago_::_%n minutes ago_" : ["%n dakika önce","%n dakika önce"],
"in a few seconds" : "bir kaç saniye içinde",
- "seconds ago" : "saniyeler önce",
+ "seconds ago" : "saniye önce",
"Empty file" : "Dosya boş",
"Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "%s kimlikli modül bulunamadı. Lütfen uygulamalarınız içinden modülü kullanıma alın ya da BT yöneticiniz ile görüşün.",
"No file conversion providers available" : "Kullanılabilecek bir dosya dönüştürücü hizmeti sağlayıcı yok",
@@ -93,6 +93,8 @@ OC.L10N.register(
"Destination does not exist" : "Hedef bulunamadı",
"Destination is not creatable" : "Hedef oluşturulamadı",
"Dot files are not allowed" : "Nokta dosyalarına izin verilmiyor",
+ "%1$s (renamed)" : "%1$s (yeniden adlandırıldı)",
+ "renamed file" : "dosyayı yeniden adlandırdı",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" dosya ya da klasör adı olarak kullanılamaz.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" dosya ya da klasör adı ön eki olarak kullanılamaz.",
"\"%1$s\" is not allowed inside a file or folder name." : "\"%1$s\" bir dosya ya da klasör adında kullanılamaz.",
@@ -163,16 +165,16 @@ OC.L10N.register(
"Set an admin Login." : "Bir yönetici kullanıcı adı yazın.",
"Set an admin password." : "Bir yönetici parolası yazın.",
"Cannot create or write into the data directory %s" : "%s veri klasörü oluşturulamadı ya da içine yazılamadı",
- "Sharing backend %s must implement the interface OCP\\Share_Backend" : "Paylaşım arka ucu %s OCP\\Share_Backend arayüzünü desteklemeli",
- "Sharing backend %s not found" : "%s paylaşım arka ucu bulunamadı",
- "Sharing backend for %s not found" : "%s için paylaşım arka ucu bulunamadı",
+ "Sharing backend %s must implement the interface OCP\\Share_Backend" : "Paylaşım arka yüzü %s OCP\\Share_Backend arayüzünü desteklemeli",
+ "Sharing backend %s not found" : "%s paylaşım arka yüzü bulunamadı",
+ "Sharing backend for %s not found" : "%s için paylaşım arka yüzü bulunamadı",
"%1$s shared %2$s with you" : "%1$s, sizinle %2$s ögesini paylaştı",
"Open %s" : "%s ögesini aç",
"%1$s via %2$s" : "%1$s, %2$s aracılığıyla",
"%1$s shared %2$s with you and wants to add:" : "%1$s sizinle %2$s ögesini paylaştı ve eklemenizi istiyor:",
"%1$s shared %2$s with you and wants to add" : "%1$s sizinle %2$s ögesini paylaştı ve eklemenizi istiyor",
"%s added a note to a file shared with you" : "%s sizinle paylaştığı bir dosyaya bir not ekledi",
- "Passwords are enforced for link and mail shares" : "Bağlantı ve e-posta paylaşımları için parolalar zorunludur",
+ "Passwords are enforced for link and mail shares" : "Bağlantı ve e-posta paylaşımları için parola kullanılması zorunlu kılınmış",
"Share recipient is not a valid user" : "Paylaşım alıcısı geçerli bir kullanıcı değil",
"Share recipient is not a valid group" : "Paylaşım alıcısı geçerli bir grup değil",
"Share recipient should be empty" : "Paylaşım alıcısı boş olmalı",
@@ -192,7 +194,7 @@ OC.L10N.register(
"Files cannot be shared with delete permissions" : "Silme izni ile dosya paylaşılamaz",
"Files cannot be shared with create permissions" : "Ekleme izni ile dosya paylaşılamaz",
"Expiration date is in the past" : "Geçerlilik sonu tarihi geçmişte",
- "Expiration date is enforced" : "Geçerlilik sonu tarihi dayatılıyor",
+ "Expiration date is enforced" : "Geçerlilik sonu tarihi zorunlu kılınmış",
"_Cannot set expiration date more than %n day in the future_::_Cannot set expiration date more than %n days in the future_" : ["Paylaşımların geçerlilik süreleri, gelecekte %n günden fazla olamaz","Paylaşımların geçerlilik süreleri, gelecekte %n günden fazla olamaz"],
"Sharing is only allowed with group members" : "Paylaşım yalnızca grup üyeleri ile yapılabilir",
"Sharing %s failed, because this item is already shared with the account %s" : "%s paylaşılamadı. Bu öge zaten %s hesabı ile paylaşılmış",
@@ -201,15 +203,16 @@ OC.L10N.register(
"Path is already shared with this group" : "Bu yol bu grup ile zaten paylaşılmış",
"Link sharing is not allowed" : "Bağlantı paylaşımına izin verilmiyor",
"Public upload is not allowed" : "Herkese açık yüklemeye izin verilmiyor",
+ "You cannot share a folder that contains other shares" : "Başka paylaşımların bulunduğu bir klasörü paylaşamazsınız",
"Sharing is disabled" : "Paylaşım kullanımdan kaldırılmış",
"Sharing is disabled for you" : "Paylaşım sizin için kullanımdan kaldırılmış",
"Cannot share with the share owner" : "Paylaşımı sahibi ile paylaşamazsınız",
"Share does not have a full ID" : "Paylaşımın tam kimliği yok",
"Cannot change share type" : "Paylaşım türü değiştirilemez",
"Can only update recipient on user shares" : "Yalnızca kullanıcı paylaşımlarındaki alıcıyı güncelleyebilir",
- "Cannot enable sending the password by Talk with an empty password" : "Boş bir parola ile Sohbet uygulaması ile parola gönderme özelliği kullanıma alınamaz",
- "Cannot enable sending the password by Talk without setting a new password" : "Yeni bir parola ayarlanmadan Sohbet uygulaması ile parola gönderme özelliği kullanıma alınamaz",
- "Cannot disable sending the password by Talk without setting a new password" : "Yeni bir parola ayarlanmadan Sohbet uygulaması ile parola gönderme kullanımdan kaldırılamaz",
+ "Cannot enable sending the password by Talk with an empty password" : "Boş bir parola kullanarak Konuş uygulaması ile parola gönderme özelliği açılamaz",
+ "Cannot enable sending the password by Talk without setting a new password" : "Yeni bir parola ayarlanmadan Konuş uygulaması ile parola gönderme özelliği açılamaz",
+ "Cannot disable sending the password by Talk without setting a new password" : "Yeni bir parola ayarlanmadan Konuş uygulaması ile parola gönderme özelliği kapatılamaz",
"Share provider does not support accepting" : "Paylaşım hizmeti sağlayıcısı kabul etmeyi desteklemiyor",
"Cannot change target of link share" : "Bağlantı paylaşımının hedefi değiştirilemedi",
"Invalid share recipient" : "Paylaşım alıcısı geçersiz",
@@ -272,6 +275,7 @@ OC.L10N.register(
"A valid Login must be provided" : "Geçerli bir kullanıcı adı yazmalısınız",
"Login contains whitespace at the beginning or at the end" : "Kullanıcı adının başında ya da sonunda boşluk var",
"Login must not consist of dots only" : "Kullanıcı adı yalnızca noktalardan oluşamaz",
+ "Username is too long" : "Kullanıcı adı çok uzun",
"Login is invalid because files already exist for this user" : "Kullanıcı adı geçersiz, bu kullanıcı için zaten bazı dosyalar var",
"Account disabled" : "Hesap kullanımdan kaldırılmış",
"Login canceled by app" : "Oturum açma uygulama tarafından iptal edildi",
@@ -362,6 +366,11 @@ OC.L10N.register(
"How many images to generate" : "Oluşturulacak görsel sayısı",
"Output images" : "Çıktı görselleri",
"The generated images" : "Oluşturulan görseller",
+ "Generate speech" : "Konuşma oluştur",
+ "Generate speech from a transcript" : "Bir yazıya dönüştürmeden konuşma oluştur",
+ "Write transcript that you want the assistant to generate speech from" : "Yardımcının konuşma oluşturmasını istediğiniz yazı dönüştürmesini yazın",
+ "Output speech" : "Konuşma çıktısı",
+ "The generated speech" : "Oluşturulan konuşma",
"Free text to text prompt" : "Ücretsiz yazıdan yazıya istemi",
"Runs an arbitrary prompt through a language model that returns a reply" : "Dil modeli ile bir yanıt döndüren isteğe bağlı bir bilgi istemi çalıştırır",
"Describe a task that you want the assistant to do or ask a question" : "Yardımcının yapmasını istediğiniz bir görevi tanımlayın ya da bir soru sorun",
@@ -441,20 +450,8 @@ OC.L10N.register(
"Generate headline" : "Başlık oluşturulsun",
"Summarizes text by reducing its length without losing key information." : "Temel içeriği kaybetmeden uzunluğunu kısaltarak metni özetler.",
"Extracts topics from a text and outputs them separated by commas." : "Bir metindeki konuları ayıklar ve bunları virgül ile ayırarak sıralar.",
- "Education Edition" : "Eğitim sürümü",
- "File name is a reserved word" : "Bu dosya adı sistem kullanıma ayrılmıştır",
- "File name contains at least one invalid character" : "Dosya adında en az bir geçersiz karakter var",
- "File name is too long" : "Dosya adı çok uzun",
- "Users" : "Kullanıcılar",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s sizinle »%2$s« ögesini paylaştı ve eklemenizi istiyor:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s sizinle »%2$s« ögesini paylaştı ve eklemenizi istiyor",
- "»%s« added a note to a file shared with you" : "»%s« sizinle paylaştığı bir dosyaya bir not ekledi",
- "Open »%s«" : "»%s« aç",
- "%1$s shared »%2$s« with you" : "%1$s, sizinle »%2$s« ögesini paylaştı",
- "%1$s shared »%2$s« with you." : "%1$s, sizinle »%2$s« ögesini paylaştı.",
- "Click the button below to open it." : "Açmak için aşağıdaki düğmeye tıklayın.",
"File is currently busy, please try again later" : "Dosya şu anda meşgul. Lütfen bir süre sonra yeniden deneyin",
"Cannot download file" : "Dosya indirilemedi",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Veri klasörü kökünde \".ocdata\" adında bir dosya bulunduğundan emin olun."
+ "Login is too long" : "Kullanıcı adı çok uzun"
},
"nplurals=2; plural=(n > 1);");
diff --git a/lib/l10n/tr.json b/lib/l10n/tr.json
index a066cd1a337..2e46571c57f 100644
--- a/lib/l10n/tr.json
+++ b/lib/l10n/tr.json
@@ -81,7 +81,7 @@
"_in %n minute_::_in %n minutes_" : ["%n dakika içinde","%n dakika içinde"],
"_%n minute ago_::_%n minutes ago_" : ["%n dakika önce","%n dakika önce"],
"in a few seconds" : "bir kaç saniye içinde",
- "seconds ago" : "saniyeler önce",
+ "seconds ago" : "saniye önce",
"Empty file" : "Dosya boş",
"Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "%s kimlikli modül bulunamadı. Lütfen uygulamalarınız içinden modülü kullanıma alın ya da BT yöneticiniz ile görüşün.",
"No file conversion providers available" : "Kullanılabilecek bir dosya dönüştürücü hizmeti sağlayıcı yok",
@@ -91,6 +91,8 @@
"Destination does not exist" : "Hedef bulunamadı",
"Destination is not creatable" : "Hedef oluşturulamadı",
"Dot files are not allowed" : "Nokta dosyalarına izin verilmiyor",
+ "%1$s (renamed)" : "%1$s (yeniden adlandırıldı)",
+ "renamed file" : "dosyayı yeniden adlandırdı",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" dosya ya da klasör adı olarak kullanılamaz.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" dosya ya da klasör adı ön eki olarak kullanılamaz.",
"\"%1$s\" is not allowed inside a file or folder name." : "\"%1$s\" bir dosya ya da klasör adında kullanılamaz.",
@@ -161,16 +163,16 @@
"Set an admin Login." : "Bir yönetici kullanıcı adı yazın.",
"Set an admin password." : "Bir yönetici parolası yazın.",
"Cannot create or write into the data directory %s" : "%s veri klasörü oluşturulamadı ya da içine yazılamadı",
- "Sharing backend %s must implement the interface OCP\\Share_Backend" : "Paylaşım arka ucu %s OCP\\Share_Backend arayüzünü desteklemeli",
- "Sharing backend %s not found" : "%s paylaşım arka ucu bulunamadı",
- "Sharing backend for %s not found" : "%s için paylaşım arka ucu bulunamadı",
+ "Sharing backend %s must implement the interface OCP\\Share_Backend" : "Paylaşım arka yüzü %s OCP\\Share_Backend arayüzünü desteklemeli",
+ "Sharing backend %s not found" : "%s paylaşım arka yüzü bulunamadı",
+ "Sharing backend for %s not found" : "%s için paylaşım arka yüzü bulunamadı",
"%1$s shared %2$s with you" : "%1$s, sizinle %2$s ögesini paylaştı",
"Open %s" : "%s ögesini aç",
"%1$s via %2$s" : "%1$s, %2$s aracılığıyla",
"%1$s shared %2$s with you and wants to add:" : "%1$s sizinle %2$s ögesini paylaştı ve eklemenizi istiyor:",
"%1$s shared %2$s with you and wants to add" : "%1$s sizinle %2$s ögesini paylaştı ve eklemenizi istiyor",
"%s added a note to a file shared with you" : "%s sizinle paylaştığı bir dosyaya bir not ekledi",
- "Passwords are enforced for link and mail shares" : "Bağlantı ve e-posta paylaşımları için parolalar zorunludur",
+ "Passwords are enforced for link and mail shares" : "Bağlantı ve e-posta paylaşımları için parola kullanılması zorunlu kılınmış",
"Share recipient is not a valid user" : "Paylaşım alıcısı geçerli bir kullanıcı değil",
"Share recipient is not a valid group" : "Paylaşım alıcısı geçerli bir grup değil",
"Share recipient should be empty" : "Paylaşım alıcısı boş olmalı",
@@ -190,7 +192,7 @@
"Files cannot be shared with delete permissions" : "Silme izni ile dosya paylaşılamaz",
"Files cannot be shared with create permissions" : "Ekleme izni ile dosya paylaşılamaz",
"Expiration date is in the past" : "Geçerlilik sonu tarihi geçmişte",
- "Expiration date is enforced" : "Geçerlilik sonu tarihi dayatılıyor",
+ "Expiration date is enforced" : "Geçerlilik sonu tarihi zorunlu kılınmış",
"_Cannot set expiration date more than %n day in the future_::_Cannot set expiration date more than %n days in the future_" : ["Paylaşımların geçerlilik süreleri, gelecekte %n günden fazla olamaz","Paylaşımların geçerlilik süreleri, gelecekte %n günden fazla olamaz"],
"Sharing is only allowed with group members" : "Paylaşım yalnızca grup üyeleri ile yapılabilir",
"Sharing %s failed, because this item is already shared with the account %s" : "%s paylaşılamadı. Bu öge zaten %s hesabı ile paylaşılmış",
@@ -199,15 +201,16 @@
"Path is already shared with this group" : "Bu yol bu grup ile zaten paylaşılmış",
"Link sharing is not allowed" : "Bağlantı paylaşımına izin verilmiyor",
"Public upload is not allowed" : "Herkese açık yüklemeye izin verilmiyor",
+ "You cannot share a folder that contains other shares" : "Başka paylaşımların bulunduğu bir klasörü paylaşamazsınız",
"Sharing is disabled" : "Paylaşım kullanımdan kaldırılmış",
"Sharing is disabled for you" : "Paylaşım sizin için kullanımdan kaldırılmış",
"Cannot share with the share owner" : "Paylaşımı sahibi ile paylaşamazsınız",
"Share does not have a full ID" : "Paylaşımın tam kimliği yok",
"Cannot change share type" : "Paylaşım türü değiştirilemez",
"Can only update recipient on user shares" : "Yalnızca kullanıcı paylaşımlarındaki alıcıyı güncelleyebilir",
- "Cannot enable sending the password by Talk with an empty password" : "Boş bir parola ile Sohbet uygulaması ile parola gönderme özelliği kullanıma alınamaz",
- "Cannot enable sending the password by Talk without setting a new password" : "Yeni bir parola ayarlanmadan Sohbet uygulaması ile parola gönderme özelliği kullanıma alınamaz",
- "Cannot disable sending the password by Talk without setting a new password" : "Yeni bir parola ayarlanmadan Sohbet uygulaması ile parola gönderme kullanımdan kaldırılamaz",
+ "Cannot enable sending the password by Talk with an empty password" : "Boş bir parola kullanarak Konuş uygulaması ile parola gönderme özelliği açılamaz",
+ "Cannot enable sending the password by Talk without setting a new password" : "Yeni bir parola ayarlanmadan Konuş uygulaması ile parola gönderme özelliği açılamaz",
+ "Cannot disable sending the password by Talk without setting a new password" : "Yeni bir parola ayarlanmadan Konuş uygulaması ile parola gönderme özelliği kapatılamaz",
"Share provider does not support accepting" : "Paylaşım hizmeti sağlayıcısı kabul etmeyi desteklemiyor",
"Cannot change target of link share" : "Bağlantı paylaşımının hedefi değiştirilemedi",
"Invalid share recipient" : "Paylaşım alıcısı geçersiz",
@@ -270,6 +273,7 @@
"A valid Login must be provided" : "Geçerli bir kullanıcı adı yazmalısınız",
"Login contains whitespace at the beginning or at the end" : "Kullanıcı adının başında ya da sonunda boşluk var",
"Login must not consist of dots only" : "Kullanıcı adı yalnızca noktalardan oluşamaz",
+ "Username is too long" : "Kullanıcı adı çok uzun",
"Login is invalid because files already exist for this user" : "Kullanıcı adı geçersiz, bu kullanıcı için zaten bazı dosyalar var",
"Account disabled" : "Hesap kullanımdan kaldırılmış",
"Login canceled by app" : "Oturum açma uygulama tarafından iptal edildi",
@@ -360,6 +364,11 @@
"How many images to generate" : "Oluşturulacak görsel sayısı",
"Output images" : "Çıktı görselleri",
"The generated images" : "Oluşturulan görseller",
+ "Generate speech" : "Konuşma oluştur",
+ "Generate speech from a transcript" : "Bir yazıya dönüştürmeden konuşma oluştur",
+ "Write transcript that you want the assistant to generate speech from" : "Yardımcının konuşma oluşturmasını istediğiniz yazı dönüştürmesini yazın",
+ "Output speech" : "Konuşma çıktısı",
+ "The generated speech" : "Oluşturulan konuşma",
"Free text to text prompt" : "Ücretsiz yazıdan yazıya istemi",
"Runs an arbitrary prompt through a language model that returns a reply" : "Dil modeli ile bir yanıt döndüren isteğe bağlı bir bilgi istemi çalıştırır",
"Describe a task that you want the assistant to do or ask a question" : "Yardımcının yapmasını istediğiniz bir görevi tanımlayın ya da bir soru sorun",
@@ -439,20 +448,8 @@
"Generate headline" : "Başlık oluşturulsun",
"Summarizes text by reducing its length without losing key information." : "Temel içeriği kaybetmeden uzunluğunu kısaltarak metni özetler.",
"Extracts topics from a text and outputs them separated by commas." : "Bir metindeki konuları ayıklar ve bunları virgül ile ayırarak sıralar.",
- "Education Edition" : "Eğitim sürümü",
- "File name is a reserved word" : "Bu dosya adı sistem kullanıma ayrılmıştır",
- "File name contains at least one invalid character" : "Dosya adında en az bir geçersiz karakter var",
- "File name is too long" : "Dosya adı çok uzun",
- "Users" : "Kullanıcılar",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s sizinle »%2$s« ögesini paylaştı ve eklemenizi istiyor:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s sizinle »%2$s« ögesini paylaştı ve eklemenizi istiyor",
- "»%s« added a note to a file shared with you" : "»%s« sizinle paylaştığı bir dosyaya bir not ekledi",
- "Open »%s«" : "»%s« aç",
- "%1$s shared »%2$s« with you" : "%1$s, sizinle »%2$s« ögesini paylaştı",
- "%1$s shared »%2$s« with you." : "%1$s, sizinle »%2$s« ögesini paylaştı.",
- "Click the button below to open it." : "Açmak için aşağıdaki düğmeye tıklayın.",
"File is currently busy, please try again later" : "Dosya şu anda meşgul. Lütfen bir süre sonra yeniden deneyin",
"Cannot download file" : "Dosya indirilemedi",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Veri klasörü kökünde \".ocdata\" adında bir dosya bulunduğundan emin olun."
+ "Login is too long" : "Kullanıcı adı çok uzun"
},"pluralForm" :"nplurals=2; plural=(n > 1);"
} \ No newline at end of file
diff --git a/lib/l10n/ug.js b/lib/l10n/ug.js
index 68b72c48aa9..0f478e7790a 100644
--- a/lib/l10n/ug.js
+++ b/lib/l10n/ug.js
@@ -378,20 +378,7 @@ OC.L10N.register(
"Generate headline" : "ماۋزۇ ھاسىل قىلىڭ",
"Summarizes text by reducing its length without losing key information." : "ئاچقۇچلۇق ئۇچۇرلارنى يوقىتىپ قويماي ئۇزۇنلۇقىنى قىسقارتىش ئارقىلىق تېكىستنى خۇلاسىلەيدۇ.",
"Extracts topics from a text and outputs them separated by commas." : "تېكىستتىن تېمىنى چىقىرىپ ، پەش ئارقىلىق ئايرىلىدۇ.",
- "Education Edition" : "مائارىپ نەشرى",
- "File name is a reserved word" : "ھۆججەت ئىسمى زاپاس سۆز",
- "File name contains at least one invalid character" : "ھۆججەت ئىسمى كەم دېگەندە بىر ئىناۋەتسىز ھەرپنى ئۆز ئىچىگە ئالىدۇ",
- "File name is too long" : "ھۆججەت ئىسمى بەك ئۇزۇن",
- "Users" : "ئىشلەتكۈچىلەر",
- "%1$s shared »%2$s« with you and wants to add:" : "%1 $ s ئورتاقلاشتى »%2 $ s« سىز بىلەن قوشماقچى:",
- "%1$s shared »%2$s« with you and wants to add" : "%1 $ s ئورتاقلاشتى »%2 $ s« سىز بىلەن قوشماقچى",
- "»%s« added a note to a file shared with you" : "»% S« سىز بىلەن ئورتاقلاشقان ھۆججەتكە خاتىرە قوشتى",
- "Open »%s«" : "ئېچىڭ »% s«",
- "%1$s shared »%2$s« with you" : "%1 $ s ئورتاقلاشتى »%2 $ s« سىز بىلەن",
- "%1$s shared »%2$s« with you." : "%1 $ s ئورتاقلاشتى »%2 $ s« سىز بىلەن.",
- "Click the button below to open it." : "ئۇنى ئېچىش ئۈچۈن تۆۋەندىكى كۇنۇپكىنى بېسىڭ.",
"File is currently busy, please try again later" : "ھۆججەت ھازىر ئالدىراش ، كېيىن قايتا سىناڭ",
- "Cannot download file" : "ھۆججەتنى چۈشۈرگىلى بولمايدۇ",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "سانلىق مەلۇمات مۇندەرىجىسىنىڭ يىلتىزىدا \".ocdata\" دەپ ئاتىلىدىغان ھۆججەتنىڭ بارلىقىغا كاپالەتلىك قىلىڭ."
+ "Cannot download file" : "ھۆججەتنى چۈشۈرگىلى بولمايدۇ"
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/ug.json b/lib/l10n/ug.json
index 6f9beeb5b3b..2fe0e3608e3 100644
--- a/lib/l10n/ug.json
+++ b/lib/l10n/ug.json
@@ -376,20 +376,7 @@
"Generate headline" : "ماۋزۇ ھاسىل قىلىڭ",
"Summarizes text by reducing its length without losing key information." : "ئاچقۇچلۇق ئۇچۇرلارنى يوقىتىپ قويماي ئۇزۇنلۇقىنى قىسقارتىش ئارقىلىق تېكىستنى خۇلاسىلەيدۇ.",
"Extracts topics from a text and outputs them separated by commas." : "تېكىستتىن تېمىنى چىقىرىپ ، پەش ئارقىلىق ئايرىلىدۇ.",
- "Education Edition" : "مائارىپ نەشرى",
- "File name is a reserved word" : "ھۆججەت ئىسمى زاپاس سۆز",
- "File name contains at least one invalid character" : "ھۆججەت ئىسمى كەم دېگەندە بىر ئىناۋەتسىز ھەرپنى ئۆز ئىچىگە ئالىدۇ",
- "File name is too long" : "ھۆججەت ئىسمى بەك ئۇزۇن",
- "Users" : "ئىشلەتكۈچىلەر",
- "%1$s shared »%2$s« with you and wants to add:" : "%1 $ s ئورتاقلاشتى »%2 $ s« سىز بىلەن قوشماقچى:",
- "%1$s shared »%2$s« with you and wants to add" : "%1 $ s ئورتاقلاشتى »%2 $ s« سىز بىلەن قوشماقچى",
- "»%s« added a note to a file shared with you" : "»% S« سىز بىلەن ئورتاقلاشقان ھۆججەتكە خاتىرە قوشتى",
- "Open »%s«" : "ئېچىڭ »% s«",
- "%1$s shared »%2$s« with you" : "%1 $ s ئورتاقلاشتى »%2 $ s« سىز بىلەن",
- "%1$s shared »%2$s« with you." : "%1 $ s ئورتاقلاشتى »%2 $ s« سىز بىلەن.",
- "Click the button below to open it." : "ئۇنى ئېچىش ئۈچۈن تۆۋەندىكى كۇنۇپكىنى بېسىڭ.",
"File is currently busy, please try again later" : "ھۆججەت ھازىر ئالدىراش ، كېيىن قايتا سىناڭ",
- "Cannot download file" : "ھۆججەتنى چۈشۈرگىلى بولمايدۇ",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "سانلىق مەلۇمات مۇندەرىجىسىنىڭ يىلتىزىدا \".ocdata\" دەپ ئاتىلىدىغان ھۆججەتنىڭ بارلىقىغا كاپالەتلىك قىلىڭ."
+ "Cannot download file" : "ھۆججەتنى چۈشۈرگىلى بولمايدۇ"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/uk.js b/lib/l10n/uk.js
index 3d29de9a772..b92f38a5f57 100644
--- a/lib/l10n/uk.js
+++ b/lib/l10n/uk.js
@@ -93,6 +93,8 @@ OC.L10N.register(
"Destination does not exist" : "Призначення відсутнє",
"Destination is not creatable" : "Неможливо створити призначення",
"Dot files are not allowed" : "Файли які починаються з крапки не допустимі",
+ "%1$s (renamed)" : "%1$s (перейменовано)",
+ "renamed file" : "перейменовано файл",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" є недозволеним ім'ям файлів або каталогів.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" є недозволеним префіксом у іменах файлів або каталоів.",
"\"%1$s\" is not allowed inside a file or folder name." : "\"%1$s\" не дозволено всередині імени файлів або каталогів.",
@@ -273,6 +275,7 @@ OC.L10N.register(
"A valid Login must be provided" : "Зазначте дійсне ім'я користувача",
"Login contains whitespace at the beginning or at the end" : "Ім'я користувача містить символ пробілу на початку або наприкінці",
"Login must not consist of dots only" : "Ім'я користувача не може складатися лише з крапок",
+ "Username is too long" : "Ім'я користувача задовге",
"Login is invalid because files already exist for this user" : "Недійсне ім'я облікового запису, оскільки файли для цього користувача вже присутні",
"Account disabled" : "Обліковий запис вимкнено",
"Login canceled by app" : "Вхід скасовано застосунком",
@@ -336,6 +339,10 @@ OC.L10N.register(
"Generate image" : "Зґенерувати зображення",
"Prompt" : "Запрошення",
"Chat" : "Чат",
+ "System prompt" : "Системний запит",
+ "Chat history" : "Історія чату",
+ "Response message" : "Відповідь",
+ "Available tools" : "Доступні інструменти",
"Generates a possible headline for a text." : "Створює ймовірний заголовок тексту.",
"Text" : "Текст",
"Summarize" : "Підсумок",
@@ -349,20 +356,8 @@ OC.L10N.register(
"Generate headline" : "Створити заголовок",
"Summarizes text by reducing its length without losing key information." : "Викокремлює головне у тексті шляхом зменшення довжини тексту без втрати ключової інформації.",
"Extracts topics from a text and outputs them separated by commas." : "Виділяє теми, які висвітлює текст, зводить їх у перелік, що розділено комами.",
- "Education Edition" : "Для навчання",
- "File name is a reserved word" : "Ім’я файлу є зарезервованим словом",
- "File name contains at least one invalid character" : "Ім’я файлу містить принаймні один некоректний символ",
- "File name is too long" : "Ім’я файлу занадто довге",
- "Users" : "Користувачі",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s надав(-ла) доступ до \"%2$s\" та хоче додати:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s надав(-ла) доступ до \"%2$s\" та хоче додати",
- "»%s« added a note to a file shared with you" : "\"%s\" додано примітку до файлу у спільному доступі",
- "Open »%s«" : "Відкрити %s",
- "%1$s shared »%2$s« with you" : "%1$s надав(-ла) доступ до \"%2$s\"",
- "%1$s shared »%2$s« with you." : "%1$s надав(-ла) доступ до \"%2$s\".",
- "Click the button below to open it." : "Щоб відкрити файл, натисніть кнопку нижче.",
"File is currently busy, please try again later" : "Файл на разі зайнятий, будь ласка, спробуйте пізніше",
"Cannot download file" : "Неможливо звантажити файл",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Переконайтеся, що в корені каталогу даних є файл під назвою \".ocdata\"."
+ "Login is too long" : "Ім'я користувача для авторизації задовге"
},
"nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != 11 ? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || (n % 100 >=11 && n % 100 <=14 )) ? 2: 3);");
diff --git a/lib/l10n/uk.json b/lib/l10n/uk.json
index 4a4fba617b4..e091c070aa7 100644
--- a/lib/l10n/uk.json
+++ b/lib/l10n/uk.json
@@ -91,6 +91,8 @@
"Destination does not exist" : "Призначення відсутнє",
"Destination is not creatable" : "Неможливо створити призначення",
"Dot files are not allowed" : "Файли які починаються з крапки не допустимі",
+ "%1$s (renamed)" : "%1$s (перейменовано)",
+ "renamed file" : "перейменовано файл",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" є недозволеним ім'ям файлів або каталогів.",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" є недозволеним префіксом у іменах файлів або каталоів.",
"\"%1$s\" is not allowed inside a file or folder name." : "\"%1$s\" не дозволено всередині імени файлів або каталогів.",
@@ -271,6 +273,7 @@
"A valid Login must be provided" : "Зазначте дійсне ім'я користувача",
"Login contains whitespace at the beginning or at the end" : "Ім'я користувача містить символ пробілу на початку або наприкінці",
"Login must not consist of dots only" : "Ім'я користувача не може складатися лише з крапок",
+ "Username is too long" : "Ім'я користувача задовге",
"Login is invalid because files already exist for this user" : "Недійсне ім'я облікового запису, оскільки файли для цього користувача вже присутні",
"Account disabled" : "Обліковий запис вимкнено",
"Login canceled by app" : "Вхід скасовано застосунком",
@@ -334,6 +337,10 @@
"Generate image" : "Зґенерувати зображення",
"Prompt" : "Запрошення",
"Chat" : "Чат",
+ "System prompt" : "Системний запит",
+ "Chat history" : "Історія чату",
+ "Response message" : "Відповідь",
+ "Available tools" : "Доступні інструменти",
"Generates a possible headline for a text." : "Створює ймовірний заголовок тексту.",
"Text" : "Текст",
"Summarize" : "Підсумок",
@@ -347,20 +354,8 @@
"Generate headline" : "Створити заголовок",
"Summarizes text by reducing its length without losing key information." : "Викокремлює головне у тексті шляхом зменшення довжини тексту без втрати ключової інформації.",
"Extracts topics from a text and outputs them separated by commas." : "Виділяє теми, які висвітлює текст, зводить їх у перелік, що розділено комами.",
- "Education Edition" : "Для навчання",
- "File name is a reserved word" : "Ім’я файлу є зарезервованим словом",
- "File name contains at least one invalid character" : "Ім’я файлу містить принаймні один некоректний символ",
- "File name is too long" : "Ім’я файлу занадто довге",
- "Users" : "Користувачі",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s надав(-ла) доступ до \"%2$s\" та хоче додати:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s надав(-ла) доступ до \"%2$s\" та хоче додати",
- "»%s« added a note to a file shared with you" : "\"%s\" додано примітку до файлу у спільному доступі",
- "Open »%s«" : "Відкрити %s",
- "%1$s shared »%2$s« with you" : "%1$s надав(-ла) доступ до \"%2$s\"",
- "%1$s shared »%2$s« with you." : "%1$s надав(-ла) доступ до \"%2$s\".",
- "Click the button below to open it." : "Щоб відкрити файл, натисніть кнопку нижче.",
"File is currently busy, please try again later" : "Файл на разі зайнятий, будь ласка, спробуйте пізніше",
"Cannot download file" : "Неможливо звантажити файл",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "Переконайтеся, що в корені каталогу даних є файл під назвою \".ocdata\"."
+ "Login is too long" : "Ім'я користувача для авторизації задовге"
},"pluralForm" :"nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != 11 ? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || (n % 100 >=11 && n % 100 <=14 )) ? 2: 3);"
} \ No newline at end of file
diff --git a/lib/l10n/ur_PK.js b/lib/l10n/ur_PK.js
index 0758c55ebe9..44d1c069b4d 100644
--- a/lib/l10n/ur_PK.js
+++ b/lib/l10n/ur_PK.js
@@ -31,7 +31,6 @@ OC.L10N.register(
"September" : "ستمبر",
"October" : "اکتوبر",
"November" : "نومبر",
- "December" : "دسمبر",
- "Users" : "یوزرز"
+ "December" : "دسمبر"
},
"nplurals=2; plural=(n != 1);");
diff --git a/lib/l10n/ur_PK.json b/lib/l10n/ur_PK.json
index e1cdfc9e1d5..dc156aa2bf6 100644
--- a/lib/l10n/ur_PK.json
+++ b/lib/l10n/ur_PK.json
@@ -29,7 +29,6 @@
"September" : "ستمبر",
"October" : "اکتوبر",
"November" : "نومبر",
- "December" : "دسمبر",
- "Users" : "یوزرز"
+ "December" : "دسمبر"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/lib/l10n/uz.js b/lib/l10n/uz.js
index b3d7be96b38..dbd52a84666 100644
--- a/lib/l10n/uz.js
+++ b/lib/l10n/uz.js
@@ -31,9 +31,7 @@ OC.L10N.register(
"Authentication error" : "Authentication error",
"Storage is temporarily not available" : "Storage is temporarily not available",
"Confirmation" : "Tasdiqlash",
- "Translate" : "Tarjima",
- "File name is too long" : "File name is too long",
- "Users" : "Users",
- "Open »%s«" : "ochish »%s«"
+ "Text" : "Matn",
+ "Translate" : "Tarjima"
},
"nplurals=1; plural=0;");
diff --git a/lib/l10n/uz.json b/lib/l10n/uz.json
index d032d72f931..4ead6aa936c 100644
--- a/lib/l10n/uz.json
+++ b/lib/l10n/uz.json
@@ -29,9 +29,7 @@
"Authentication error" : "Authentication error",
"Storage is temporarily not available" : "Storage is temporarily not available",
"Confirmation" : "Tasdiqlash",
- "Translate" : "Tarjima",
- "File name is too long" : "File name is too long",
- "Users" : "Users",
- "Open »%s«" : "ochish »%s«"
+ "Text" : "Matn",
+ "Translate" : "Tarjima"
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/lib/l10n/vi.js b/lib/l10n/vi.js
index 4a0ea6e39b0..28d695a47eb 100644
--- a/lib/l10n/vi.js
+++ b/lib/l10n/vi.js
@@ -103,10 +103,6 @@ OC.L10N.register(
"Storage is temporarily not available" : "Kho lưu trữ tạm thời không khả dụng",
"Text" : "Văn bản",
"Summary" : "Tóm tắt",
- "Translate" : "Dịch",
- "Education Edition" : "Bản Giáo dục",
- "Users" : "Người dùng",
- "Open »%s«" : "Mở »%s«",
- "Click the button below to open it." : "Bấm vào nút bên dưới để mở nó."
+ "Translate" : "Dịch"
},
"nplurals=1; plural=0;");
diff --git a/lib/l10n/vi.json b/lib/l10n/vi.json
index b8b5adc7de6..6982fd39e06 100644
--- a/lib/l10n/vi.json
+++ b/lib/l10n/vi.json
@@ -101,10 +101,6 @@
"Storage is temporarily not available" : "Kho lưu trữ tạm thời không khả dụng",
"Text" : "Văn bản",
"Summary" : "Tóm tắt",
- "Translate" : "Dịch",
- "Education Edition" : "Bản Giáo dục",
- "Users" : "Người dùng",
- "Open »%s«" : "Mở »%s«",
- "Click the button below to open it." : "Bấm vào nút bên dưới để mở nó."
+ "Translate" : "Dịch"
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/lib/l10n/zh_CN.js b/lib/l10n/zh_CN.js
index 818f0fdad18..7a2f7cca2a4 100644
--- a/lib/l10n/zh_CN.js
+++ b/lib/l10n/zh_CN.js
@@ -93,6 +93,8 @@ OC.L10N.register(
"Destination does not exist" : "目标不存在",
"Destination is not creatable" : "目标不可创建",
"Dot files are not allowed" : "以 . 开头的文件不被允许",
+ "%1$s (renamed)" : "%1$s(已重命名)",
+ "renamed file" : "已重命名文件",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" 是禁止的文件或文件夹名称。",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" 是文件或文件夹名称的禁止前缀。",
"\"%1$s\" is not allowed inside a file or folder name." : "文件或文件夹名称中不允许出现 \"%1$s\"。",
@@ -273,7 +275,7 @@ OC.L10N.register(
"A valid Login must be provided" : "必须提供有效的登录名",
"Login contains whitespace at the beginning or at the end" : "登录名开头或结尾包含空格",
"Login must not consist of dots only" : "登录名不能仅由点组成",
- "Login is too long" : "登录名太长",
+ "Username is too long" : "用户名太长",
"Login is invalid because files already exist for this user" : "登录无效,因为此用户的文件已存在",
"Account disabled" : "帐户已禁用",
"Login canceled by app" : "已通过应用取消登录",
@@ -364,6 +366,11 @@ OC.L10N.register(
"How many images to generate" : "生成多少张图片",
"Output images" : "输出图像",
"The generated images" : "生成的图像",
+ "Generate speech" : "生成语音",
+ "Generate speech from a transcript" : "从转录生成语音",
+ "Write transcript that you want the assistant to generate speech from" : "编写您想要助手从中生成语音的转录内容",
+ "Output speech" : "输出语音",
+ "The generated speech" : "生成的语音",
"Free text to text prompt" : "免费文本转文本提示",
"Runs an arbitrary prompt through a language model that returns a reply" : "通过语言模型运行任意提示并返回答复",
"Describe a task that you want the assistant to do or ask a question" : "描述你希望助手执行的任务或提出问题",
@@ -443,20 +450,8 @@ OC.L10N.register(
"Generate headline" : "生成标题",
"Summarizes text by reducing its length without losing key information." : "总结一段文本以减少长度而不丢失关键信息",
"Extracts topics from a text and outputs them separated by commas." : "从文本中摘出主题,输出逗号分隔的结果",
- "Education Edition" : "教育版",
- "File name is a reserved word" : "文件名包含敏感字符",
- "File name contains at least one invalid character" : "文件名中存在至少一个非法字符",
- "File name is too long" : "文件名过长",
- "Users" : "用户",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s 与您共享了 »%2$s« 并希望添加:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s 与您共享了 »%2$s« 并希望添加",
- "»%s« added a note to a file shared with you" : "»%s« 在与你共享的文件中添加了备注",
- "Open »%s«" : "打开 »%s«",
- "%1$s shared »%2$s« with you" : "%1$s 对您共享了 »%2$s«",
- "%1$s shared »%2$s« with you." : "%1$s 对您共享了 »%2$s«。",
- "Click the button below to open it." : "点击下方按钮可打开它。",
"File is currently busy, please try again later" : "文件当前正忙,请稍后再试",
"Cannot download file" : "无法下载文件",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "请确定在根目录下有一个名为\".ocdata\"的文件。"
+ "Login is too long" : "登录名太长"
},
"nplurals=1; plural=0;");
diff --git a/lib/l10n/zh_CN.json b/lib/l10n/zh_CN.json
index bc3d5081fdc..1727656ae7d 100644
--- a/lib/l10n/zh_CN.json
+++ b/lib/l10n/zh_CN.json
@@ -91,6 +91,8 @@
"Destination does not exist" : "目标不存在",
"Destination is not creatable" : "目标不可创建",
"Dot files are not allowed" : "以 . 开头的文件不被允许",
+ "%1$s (renamed)" : "%1$s(已重命名)",
+ "renamed file" : "已重命名文件",
"\"%1$s\" is a forbidden file or folder name." : "\"%1$s\" 是禁止的文件或文件夹名称。",
"\"%1$s\" is a forbidden prefix for file or folder names." : "\"%1$s\" 是文件或文件夹名称的禁止前缀。",
"\"%1$s\" is not allowed inside a file or folder name." : "文件或文件夹名称中不允许出现 \"%1$s\"。",
@@ -271,7 +273,7 @@
"A valid Login must be provided" : "必须提供有效的登录名",
"Login contains whitespace at the beginning or at the end" : "登录名开头或结尾包含空格",
"Login must not consist of dots only" : "登录名不能仅由点组成",
- "Login is too long" : "登录名太长",
+ "Username is too long" : "用户名太长",
"Login is invalid because files already exist for this user" : "登录无效,因为此用户的文件已存在",
"Account disabled" : "帐户已禁用",
"Login canceled by app" : "已通过应用取消登录",
@@ -362,6 +364,11 @@
"How many images to generate" : "生成多少张图片",
"Output images" : "输出图像",
"The generated images" : "生成的图像",
+ "Generate speech" : "生成语音",
+ "Generate speech from a transcript" : "从转录生成语音",
+ "Write transcript that you want the assistant to generate speech from" : "编写您想要助手从中生成语音的转录内容",
+ "Output speech" : "输出语音",
+ "The generated speech" : "生成的语音",
"Free text to text prompt" : "免费文本转文本提示",
"Runs an arbitrary prompt through a language model that returns a reply" : "通过语言模型运行任意提示并返回答复",
"Describe a task that you want the assistant to do or ask a question" : "描述你希望助手执行的任务或提出问题",
@@ -441,20 +448,8 @@
"Generate headline" : "生成标题",
"Summarizes text by reducing its length without losing key information." : "总结一段文本以减少长度而不丢失关键信息",
"Extracts topics from a text and outputs them separated by commas." : "从文本中摘出主题,输出逗号分隔的结果",
- "Education Edition" : "教育版",
- "File name is a reserved word" : "文件名包含敏感字符",
- "File name contains at least one invalid character" : "文件名中存在至少一个非法字符",
- "File name is too long" : "文件名过长",
- "Users" : "用户",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s 与您共享了 »%2$s« 并希望添加:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s 与您共享了 »%2$s« 并希望添加",
- "»%s« added a note to a file shared with you" : "»%s« 在与你共享的文件中添加了备注",
- "Open »%s«" : "打开 »%s«",
- "%1$s shared »%2$s« with you" : "%1$s 对您共享了 »%2$s«",
- "%1$s shared »%2$s« with you." : "%1$s 对您共享了 »%2$s«。",
- "Click the button below to open it." : "点击下方按钮可打开它。",
"File is currently busy, please try again later" : "文件当前正忙,请稍后再试",
"Cannot download file" : "无法下载文件",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "请确定在根目录下有一个名为\".ocdata\"的文件。"
+ "Login is too long" : "登录名太长"
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/lib/l10n/zh_HK.js b/lib/l10n/zh_HK.js
index 7a98e4b4905..17c629aba08 100644
--- a/lib/l10n/zh_HK.js
+++ b/lib/l10n/zh_HK.js
@@ -93,6 +93,8 @@ OC.L10N.register(
"Destination does not exist" : "目的地不存在",
"Destination is not creatable" : "無法建立目的地",
"Dot files are not allowed" : "不允許小數點開頭的檔案",
+ "%1$s (renamed)" : "%1$s(已重新命名)",
+ "renamed file" : "已重新命名的檔案",
"\"%1$s\" is a forbidden file or folder name." : "「%1$s」是禁止的檔案或資料夾名稱。",
"\"%1$s\" is a forbidden prefix for file or folder names." : "「%1$s」是禁止的檔案或資料夾名稱前綴。",
"\"%1$s\" is not allowed inside a file or folder name." : "「%1$s」不允許出現在檔案或資料夾名稱中。",
@@ -201,6 +203,7 @@ OC.L10N.register(
"Path is already shared with this group" : "已與此群組分享了路徑",
"Link sharing is not allowed" : "不允許連結分享",
"Public upload is not allowed" : "不允許公開上傳",
+ "You cannot share a folder that contains other shares" : "您無法分享包含其他分享的資料夾",
"Sharing is disabled" : "已停用分享",
"Sharing is disabled for you" : "您已停用分享",
"Cannot share with the share owner" : "無法與分享擁有者分享",
@@ -272,6 +275,7 @@ OC.L10N.register(
"A valid Login must be provided" : "必須提供有效帳戶",
"Login contains whitespace at the beginning or at the end" : "帳戶的開頭或結尾有空白",
"Login must not consist of dots only" : "帳戶不能只包含小數點",
+ "Username is too long" : "用戶名稱太長",
"Login is invalid because files already exist for this user" : "帳戶無效,因為此用戶的檔案已經存在",
"Account disabled" : "帳戶已停用",
"Login canceled by app" : "登入已被應用程式取消",
@@ -362,6 +366,11 @@ OC.L10N.register(
"How many images to generate" : "要產生多少圖像",
"Output images" : "輸出圖像",
"The generated images" : "產生的圖像",
+ "Generate speech" : "產生語音",
+ "Generate speech from a transcript" : "從文字稿産生語音",
+ "Write transcript that you want the assistant to generate speech from" : "寫下您想要小幫手產生語音的文字稿",
+ "Output speech" : "輸出語音",
+ "The generated speech" : "產生的語音",
"Free text to text prompt" : "文字提示的自由文字",
"Runs an arbitrary prompt through a language model that returns a reply" : "透過回傳回覆的語言模型執行任意提示",
"Describe a task that you want the assistant to do or ask a question" : "描述您希望助理執行的任務或提出問題",
@@ -441,20 +450,8 @@ OC.L10N.register(
"Generate headline" : "産生標題",
"Summarizes text by reducing its length without losing key information." : "通過減少文字長度來總結而不丟失關鍵資訊。",
"Extracts topics from a text and outputs them separated by commas." : "從文字中提取主題並輸出,並用逗號分隔。",
- "Education Edition" : "教育版",
- "File name is a reserved word" : "檔案名稱是保留字",
- "File name contains at least one invalid character" : "檔案名稱含有不允許的字元",
- "File name is too long" : "檔案名稱太長",
- "Users" : "用戶",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s 與您分享了 %2$s ,且想要加入:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s 與您分享了 %2$s ,且想要加入",
- "»%s« added a note to a file shared with you" : "%s 在與您分享的檔案中加入了註解",
- "Open »%s«" : "開啟 »%s«",
- "%1$s shared »%2$s« with you" : "%1$s 與您分享了 %2$s",
- "%1$s shared »%2$s« with you." : "%1$s 與您分享了 %2$s",
- "Click the button below to open it." : "點下方連結開啟",
"File is currently busy, please try again later" : "檔案目前忙碌中,請稍候再試",
"Cannot download file" : "無法下載檔案",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "請確保資料目錄最上層有一個 \"。ocdata\" 檔案"
+ "Login is too long" : "帳號太長了"
},
"nplurals=1; plural=0;");
diff --git a/lib/l10n/zh_HK.json b/lib/l10n/zh_HK.json
index 94658c90974..b2ef29118b8 100644
--- a/lib/l10n/zh_HK.json
+++ b/lib/l10n/zh_HK.json
@@ -91,6 +91,8 @@
"Destination does not exist" : "目的地不存在",
"Destination is not creatable" : "無法建立目的地",
"Dot files are not allowed" : "不允許小數點開頭的檔案",
+ "%1$s (renamed)" : "%1$s(已重新命名)",
+ "renamed file" : "已重新命名的檔案",
"\"%1$s\" is a forbidden file or folder name." : "「%1$s」是禁止的檔案或資料夾名稱。",
"\"%1$s\" is a forbidden prefix for file or folder names." : "「%1$s」是禁止的檔案或資料夾名稱前綴。",
"\"%1$s\" is not allowed inside a file or folder name." : "「%1$s」不允許出現在檔案或資料夾名稱中。",
@@ -199,6 +201,7 @@
"Path is already shared with this group" : "已與此群組分享了路徑",
"Link sharing is not allowed" : "不允許連結分享",
"Public upload is not allowed" : "不允許公開上傳",
+ "You cannot share a folder that contains other shares" : "您無法分享包含其他分享的資料夾",
"Sharing is disabled" : "已停用分享",
"Sharing is disabled for you" : "您已停用分享",
"Cannot share with the share owner" : "無法與分享擁有者分享",
@@ -270,6 +273,7 @@
"A valid Login must be provided" : "必須提供有效帳戶",
"Login contains whitespace at the beginning or at the end" : "帳戶的開頭或結尾有空白",
"Login must not consist of dots only" : "帳戶不能只包含小數點",
+ "Username is too long" : "用戶名稱太長",
"Login is invalid because files already exist for this user" : "帳戶無效,因為此用戶的檔案已經存在",
"Account disabled" : "帳戶已停用",
"Login canceled by app" : "登入已被應用程式取消",
@@ -360,6 +364,11 @@
"How many images to generate" : "要產生多少圖像",
"Output images" : "輸出圖像",
"The generated images" : "產生的圖像",
+ "Generate speech" : "產生語音",
+ "Generate speech from a transcript" : "從文字稿産生語音",
+ "Write transcript that you want the assistant to generate speech from" : "寫下您想要小幫手產生語音的文字稿",
+ "Output speech" : "輸出語音",
+ "The generated speech" : "產生的語音",
"Free text to text prompt" : "文字提示的自由文字",
"Runs an arbitrary prompt through a language model that returns a reply" : "透過回傳回覆的語言模型執行任意提示",
"Describe a task that you want the assistant to do or ask a question" : "描述您希望助理執行的任務或提出問題",
@@ -439,20 +448,8 @@
"Generate headline" : "産生標題",
"Summarizes text by reducing its length without losing key information." : "通過減少文字長度來總結而不丟失關鍵資訊。",
"Extracts topics from a text and outputs them separated by commas." : "從文字中提取主題並輸出,並用逗號分隔。",
- "Education Edition" : "教育版",
- "File name is a reserved word" : "檔案名稱是保留字",
- "File name contains at least one invalid character" : "檔案名稱含有不允許的字元",
- "File name is too long" : "檔案名稱太長",
- "Users" : "用戶",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s 與您分享了 %2$s ,且想要加入:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s 與您分享了 %2$s ,且想要加入",
- "»%s« added a note to a file shared with you" : "%s 在與您分享的檔案中加入了註解",
- "Open »%s«" : "開啟 »%s«",
- "%1$s shared »%2$s« with you" : "%1$s 與您分享了 %2$s",
- "%1$s shared »%2$s« with you." : "%1$s 與您分享了 %2$s",
- "Click the button below to open it." : "點下方連結開啟",
"File is currently busy, please try again later" : "檔案目前忙碌中,請稍候再試",
"Cannot download file" : "無法下載檔案",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "請確保資料目錄最上層有一個 \"。ocdata\" 檔案"
+ "Login is too long" : "帳號太長了"
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/lib/l10n/zh_TW.js b/lib/l10n/zh_TW.js
index 95a20523c8f..196cb52767f 100644
--- a/lib/l10n/zh_TW.js
+++ b/lib/l10n/zh_TW.js
@@ -93,6 +93,8 @@ OC.L10N.register(
"Destination does not exist" : "目的地不存在",
"Destination is not creatable" : "無法建立目的地",
"Dot files are not allowed" : "不允許小數點開頭的檔案",
+ "%1$s (renamed)" : "%1$s(已重新命名)",
+ "renamed file" : "已重新命名檔案",
"\"%1$s\" is a forbidden file or folder name." : "「%1$s」是禁止的檔案或資料夾名稱。",
"\"%1$s\" is a forbidden prefix for file or folder names." : "「%1$s」是禁止的檔案或資料夾名稱前綴。",
"\"%1$s\" is not allowed inside a file or folder name." : "「%1$s」不允許出現在檔案或資料夾名稱中。",
@@ -273,7 +275,7 @@ OC.L10N.register(
"A valid Login must be provided" : "必須提供有效帳號",
"Login contains whitespace at the beginning or at the end" : "帳號的開頭或結尾有空白",
"Login must not consist of dots only" : "帳號不能只包含小數點",
- "Login is too long" : "帳號太長了",
+ "Username is too long" : "使用者名稱太長了",
"Login is invalid because files already exist for this user" : "帳號無效,因為使用者的檔案已經存在",
"Account disabled" : "帳號已停用",
"Login canceled by app" : "應用程式取消了登入",
@@ -364,6 +366,11 @@ OC.L10N.register(
"How many images to generate" : "要產生多少影像",
"Output images" : "輸出影像",
"The generated images" : "產生的影像",
+ "Generate speech" : "產生語音",
+ "Generate speech from a transcript" : "從轉錄稿產生語音",
+ "Write transcript that you want the assistant to generate speech from" : "寫下您想要小幫手產生語音的來源轉錄稿",
+ "Output speech" : "輸出語音",
+ "The generated speech" : "產生的語音",
"Free text to text prompt" : "文字提示的自由文字",
"Runs an arbitrary prompt through a language model that returns a reply" : "透過回傳回覆的語言模型執行任意提示",
"Describe a task that you want the assistant to do or ask a question" : "描述您希望助理執行的任務或提出問題",
@@ -443,20 +450,8 @@ OC.L10N.register(
"Generate headline" : "生成標題",
"Summarizes text by reducing its length without losing key information." : "寫成摘要,減少文字長度而不丟失關鍵資訊。",
"Extracts topics from a text and outputs them separated by commas." : "從文字中取出涵蓋的主題並輸出,然後用逗號分隔。",
- "Education Edition" : "教育版",
- "File name is a reserved word" : "檔案名稱是保留字",
- "File name contains at least one invalid character" : "檔案名稱含有不允許的字元",
- "File name is too long" : "檔案名稱太長",
- "Users" : "使用者",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s 與您分享了「%2$s 」,且想要新增:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s 與您分享了「%2$s」,且想要新增",
- "»%s« added a note to a file shared with you" : "「%s」在與您分享的檔案中加入了備註",
- "Open »%s«" : "開啟「%s」",
- "%1$s shared »%2$s« with you" : "%1$s 與您分享了「%2$s」",
- "%1$s shared »%2$s« with you." : "%1$s 與您分享了「%2$s」。",
- "Click the button below to open it." : "點擊下方的按鈕將其打開。",
"File is currently busy, please try again later" : "檔案目前忙碌中,請稍候再試",
"Cannot download file" : "無法下載檔案",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "請確保資料目錄最上層有一個「.ocdata」檔案。"
+ "Login is too long" : "帳號太長了"
},
"nplurals=1; plural=0;");
diff --git a/lib/l10n/zh_TW.json b/lib/l10n/zh_TW.json
index b9af7705ef9..5bde18ad24d 100644
--- a/lib/l10n/zh_TW.json
+++ b/lib/l10n/zh_TW.json
@@ -91,6 +91,8 @@
"Destination does not exist" : "目的地不存在",
"Destination is not creatable" : "無法建立目的地",
"Dot files are not allowed" : "不允許小數點開頭的檔案",
+ "%1$s (renamed)" : "%1$s(已重新命名)",
+ "renamed file" : "已重新命名檔案",
"\"%1$s\" is a forbidden file or folder name." : "「%1$s」是禁止的檔案或資料夾名稱。",
"\"%1$s\" is a forbidden prefix for file or folder names." : "「%1$s」是禁止的檔案或資料夾名稱前綴。",
"\"%1$s\" is not allowed inside a file or folder name." : "「%1$s」不允許出現在檔案或資料夾名稱中。",
@@ -271,7 +273,7 @@
"A valid Login must be provided" : "必須提供有效帳號",
"Login contains whitespace at the beginning or at the end" : "帳號的開頭或結尾有空白",
"Login must not consist of dots only" : "帳號不能只包含小數點",
- "Login is too long" : "帳號太長了",
+ "Username is too long" : "使用者名稱太長了",
"Login is invalid because files already exist for this user" : "帳號無效,因為使用者的檔案已經存在",
"Account disabled" : "帳號已停用",
"Login canceled by app" : "應用程式取消了登入",
@@ -362,6 +364,11 @@
"How many images to generate" : "要產生多少影像",
"Output images" : "輸出影像",
"The generated images" : "產生的影像",
+ "Generate speech" : "產生語音",
+ "Generate speech from a transcript" : "從轉錄稿產生語音",
+ "Write transcript that you want the assistant to generate speech from" : "寫下您想要小幫手產生語音的來源轉錄稿",
+ "Output speech" : "輸出語音",
+ "The generated speech" : "產生的語音",
"Free text to text prompt" : "文字提示的自由文字",
"Runs an arbitrary prompt through a language model that returns a reply" : "透過回傳回覆的語言模型執行任意提示",
"Describe a task that you want the assistant to do or ask a question" : "描述您希望助理執行的任務或提出問題",
@@ -441,20 +448,8 @@
"Generate headline" : "生成標題",
"Summarizes text by reducing its length without losing key information." : "寫成摘要,減少文字長度而不丟失關鍵資訊。",
"Extracts topics from a text and outputs them separated by commas." : "從文字中取出涵蓋的主題並輸出,然後用逗號分隔。",
- "Education Edition" : "教育版",
- "File name is a reserved word" : "檔案名稱是保留字",
- "File name contains at least one invalid character" : "檔案名稱含有不允許的字元",
- "File name is too long" : "檔案名稱太長",
- "Users" : "使用者",
- "%1$s shared »%2$s« with you and wants to add:" : "%1$s 與您分享了「%2$s 」,且想要新增:",
- "%1$s shared »%2$s« with you and wants to add" : "%1$s 與您分享了「%2$s」,且想要新增",
- "»%s« added a note to a file shared with you" : "「%s」在與您分享的檔案中加入了備註",
- "Open »%s«" : "開啟「%s」",
- "%1$s shared »%2$s« with you" : "%1$s 與您分享了「%2$s」",
- "%1$s shared »%2$s« with you." : "%1$s 與您分享了「%2$s」。",
- "Click the button below to open it." : "點擊下方的按鈕將其打開。",
"File is currently busy, please try again later" : "檔案目前忙碌中,請稍候再試",
"Cannot download file" : "無法下載檔案",
- "Ensure there is a file called \".ocdata\" in the root of the data directory." : "請確保資料目錄最上層有一個「.ocdata」檔案。"
+ "Login is too long" : "帳號太長了"
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/lib/private/Accounts/AccountManager.php b/lib/private/Accounts/AccountManager.php
index d69e72a29de..e8b67311636 100644
--- a/lib/private/Accounts/AccountManager.php
+++ b/lib/private/Accounts/AccountManager.php
@@ -131,9 +131,7 @@ class AccountManager implements IAccountManager {
$property->setScope(self::SCOPE_LOCAL);
}
} else {
- // migrate scope values to the new format
- // invalid scopes are mapped to a default value
- $property->setScope(AccountProperty::mapScopeToV2($property->getScope()));
+ $property->setScope($property->getScope());
}
}
diff --git a/lib/private/Accounts/AccountProperty.php b/lib/private/Accounts/AccountProperty.php
index 0c4ad568709..3a89e9bbc7a 100644
--- a/lib/private/Accounts/AccountProperty.php
+++ b/lib/private/Accounts/AccountProperty.php
@@ -55,16 +55,11 @@ class AccountProperty implements IAccountProperty {
* @since 15.0.0
*/
public function setScope(string $scope): IAccountProperty {
- $newScope = $this->mapScopeToV2($scope);
- if (!in_array($newScope, [
- IAccountManager::SCOPE_LOCAL,
- IAccountManager::SCOPE_FEDERATED,
- IAccountManager::SCOPE_PRIVATE,
- IAccountManager::SCOPE_PUBLISHED
- ])) {
+ if (!in_array($scope, IAccountManager::ALLOWED_SCOPES, )) {
throw new InvalidArgumentException('Invalid scope');
}
- $this->scope = $newScope;
+ /** @var IAccountManager::SCOPE_* $scope */
+ $this->scope = $scope;
return $this;
}
@@ -105,19 +100,6 @@ class AccountProperty implements IAccountProperty {
return $this->scope;
}
- public static function mapScopeToV2(string $scope): string {
- if (str_starts_with($scope, 'v2-')) {
- return $scope;
- }
-
- return match ($scope) {
- IAccountManager::VISIBILITY_PRIVATE, '' => IAccountManager::SCOPE_LOCAL,
- IAccountManager::VISIBILITY_CONTACTS_ONLY => IAccountManager::SCOPE_FEDERATED,
- IAccountManager::VISIBILITY_PUBLIC => IAccountManager::SCOPE_PUBLISHED,
- default => $scope,
- };
- }
-
/**
* Get the verification status of a property
*
diff --git a/lib/private/App/AppManager.php b/lib/private/App/AppManager.php
index f6494fa946d..eb4700020d2 100644
--- a/lib/private/App/AppManager.php
+++ b/lib/private/App/AppManager.php
@@ -8,6 +8,7 @@ namespace OC\App;
use OC\AppConfig;
use OC\AppFramework\Bootstrap\Coordinator;
+use OC\Config\ConfigManager;
use OCP\Activity\IManager as IActivityManager;
use OCP\App\AppPathNotFoundException;
use OCP\App\Events\AppDisableEvent;
@@ -18,6 +19,7 @@ use OCP\Collaboration\AutoComplete\IManager as IAutoCompleteManager;
use OCP\Collaboration\Collaborators\ISearch as ICollaboratorSearch;
use OCP\Diagnostics\IEventLogger;
use OCP\EventDispatcher\IEventDispatcher;
+use OCP\IAppConfig;
use OCP\ICacheFactory;
use OCP\IConfig;
use OCP\IGroup;
@@ -26,6 +28,7 @@ use OCP\INavigationManager;
use OCP\IURLGenerator;
use OCP\IUser;
use OCP\IUserSession;
+use OCP\Server;
use OCP\ServerVersion;
use OCP\Settings\IManager as ISettingsManager;
use Psr\Log\LoggerInterface;
@@ -81,12 +84,13 @@ class AppManager implements IAppManager {
private IEventDispatcher $dispatcher,
private LoggerInterface $logger,
private ServerVersion $serverVersion,
+ private ConfigManager $configManager,
) {
}
private function getNavigationManager(): INavigationManager {
if ($this->navigationManager === null) {
- $this->navigationManager = \OCP\Server::get(INavigationManager::class);
+ $this->navigationManager = Server::get(INavigationManager::class);
}
return $this->navigationManager;
}
@@ -112,7 +116,7 @@ class AppManager implements IAppManager {
if (!$this->config->getSystemValueBool('installed', false)) {
throw new \Exception('Nextcloud is not installed yet, AppConfig is not available');
}
- $this->appConfig = \OCP\Server::get(AppConfig::class);
+ $this->appConfig = Server::get(AppConfig::class);
return $this->appConfig;
}
@@ -123,7 +127,7 @@ class AppManager implements IAppManager {
if (!$this->config->getSystemValueBool('installed', false)) {
throw new \Exception('Nextcloud is not installed yet, AppConfig is not available');
}
- $this->urlGenerator = \OCP\Server::get(IURLGenerator::class);
+ $this->urlGenerator = Server::get(IURLGenerator::class);
return $this->urlGenerator;
}
@@ -134,7 +138,8 @@ class AppManager implements IAppManager {
*/
private function getEnabledAppsValues(): array {
if (!$this->enabledAppsCache) {
- $values = $this->getAppConfig()->getValues(false, 'enabled');
+ /** @var array<string,string> */
+ $values = $this->getAppConfig()->searchValues('enabled', false, IAppConfig::VALUE_STRING);
$alwaysEnabledApps = $this->getAlwaysEnabledApps();
foreach ($alwaysEnabledApps as $appId) {
@@ -202,7 +207,7 @@ class AppManager implements IAppManager {
* List all apps enabled for a user
*
* @param \OCP\IUser $user
- * @return string[]
+ * @return list<string>
*/
public function getEnabledAppsForUser(IUser $user) {
$apps = $this->getEnabledAppsValues();
@@ -457,7 +462,7 @@ class AppManager implements IAppManager {
]);
}
- $coordinator = \OCP\Server::get(Coordinator::class);
+ $coordinator = Server::get(Coordinator::class);
$coordinator->bootApp($app);
$eventLogger->start("bootstrap:load_app:$app:info", "Load info.xml for $app and register any services defined in it");
@@ -545,11 +550,16 @@ class AppManager implements IAppManager {
* @param string $appId
* @param bool $forceEnable
* @throws AppPathNotFoundException
+ * @throws \InvalidArgumentException if the application is not installed yet
*/
public function enableApp(string $appId, bool $forceEnable = false): void {
// Check if app exists
$this->getAppPath($appId);
+ if ($this->config->getAppValue($appId, 'installed_version', '') === '') {
+ throw new \InvalidArgumentException("$appId is not installed, cannot be enabled.");
+ }
+
if ($forceEnable) {
$this->overwriteNextcloudRequirement($appId);
}
@@ -561,6 +571,8 @@ class AppManager implements IAppManager {
ManagerEvent::EVENT_APP_ENABLE, $appId
));
$this->clearAppsCache();
+
+ $this->configManager->migrateConfigLexiconKeys($appId);
}
/**
@@ -596,6 +608,10 @@ class AppManager implements IAppManager {
throw new \InvalidArgumentException("$appId can't be enabled for groups.");
}
+ if ($this->config->getAppValue($appId, 'installed_version', '') === '') {
+ throw new \InvalidArgumentException("$appId is not installed, cannot be enabled.");
+ }
+
if ($forceEnable) {
$this->overwriteNextcloudRequirement($appId);
}
@@ -615,6 +631,8 @@ class AppManager implements IAppManager {
ManagerEvent::EVENT_APP_ENABLE_FOR_GROUPS, $appId, $groups
));
$this->clearAppsCache();
+
+ $this->configManager->migrateConfigLexiconKeys($appId);
}
/**
@@ -775,8 +793,8 @@ class AppManager implements IAppManager {
*
* @return array<string, string>
*/
- public function getAppInstalledVersions(): array {
- return $this->getAppConfig()->getAppInstalledVersions();
+ public function getAppInstalledVersions(bool $onlyEnabled = false): array {
+ return $this->getAppConfig()->getAppInstalledVersions($onlyEnabled);
}
/**
@@ -812,6 +830,10 @@ class AppManager implements IAppManager {
}
private function isAlwaysEnabled(string $appId): bool {
+ if ($appId === 'core') {
+ return true;
+ }
+
$alwaysEnabled = $this->getAlwaysEnabledApps();
return in_array($appId, $alwaysEnabled, true);
}
diff --git a/lib/private/App/AppStore/AppNotFoundException.php b/lib/private/App/AppStore/AppNotFoundException.php
new file mode 100644
index 00000000000..79ceebb4423
--- /dev/null
+++ b/lib/private/App/AppStore/AppNotFoundException.php
@@ -0,0 +1,13 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace OC\App\AppStore;
+
+class AppNotFoundException extends \Exception {
+}
diff --git a/lib/private/AppConfig.php b/lib/private/AppConfig.php
index 092d37c3338..b6412b410bb 100644
--- a/lib/private/AppConfig.php
+++ b/lib/private/AppConfig.php
@@ -15,6 +15,7 @@ use NCU\Config\Lexicon\ConfigLexiconEntry;
use NCU\Config\Lexicon\ConfigLexiconStrictness;
use NCU\Config\Lexicon\IConfigLexicon;
use OC\AppFramework\Bootstrap\Coordinator;
+use OC\Config\ConfigManager;
use OCP\DB\Exception as DBException;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Exceptions\AppConfigIncorrectTypeException;
@@ -24,6 +25,7 @@ use OCP\IAppConfig;
use OCP\IConfig;
use OCP\IDBConnection;
use OCP\Security\ICrypto;
+use OCP\Server;
use Psr\Log\LoggerInterface;
/**
@@ -59,8 +61,9 @@ class AppConfig implements IAppConfig {
private array $valueTypes = []; // type for all config values
private bool $fastLoaded = false;
private bool $lazyLoaded = false;
- /** @var array<array-key, array{entries: array<array-key, ConfigLexiconEntry>, strictness: ConfigLexiconStrictness}> ['app_id' => ['strictness' => ConfigLexiconStrictness, 'entries' => ['config_key' => ConfigLexiconEntry[]]] */
+ /** @var array<string, array{entries: array<string, ConfigLexiconEntry>, aliases: array<string, string>, strictness: ConfigLexiconStrictness}> ['app_id' => ['strictness' => ConfigLexiconStrictness, 'entries' => ['config_key' => ConfigLexiconEntry[]]] */
private array $configLexiconDetails = [];
+ private bool $ignoreLexiconAliases = false;
/** @var ?array<string, string> */
private ?array $appVersionsCache = null;
@@ -117,6 +120,7 @@ class AppConfig implements IAppConfig {
public function hasKey(string $app, string $key, ?bool $lazy = false): bool {
$this->assertParams($app, $key);
$this->loadConfig($app, $lazy);
+ $this->matchAndApplyLexiconDefinition($app, $key);
if ($lazy === null) {
$appCache = $this->getAllValues($app);
@@ -142,6 +146,7 @@ class AppConfig implements IAppConfig {
public function isSensitive(string $app, string $key, ?bool $lazy = false): bool {
$this->assertParams($app, $key);
$this->loadConfig(null, $lazy);
+ $this->matchAndApplyLexiconDefinition($app, $key);
if (!isset($this->valueTypes[$app][$key])) {
throw new AppConfigUnknownKeyException('unknown config key');
@@ -162,6 +167,9 @@ class AppConfig implements IAppConfig {
* @since 29.0.0
*/
public function isLazy(string $app, string $key): bool {
+ $this->assertParams($app, $key);
+ $this->matchAndApplyLexiconDefinition($app, $key);
+
// there is a huge probability the non-lazy config are already loaded
if ($this->hasKey($app, $key, false)) {
return false;
@@ -284,7 +292,7 @@ class AppConfig implements IAppConfig {
): string {
try {
$lazy = ($lazy === null) ? $this->isLazy($app, $key) : $lazy;
- } catch (AppConfigUnknownKeyException $e) {
+ } catch (AppConfigUnknownKeyException) {
return $default;
}
@@ -429,6 +437,7 @@ class AppConfig implements IAppConfig {
int $type,
): string {
$this->assertParams($app, $key, valueType: $type);
+ $origKey = $key;
if (!$this->matchAndApplyLexiconDefinition($app, $key, $lazy, $type, $default)) {
return $default; // returns default if strictness of lexicon is set to WARNING (block and report)
}
@@ -469,6 +478,14 @@ class AppConfig implements IAppConfig {
$value = $this->crypto->decrypt(substr($value, self::ENCRYPTION_PREFIX_LENGTH));
}
+ // in case the key was modified while running matchAndApplyLexiconDefinition() we are
+ // interested to check options in case a modification of the value is needed
+ // ie inverting value from previous key when using lexicon option RENAME_INVERT_BOOLEAN
+ if ($origKey !== $key && $type === self::VALUE_BOOL) {
+ $configManager = Server::get(ConfigManager::class);
+ $value = ($configManager->convertToBool($value, $this->getLexiconEntry($app, $key))) ? '1' : '0';
+ }
+
return $value;
}
@@ -488,6 +505,14 @@ class AppConfig implements IAppConfig {
* @see VALUE_ARRAY
*/
public function getValueType(string $app, string $key, ?bool $lazy = null): int {
+ $type = self::VALUE_MIXED;
+ $ignorable = $lazy ?? false;
+ $this->matchAndApplyLexiconDefinition($app, $key, $ignorable, $type);
+ if ($type !== self::VALUE_MIXED) {
+ // a modified $type means config key is set in Lexicon
+ return $type;
+ }
+
$this->assertParams($app, $key);
$this->loadConfig($app, $lazy);
@@ -855,7 +880,8 @@ class AppConfig implements IAppConfig {
public function updateType(string $app, string $key, int $type = self::VALUE_MIXED): bool {
$this->assertParams($app, $key);
$this->loadConfigAll();
- $lazy = $this->isLazy($app, $key);
+ $this->matchAndApplyLexiconDefinition($app, $key);
+ $this->isLazy($app, $key); // confirm key exists
// type can only be one type
if (!in_array($type, [self::VALUE_MIXED, self::VALUE_STRING, self::VALUE_INT, self::VALUE_FLOAT, self::VALUE_BOOL, self::VALUE_ARRAY])) {
@@ -897,6 +923,7 @@ class AppConfig implements IAppConfig {
public function updateSensitive(string $app, string $key, bool $sensitive): bool {
$this->assertParams($app, $key);
$this->loadConfigAll();
+ $this->matchAndApplyLexiconDefinition($app, $key);
try {
if ($sensitive === $this->isSensitive($app, $key, null)) {
@@ -956,6 +983,7 @@ class AppConfig implements IAppConfig {
public function updateLazy(string $app, string $key, bool $lazy): bool {
$this->assertParams($app, $key);
$this->loadConfigAll();
+ $this->matchAndApplyLexiconDefinition($app, $key);
try {
if ($lazy === $this->isLazy($app, $key)) {
@@ -991,6 +1019,7 @@ class AppConfig implements IAppConfig {
public function getDetails(string $app, string $key): array {
$this->assertParams($app, $key);
$this->loadConfigAll();
+ $this->matchAndApplyLexiconDefinition($app, $key);
$lazy = $this->isLazy($app, $key);
if ($lazy) {
@@ -1078,6 +1107,8 @@ class AppConfig implements IAppConfig {
*/
public function deleteKey(string $app, string $key): void {
$this->assertParams($app, $key);
+ $this->matchAndApplyLexiconDefinition($app, $key);
+
$qb = $this->connection->getQueryBuilder();
$qb->delete('appconfig')
->where($qb->expr()->eq('appid', $qb->createNamedParameter($app)))
@@ -1285,6 +1316,7 @@ class AppConfig implements IAppConfig {
*/
public function getValue($app, $key, $default = null) {
$this->loadConfig($app);
+ $this->matchAndApplyLexiconDefinition($app, $key);
return $this->fastCache[$app][$key] ?? $default;
}
@@ -1364,7 +1396,7 @@ class AppConfig implements IAppConfig {
foreach ($values as $key => $value) {
try {
$type = $this->getValueType($app, $key, $lazy);
- } catch (AppConfigUnknownKeyException $e) {
+ } catch (AppConfigUnknownKeyException) {
continue;
}
@@ -1548,7 +1580,8 @@ class AppConfig implements IAppConfig {
}
/**
- * match and apply current use of config values with defined lexicon
+ * Match and apply current use of config values with defined lexicon.
+ * Set $lazy to NULL only if only interested into checking that $key is alias.
*
* @throws AppConfigUnknownKeyException
* @throws AppConfigTypeConflictException
@@ -1556,9 +1589,9 @@ class AppConfig implements IAppConfig {
*/
private function matchAndApplyLexiconDefinition(
string $app,
- string $key,
- bool &$lazy,
- int &$type,
+ string &$key,
+ ?bool &$lazy = null,
+ int &$type = self::VALUE_MIXED,
string &$default = '',
): bool {
if (in_array($key,
@@ -1570,11 +1603,18 @@ class AppConfig implements IAppConfig {
return true; // we don't break stuff for this list of config keys.
}
$configDetails = $this->getConfigDetailsFromLexicon($app);
+ if (array_key_exists($key, $configDetails['aliases']) && !$this->ignoreLexiconAliases) {
+ // in case '$rename' is set in ConfigLexiconEntry, we use the new config key
+ $key = $configDetails['aliases'][$key];
+ }
+
if (!array_key_exists($key, $configDetails['entries'])) {
- return $this->applyLexiconStrictness(
- $configDetails['strictness'],
- 'The app config key ' . $app . '/' . $key . ' is not defined in the config lexicon'
- );
+ return $this->applyLexiconStrictness($configDetails['strictness'], 'The app config key ' . $app . '/' . $key . ' is not defined in the config lexicon');
+ }
+
+ // if lazy is NULL, we ignore all check on the type/lazyness/default from Lexicon
+ if ($lazy === null) {
+ return true;
}
/** @var ConfigLexiconEntry $configValue */
@@ -1636,20 +1676,25 @@ class AppConfig implements IAppConfig {
* extract details from registered $appId's config lexicon
*
* @param string $appId
+ * @internal
*
- * @return array{entries: array<array-key, ConfigLexiconEntry>, strictness: ConfigLexiconStrictness}
+ * @return array{entries: array<string, ConfigLexiconEntry>, aliases: array<string, string>, strictness: ConfigLexiconStrictness}
*/
- private function getConfigDetailsFromLexicon(string $appId): array {
+ public function getConfigDetailsFromLexicon(string $appId): array {
if (!array_key_exists($appId, $this->configLexiconDetails)) {
- $entries = [];
+ $entries = $aliases = [];
$bootstrapCoordinator = \OCP\Server::get(Coordinator::class);
$configLexicon = $bootstrapCoordinator->getRegistrationContext()?->getConfigLexicon($appId);
foreach ($configLexicon?->getAppConfigs() ?? [] as $configEntry) {
$entries[$configEntry->getKey()] = $configEntry;
+ if ($configEntry->getRename() !== null) {
+ $aliases[$configEntry->getRename()] = $configEntry->getKey();
+ }
}
$this->configLexiconDetails[$appId] = [
'entries' => $entries,
+ 'aliases' => $aliases,
'strictness' => $configLexicon?->getStrictness() ?? ConfigLexiconStrictness::IGNORE
];
}
@@ -1657,16 +1702,36 @@ class AppConfig implements IAppConfig {
return $this->configLexiconDetails[$appId];
}
+ private function getLexiconEntry(string $appId, string $key): ?ConfigLexiconEntry {
+ return $this->getConfigDetailsFromLexicon($appId)['entries'][$key] ?? null;
+ }
+
+ /**
+ * if set to TRUE, ignore aliases defined in Config Lexicon during the use of the methods of this class
+ *
+ * @internal
+ */
+ public function ignoreLexiconAliases(bool $ignore): void {
+ $this->ignoreLexiconAliases = $ignore;
+ }
+
/**
* Returns the installed versions of all apps
*
* @return array<string, string>
*/
- public function getAppInstalledVersions(): array {
+ public function getAppInstalledVersions(bool $onlyEnabled = false): array {
if ($this->appVersionsCache === null) {
/** @var array<string, string> */
$this->appVersionsCache = $this->searchValues('installed_version', false, IAppConfig::VALUE_STRING);
}
+ if ($onlyEnabled) {
+ return array_filter(
+ $this->appVersionsCache,
+ fn (string $app): bool => $this->getValueString($app, 'enabled', 'no') !== 'no',
+ ARRAY_FILTER_USE_KEY
+ );
+ }
return $this->appVersionsCache;
}
}
diff --git a/lib/private/AppFramework/Bootstrap/Coordinator.php b/lib/private/AppFramework/Bootstrap/Coordinator.php
index 2b04d291730..190244051d3 100644
--- a/lib/private/AppFramework/Bootstrap/Coordinator.php
+++ b/lib/private/AppFramework/Bootstrap/Coordinator.php
@@ -20,6 +20,7 @@ use OCP\Dashboard\IManager;
use OCP\Diagnostics\IEventLogger;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\IServerContainer;
+use Psr\Container\ContainerExceptionInterface;
use Psr\Log\LoggerInterface;
use Throwable;
use function class_exists;
@@ -69,26 +70,32 @@ class Coordinator {
*/
try {
$path = $this->appManager->getAppPath($appId);
+ OC_App::registerAutoloading($appId, $path);
} catch (AppPathNotFoundException) {
// Ignore
continue;
}
- OC_App::registerAutoloading($appId, $path);
$this->eventLogger->end("bootstrap:register_app:$appId:autoloader");
/*
* Next we check if there is an application class, and it implements
* the \OCP\AppFramework\Bootstrap\IBootstrap interface
*/
- $appNameSpace = App::buildAppNamespace($appId);
+ if ($appId === 'core') {
+ $appNameSpace = 'OC\\Core';
+ } else {
+ $appNameSpace = App::buildAppNamespace($appId);
+ }
$applicationClassName = $appNameSpace . '\\AppInfo\\Application';
+
try {
- if (class_exists($applicationClassName) && in_array(IBootstrap::class, class_implements($applicationClassName), true)) {
+ if (class_exists($applicationClassName) && is_a($applicationClassName, IBootstrap::class, true)) {
$this->eventLogger->start("bootstrap:register_app:$appId:application", "Load `Application` instance for $appId");
try {
- /** @var IBootstrap|App $application */
- $apps[$appId] = $application = $this->serverContainer->query($applicationClassName);
- } catch (QueryException $e) {
+ /** @var IBootstrap&App $application */
+ $application = $this->serverContainer->query($applicationClassName);
+ $apps[$appId] = $application;
+ } catch (ContainerExceptionInterface $e) {
// Weird, but ok
$this->eventLogger->end("bootstrap:register_app:$appId");
continue;
diff --git a/lib/private/AppFramework/Bootstrap/RegistrationContext.php b/lib/private/AppFramework/Bootstrap/RegistrationContext.php
index c3b829825c2..95ad129c466 100644
--- a/lib/private/AppFramework/Bootstrap/RegistrationContext.php
+++ b/lib/private/AppFramework/Bootstrap/RegistrationContext.php
@@ -157,7 +157,7 @@ class RegistrationContext {
/** @var ServiceRegistration<\OCP\Files\Conversion\IConversionProvider>[] */
private array $fileConversionProviders = [];
-
+
/** @var ServiceRegistration<IMailProvider>[] */
private $mailProviders = [];
diff --git a/lib/private/AppFramework/Middleware/NotModifiedMiddleware.php b/lib/private/AppFramework/Middleware/NotModifiedMiddleware.php
index 17b423164f6..08b30092155 100644
--- a/lib/private/AppFramework/Middleware/NotModifiedMiddleware.php
+++ b/lib/private/AppFramework/Middleware/NotModifiedMiddleware.php
@@ -29,7 +29,7 @@ class NotModifiedMiddleware extends Middleware {
}
$modifiedSinceHeader = $this->request->getHeader('IF_MODIFIED_SINCE');
- if ($modifiedSinceHeader !== '' && $response->getLastModified() !== null && trim($modifiedSinceHeader) === $response->getLastModified()->format(\DateTimeInterface::RFC2822)) {
+ if ($modifiedSinceHeader !== '' && $response->getLastModified() !== null && trim($modifiedSinceHeader) === $response->getLastModified()->format(\DateTimeInterface::RFC7231)) {
$response->setStatus(Http::STATUS_NOT_MODIFIED);
return $response;
}
diff --git a/lib/private/AppFramework/Middleware/PublicShare/PublicShareMiddleware.php b/lib/private/AppFramework/Middleware/PublicShare/PublicShareMiddleware.php
index 2b3025fccff..b3040673d0f 100644
--- a/lib/private/AppFramework/Middleware/PublicShare/PublicShareMiddleware.php
+++ b/lib/private/AppFramework/Middleware/PublicShare/PublicShareMiddleware.php
@@ -120,7 +120,7 @@ class PublicShareMiddleware extends Middleware {
private function throttle($bruteforceProtectionAction, $token): void {
$ip = $this->request->getRemoteAddress();
- $this->throttler->sleepDelay($ip, $bruteforceProtectionAction);
+ $this->throttler->sleepDelayOrThrowOnMax($ip, $bruteforceProtectionAction);
$this->throttler->registerAttempt($bruteforceProtectionAction, $ip, ['token' => $token]);
}
}
diff --git a/lib/private/AppFramework/Middleware/Security/Exceptions/NotConfirmedException.php b/lib/private/AppFramework/Middleware/Security/Exceptions/NotConfirmedException.php
index 7e950f2c976..edf25c2cbe7 100644
--- a/lib/private/AppFramework/Middleware/Security/Exceptions/NotConfirmedException.php
+++ b/lib/private/AppFramework/Middleware/Security/Exceptions/NotConfirmedException.php
@@ -14,7 +14,7 @@ use OCP\AppFramework\Http;
* @package OC\AppFramework\Middleware\Security\Exceptions
*/
class NotConfirmedException extends SecurityException {
- public function __construct() {
- parent::__construct('Password confirmation is required', Http::STATUS_FORBIDDEN);
+ public function __construct(string $message = 'Password confirmation is required') {
+ parent::__construct($message, Http::STATUS_FORBIDDEN);
}
}
diff --git a/lib/private/AppFramework/Middleware/Security/PasswordConfirmationMiddleware.php b/lib/private/AppFramework/Middleware/Security/PasswordConfirmationMiddleware.php
index d00840084a3..e65fe94d608 100644
--- a/lib/private/AppFramework/Middleware/Security/PasswordConfirmationMiddleware.php
+++ b/lib/private/AppFramework/Middleware/Security/PasswordConfirmationMiddleware.php
@@ -79,6 +79,9 @@ class PasswordConfirmationMiddleware extends Middleware {
if ($this->isPasswordConfirmationStrict($reflectionMethod)) {
$authHeader = $this->request->getHeader('Authorization');
+ if (!str_starts_with(strtolower($authHeader), 'basic ')) {
+ throw new NotConfirmedException('Required authorization header missing');
+ }
[, $password] = explode(':', base64_decode(substr($authHeader, 6)), 2);
$loginName = $this->session->get('loginname');
$loginResult = $this->userManager->checkPassword($loginName, $password);
diff --git a/lib/private/AppFramework/Routing/RouteConfig.php b/lib/private/AppFramework/Routing/RouteConfig.php
deleted file mode 100644
index 2b7f21a8ba5..00000000000
--- a/lib/private/AppFramework/Routing/RouteConfig.php
+++ /dev/null
@@ -1,279 +0,0 @@
-<?php
-
-declare(strict_types=1);
-/**
- * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
- * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
- * SPDX-License-Identifier: AGPL-3.0-only
- */
-namespace OC\AppFramework\Routing;
-
-use OC\AppFramework\DependencyInjection\DIContainer;
-use OC\Route\Router;
-
-/**
- * Class RouteConfig
- * @package OC\AppFramework\routing
- */
-class RouteConfig {
- /** @var DIContainer */
- private $container;
-
- /** @var Router */
- private $router;
-
- /** @var array */
- private $routes;
-
- /** @var string */
- private $appName;
-
- /** @var string[] */
- private $controllerNameCache = [];
-
- protected $rootUrlApps = [
- 'cloud_federation_api',
- 'core',
- 'files_sharing',
- 'files',
- 'profile',
- 'settings',
- 'spreed',
- ];
-
- /**
- * @param \OC\AppFramework\DependencyInjection\DIContainer $container
- * @param \OC\Route\Router $router
- * @param array $routes
- * @internal param $appName
- */
- public function __construct(DIContainer $container, Router $router, $routes) {
- $this->routes = $routes;
- $this->container = $container;
- $this->router = $router;
- $this->appName = $container['AppName'];
- }
-
- /**
- * The routes and resource will be registered to the \OCP\Route\IRouter
- */
- public function register() {
- // parse simple
- $this->processIndexRoutes($this->routes);
-
- // parse resources
- $this->processIndexResources($this->routes);
-
- /*
- * OCS routes go into a different collection
- */
- $oldCollection = $this->router->getCurrentCollection();
- $this->router->useCollection($oldCollection . '.ocs');
-
- // parse ocs simple routes
- $this->processOCS($this->routes);
-
- // parse ocs simple routes
- $this->processOCSResources($this->routes);
-
- $this->router->useCollection($oldCollection);
- }
-
- private function processOCS(array $routes): void {
- $ocsRoutes = $routes['ocs'] ?? [];
- foreach ($ocsRoutes as $ocsRoute) {
- $this->processRoute($ocsRoute, 'ocs.');
- }
- }
-
- /**
- * Creates one route base on the give configuration
- * @param array $routes
- * @throws \UnexpectedValueException
- */
- private function processIndexRoutes(array $routes): void {
- $simpleRoutes = $routes['routes'] ?? [];
- foreach ($simpleRoutes as $simpleRoute) {
- $this->processRoute($simpleRoute);
- }
- }
-
- protected function processRoute(array $route, string $routeNamePrefix = ''): void {
- $name = $route['name'];
- $postfix = $route['postfix'] ?? '';
- $root = $this->buildRootPrefix($route, $routeNamePrefix);
-
- $url = $root . '/' . ltrim($route['url'], '/');
- $verb = strtoupper($route['verb'] ?? 'GET');
-
- $split = explode('#', $name, 2);
- if (count($split) !== 2) {
- throw new \UnexpectedValueException('Invalid route name: use the format foo#bar to reference FooController::bar');
- }
- [$controller, $action] = $split;
-
- $controllerName = $this->buildControllerName($controller);
- $actionName = $this->buildActionName($action);
-
- /*
- * The route name has to be lowercase, for symfony to match it correctly.
- * This is required because smyfony allows mixed casing for controller names in the routes.
- * To avoid breaking all the existing route names, registering and matching will only use the lowercase names.
- * This is also safe on the PHP side because class and method names collide regardless of the casing.
- */
- $routeName = strtolower($routeNamePrefix . $this->appName . '.' . $controller . '.' . $action . $postfix);
-
- $router = $this->router->create($routeName, $url)
- ->method($verb);
-
- // optionally register requirements for route. This is used to
- // tell the route parser how url parameters should be matched
- if (array_key_exists('requirements', $route)) {
- $router->requirements($route['requirements']);
- }
-
- // optionally register defaults for route. This is used to
- // tell the route parser how url parameters should be default valued
- $defaults = [];
- if (array_key_exists('defaults', $route)) {
- $defaults = $route['defaults'];
- }
-
- $defaults['caller'] = [$this->appName, $controllerName, $actionName];
- $router->defaults($defaults);
- }
-
- /**
- * For a given name and url restful OCS routes are created:
- * - index
- * - show
- * - create
- * - update
- * - destroy
- *
- * @param array $routes
- */
- private function processOCSResources(array $routes): void {
- $this->processResources($routes['ocs-resources'] ?? [], 'ocs.');
- }
-
- /**
- * For a given name and url restful routes are created:
- * - index
- * - show
- * - create
- * - update
- * - destroy
- *
- * @param array $routes
- */
- private function processIndexResources(array $routes): void {
- $this->processResources($routes['resources'] ?? []);
- }
-
- /**
- * For a given name and url restful routes are created:
- * - index
- * - show
- * - create
- * - update
- * - destroy
- *
- * @param array $resources
- * @param string $routeNamePrefix
- */
- protected function processResources(array $resources, string $routeNamePrefix = ''): void {
- // declaration of all restful actions
- $actions = [
- ['name' => 'index', 'verb' => 'GET', 'on-collection' => true],
- ['name' => 'show', 'verb' => 'GET'],
- ['name' => 'create', 'verb' => 'POST', 'on-collection' => true],
- ['name' => 'update', 'verb' => 'PUT'],
- ['name' => 'destroy', 'verb' => 'DELETE'],
- ];
-
- foreach ($resources as $resource => $config) {
- $root = $this->buildRootPrefix($config, $routeNamePrefix);
-
- // the url parameter used as id to the resource
- foreach ($actions as $action) {
- $url = $root . '/' . ltrim($config['url'], '/');
- $method = $action['name'];
-
- $verb = strtoupper($action['verb'] ?? 'GET');
- $collectionAction = $action['on-collection'] ?? false;
- if (!$collectionAction) {
- $url .= '/{id}';
- }
- if (isset($action['url-postfix'])) {
- $url .= '/' . $action['url-postfix'];
- }
-
- $controller = $resource;
-
- $controllerName = $this->buildControllerName($controller);
- $actionName = $this->buildActionName($method);
-
- $routeName = $routeNamePrefix . $this->appName . '.' . strtolower($resource) . '.' . $method;
-
- $route = $this->router->create($routeName, $url)
- ->method($verb);
-
- $route->defaults(['caller' => [$this->appName, $controllerName, $actionName]]);
- }
- }
- }
-
- private function buildRootPrefix(array $route, string $routeNamePrefix): string {
- $defaultRoot = $this->appName === 'core' ? '' : '/apps/' . $this->appName;
- $root = $route['root'] ?? $defaultRoot;
-
- if ($routeNamePrefix !== '') {
- // In OCS all apps are whitelisted
- return $root;
- }
-
- if (!\in_array($this->appName, $this->rootUrlApps, true)) {
- // Only allow root URLS for some apps
- return $defaultRoot;
- }
-
- return $root;
- }
-
- /**
- * Based on a given route name the controller name is generated
- * @param string $controller
- * @return string
- */
- private function buildControllerName(string $controller): string {
- if (!isset($this->controllerNameCache[$controller])) {
- $this->controllerNameCache[$controller] = $this->underScoreToCamelCase(ucfirst($controller)) . 'Controller';
- }
- return $this->controllerNameCache[$controller];
- }
-
- /**
- * Based on the action part of the route name the controller method name is generated
- * @param string $action
- * @return string
- */
- private function buildActionName(string $action): string {
- return $this->underScoreToCamelCase($action);
- }
-
- /**
- * Underscored strings are converted to camel case strings
- * @param string $str
- * @return string
- */
- private function underScoreToCamelCase(string $str): string {
- $pattern = '/_[a-z]?/';
- return preg_replace_callback(
- $pattern,
- function ($matches) {
- return strtoupper(ltrim($matches[0], '_'));
- },
- $str);
- }
-}
diff --git a/lib/private/AppFramework/Routing/RouteParser.php b/lib/private/AppFramework/Routing/RouteParser.php
index 894a74c727b..55e58234673 100644
--- a/lib/private/AppFramework/Routing/RouteParser.php
+++ b/lib/private/AppFramework/Routing/RouteParser.php
@@ -76,7 +76,7 @@ class RouteParser {
$url = $root . '/' . ltrim($route['url'], '/');
$verb = strtoupper($route['verb'] ?? 'GET');
- $split = explode('#', $name, 2);
+ $split = explode('#', $name, 3);
if (count($split) !== 2) {
throw new \UnexpectedValueException('Invalid route name: use the format foo#bar to reference FooController::bar');
}
@@ -87,7 +87,7 @@ class RouteParser {
/*
* The route name has to be lowercase, for symfony to match it correctly.
- * This is required because smyfony allows mixed casing for controller names in the routes.
+ * This is required because symfony allows mixed casing for controller names in the routes.
* To avoid breaking all the existing route names, registering and matching will only use the lowercase names.
* This is also safe on the PHP side because class and method names collide regardless of the casing.
*/
diff --git a/lib/private/AppFramework/Services/AppConfig.php b/lib/private/AppFramework/Services/AppConfig.php
index 77c5ea4de0c..04d97738483 100644
--- a/lib/private/AppFramework/Services/AppConfig.php
+++ b/lib/private/AppFramework/Services/AppConfig.php
@@ -343,7 +343,7 @@ class AppConfig implements IAppConfig {
*
* @return array<string, string>
*/
- public function getAppInstalledVersions(): array {
- return $this->appConfig->getAppInstalledVersions();
+ public function getAppInstalledVersions(bool $onlyEnabled = false): array {
+ return $this->appConfig->getAppInstalledVersions($onlyEnabled);
}
}
diff --git a/lib/private/AppFramework/Utility/SimpleContainer.php b/lib/private/AppFramework/Utility/SimpleContainer.php
index 24918992ea3..481c12cc708 100644
--- a/lib/private/AppFramework/Utility/SimpleContainer.php
+++ b/lib/private/AppFramework/Utility/SimpleContainer.php
@@ -12,6 +12,7 @@ use Closure;
use OCP\AppFramework\QueryException;
use OCP\IContainer;
use Pimple\Container;
+use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;
use ReflectionClass;
use ReflectionException;
@@ -23,8 +24,9 @@ use function class_exists;
* SimpleContainer is a simple implementation of a container on basis of Pimple
*/
class SimpleContainer implements ArrayAccess, ContainerInterface, IContainer {
- /** @var Container */
- private $container;
+ public static bool $useLazyObjects = false;
+
+ private Container $container;
public function __construct() {
$this->container = new Container();
@@ -49,16 +51,29 @@ class SimpleContainer implements ArrayAccess, ContainerInterface, IContainer {
/**
* @param ReflectionClass $class the class to instantiate
- * @return \stdClass the created class
+ * @return object the created class
* @suppress PhanUndeclaredClassInstanceof
*/
- private function buildClass(ReflectionClass $class) {
+ private function buildClass(ReflectionClass $class): object {
$constructor = $class->getConstructor();
if ($constructor === null) {
+ /* No constructor, return a instance directly */
return $class->newInstance();
}
+ if (PHP_VERSION_ID >= 80400 && self::$useLazyObjects) {
+ /* For PHP>=8.4, use a lazy ghost to delay constructor and dependency resolving */
+ /** @psalm-suppress UndefinedMethod */
+ return $class->newLazyGhost(function (object $object) use ($constructor): void {
+ /** @psalm-suppress DirectConstructorCall For lazy ghosts we have to call the constructor directly */
+ $object->__construct(...$this->buildClassConstructorParameters($constructor));
+ });
+ } else {
+ return $class->newInstanceArgs($this->buildClassConstructorParameters($constructor));
+ }
+ }
- return $class->newInstanceArgs(array_map(function (ReflectionParameter $parameter) {
+ private function buildClassConstructorParameters(\ReflectionMethod $constructor): array {
+ return array_map(function (ReflectionParameter $parameter) {
$parameterType = $parameter->getType();
$resolveName = $parameter->getName();
@@ -69,10 +84,10 @@ class SimpleContainer implements ArrayAccess, ContainerInterface, IContainer {
}
try {
- $builtIn = $parameter->hasType() && ($parameter->getType() instanceof ReflectionNamedType)
- && $parameter->getType()->isBuiltin();
+ $builtIn = $parameterType !== null && ($parameterType instanceof ReflectionNamedType)
+ && $parameterType->isBuiltin();
return $this->query($resolveName, !$builtIn);
- } catch (QueryException $e) {
+ } catch (ContainerExceptionInterface $e) {
// Service not found, use the default value when available
if ($parameter->isDefaultValueAvailable()) {
return $parameter->getDefaultValue();
@@ -82,7 +97,7 @@ class SimpleContainer implements ArrayAccess, ContainerInterface, IContainer {
$resolveName = $parameter->getName();
try {
return $this->query($resolveName);
- } catch (QueryException $e2) {
+ } catch (ContainerExceptionInterface $e2) {
// Pass null if typed and nullable
if ($parameter->allowsNull() && ($parameterType instanceof ReflectionNamedType)) {
return null;
@@ -95,7 +110,7 @@ class SimpleContainer implements ArrayAccess, ContainerInterface, IContainer {
throw $e;
}
- }, $constructor->getParameters()));
+ }, $constructor->getParameters());
}
public function resolve($name) {
@@ -153,13 +168,13 @@ class SimpleContainer implements ArrayAccess, ContainerInterface, IContainer {
return $closure($this);
};
$name = $this->sanitizeName($name);
- if (isset($this[$name])) {
- unset($this[$name]);
+ if (isset($this->container[$name])) {
+ unset($this->container[$name]);
}
if ($shared) {
- $this[$name] = $wrapped;
+ $this->container[$name] = $wrapped;
} else {
- $this[$name] = $this->container->factory($wrapped);
+ $this->container[$name] = $this->container->factory($wrapped);
}
}
diff --git a/lib/private/Blurhash/Listener/GenerateBlurhashMetadata.php b/lib/private/Blurhash/Listener/GenerateBlurhashMetadata.php
index 16f63594f19..8faf4627251 100644
--- a/lib/private/Blurhash/Listener/GenerateBlurhashMetadata.php
+++ b/lib/private/Blurhash/Listener/GenerateBlurhashMetadata.php
@@ -19,6 +19,7 @@ use OCP\Files\NotPermittedException;
use OCP\FilesMetadata\AMetadataEvent;
use OCP\FilesMetadata\Event\MetadataBackgroundEvent;
use OCP\FilesMetadata\Event\MetadataLiveEvent;
+use OCP\IPreview;
use OCP\Lock\LockedException;
/**
@@ -27,11 +28,14 @@ use OCP\Lock\LockedException;
* @template-implements IEventListener<AMetadataEvent>
*/
class GenerateBlurhashMetadata implements IEventListener {
- private const RESIZE_BOXSIZE = 30;
-
private const COMPONENTS_X = 4;
private const COMPONENTS_Y = 3;
+ public function __construct(
+ private IPreview $preview,
+ ) {
+ }
+
/**
* @throws NotPermittedException
* @throws GenericFileException
@@ -64,42 +68,20 @@ class GenerateBlurhashMetadata implements IEventListener {
return;
}
- $image = $this->resizedImageFromFile($file);
- if (!$image) {
+ // Preview are disabled, so we skip generating the blurhash.
+ if (!$this->preview->isAvailable($file)) {
return;
}
- $metadata->setString('blurhash', $this->generateBlurHash($image))
- ->setEtag('blurhash', $currentEtag);
- }
-
- /**
- * @param File $file
- *
- * @return GdImage|false
- * @throws GenericFileException
- * @throws NotPermittedException
- * @throws LockedException
- */
- private function resizedImageFromFile(File $file): GdImage|false {
- $image = @imagecreatefromstring($file->getContent());
- if ($image === false) {
- return false;
- }
-
- $currX = imagesx($image);
- $currY = imagesy($image);
+ $preview = $this->preview->getPreview($file, 64, 64, cacheResult: false);
+ $image = @imagecreatefromstring($preview->getContent());
- if ($currX > $currY) {
- $newX = self::RESIZE_BOXSIZE;
- $newY = intval($currY * $newX / $currX);
- } else {
- $newY = self::RESIZE_BOXSIZE;
- $newX = intval($currX * $newY / $currY);
+ if (!$image) {
+ return;
}
- $newImage = @imagescale($image, $newX, $newY);
- return ($newImage !== false) ? $newImage : $image;
+ $metadata->setString('blurhash', $this->generateBlurHash($image))
+ ->setEtag('blurhash', $currentEtag);
}
/**
diff --git a/lib/private/Calendar/Manager.php b/lib/private/Calendar/Manager.php
index e86e0e1d410..21370e74d54 100644
--- a/lib/private/Calendar/Manager.php
+++ b/lib/private/Calendar/Manager.php
@@ -33,6 +33,7 @@ use Sabre\HTTP\Response;
use Sabre\VObject\Component\VCalendar;
use Sabre\VObject\Component\VEvent;
use Sabre\VObject\Component\VFreeBusy;
+use Sabre\VObject\ParseException;
use Sabre\VObject\Property\VCard\DateTime;
use Sabre\VObject\Reader;
use Throwable;
@@ -235,9 +236,14 @@ class Manager implements IManager {
$this->logger->warning('iMip message could not be processed because user has no calendars');
return false;
}
-
- /** @var VCalendar $vObject|null */
- $calendarObject = Reader::read($calendarData);
+
+ try {
+ /** @var VCalendar $vObject|null */
+ $calendarObject = Reader::read($calendarData);
+ } catch (ParseException $e) {
+ $this->logger->error('iMip message could not be processed because an error occurred while parsing the iMip message', ['exception' => $e]);
+ return false;
+ }
if (!isset($calendarObject->METHOD) || $calendarObject->METHOD->getValue() !== 'REQUEST') {
$this->logger->warning('iMip message contains an incorrect or invalid method');
@@ -249,6 +255,7 @@ class Manager implements IManager {
return false;
}
+ /** @var VEvent|null $vEvent */
$eventObject = $calendarObject->VEVENT;
if (!isset($eventObject->UID)) {
@@ -256,6 +263,11 @@ class Manager implements IManager {
return false;
}
+ if (!isset($eventObject->ORGANIZER)) {
+ $this->logger->warning('iMip message event dose not contains an organizer');
+ return false;
+ }
+
if (!isset($eventObject->ATTENDEE)) {
$this->logger->warning('iMip message event dose not contains any attendees');
return false;
@@ -296,7 +308,7 @@ class Manager implements IManager {
}
}
- $this->logger->warning('iMip message event could not be processed because the no corresponding event was found in any calendar');
+ $this->logger->warning('iMip message event could not be processed because no corresponding event was found in any calendar');
return false;
}
@@ -309,23 +321,51 @@ class Manager implements IManager {
string $recipient,
string $calendarData,
): bool {
- /** @var VCalendar $vObject|null */
- $vObject = Reader::read($calendarData);
+
+ $calendars = $this->getCalendarsForPrincipal($principalUri);
+ if (empty($calendars)) {
+ $this->logger->warning('iMip message could not be processed because user has no calendars');
+ return false;
+ }
+
+ try {
+ /** @var VCalendar $vObject|null */
+ $vObject = Reader::read($calendarData);
+ } catch (ParseException $e) {
+ $this->logger->error('iMip message could not be processed because an error occurred while parsing the iMip message', ['exception' => $e]);
+ return false;
+ }
if ($vObject === null) {
+ $this->logger->warning('iMip message contains an invalid calendar object');
+ return false;
+ }
+
+ if (!isset($vObject->METHOD) || $vObject->METHOD->getValue() !== 'REPLY') {
+ $this->logger->warning('iMip message contains an incorrect or invalid method');
+ return false;
+ }
+
+ if (!isset($vObject->VEVENT)) {
+ $this->logger->warning('iMip message contains no event');
return false;
}
/** @var VEvent|null $vEvent */
- $vEvent = $vObject->{'VEVENT'};
+ $vEvent = $vObject->VEVENT;
+
+ if (!isset($vEvent->UID)) {
+ $this->logger->warning('iMip message event dose not contains a UID');
+ return false;
+ }
- if ($vEvent === null) {
+ if (!isset($vEvent->ORGANIZER)) {
+ $this->logger->warning('iMip message event dose not contains an organizer');
return false;
}
- // First, we check if the correct method is passed to us
- if (strcasecmp('REPLY', $vObject->{'METHOD'}->getValue()) !== 0) {
- $this->logger->warning('Wrong method provided for processing');
+ if (!isset($vEvent->ATTENDEE)) {
+ $this->logger->warning('iMip message event dose not contains any attendees');
return false;
}
@@ -333,7 +373,7 @@ class Manager implements IManager {
$organizer = substr($vEvent->{'ORGANIZER'}->getValue(), 7);
if (strcasecmp($recipient, $organizer) !== 0) {
- $this->logger->warning('Recipient and ORGANIZER must be identical');
+ $this->logger->warning('iMip message event could not be processed because recipient and ORGANIZER must be identical');
return false;
}
@@ -341,13 +381,7 @@ class Manager implements IManager {
/** @var DateTime $eventTime */
$eventTime = $vEvent->{'DTSTART'};
if ($eventTime->getDateTime()->getTimeStamp() < $this->timeFactory->getTime()) { // this might cause issues with recurrences
- $this->logger->warning('Only events in the future are processed');
- return false;
- }
-
- $calendars = $this->getCalendarsForPrincipal($principalUri);
- if (empty($calendars)) {
- $this->logger->warning('Could not find any calendars for principal ' . $principalUri);
+ $this->logger->warning('iMip message event could not be processed because the event is in the past');
return false;
}
@@ -369,14 +403,14 @@ class Manager implements IManager {
}
if (empty($found)) {
- $this->logger->info('Event not found in any calendar for principal ' . $principalUri . 'and UID' . $vEvent->{'UID'}->getValue());
+ $this->logger->warning('iMip message event could not be processed because no corresponding event was found in any calendar ' . $principalUri . 'and UID' . $vEvent->{'UID'}->getValue());
return false;
}
try {
$found->handleIMipMessage($name, $calendarData); // sabre will handle the scheduling behind the scenes
} catch (CalendarException $e) {
- $this->logger->error('Could not update calendar for iMIP processing', ['exception' => $e]);
+ $this->logger->error('An error occurred while processing the iMip message event', ['exception' => $e]);
return false;
}
return true;
@@ -393,29 +427,57 @@ class Manager implements IManager {
string $recipient,
string $calendarData,
): bool {
- /** @var VCalendar $vObject|null */
- $vObject = Reader::read($calendarData);
+
+ $calendars = $this->getCalendarsForPrincipal($principalUri);
+ if (empty($calendars)) {
+ $this->logger->warning('iMip message could not be processed because user has no calendars');
+ return false;
+ }
+
+ try {
+ /** @var VCalendar $vObject|null */
+ $vObject = Reader::read($calendarData);
+ } catch (ParseException $e) {
+ $this->logger->error('iMip message could not be processed because an error occurred while parsing the iMip message', ['exception' => $e]);
+ return false;
+ }
if ($vObject === null) {
+ $this->logger->warning('iMip message contains an invalid calendar object');
+ return false;
+ }
+
+ if (!isset($vObject->METHOD) || $vObject->METHOD->getValue() !== 'CANCEL') {
+ $this->logger->warning('iMip message contains an incorrect or invalid method');
+ return false;
+ }
+
+ if (!isset($vObject->VEVENT)) {
+ $this->logger->warning('iMip message contains no event');
return false;
}
/** @var VEvent|null $vEvent */
$vEvent = $vObject->{'VEVENT'};
- if ($vEvent === null) {
+ if (!isset($vEvent->UID)) {
+ $this->logger->warning('iMip message event dose not contains a UID');
+ return false;
+ }
+
+ if (!isset($vEvent->ORGANIZER)) {
+ $this->logger->warning('iMip message event dose not contains an organizer');
return false;
}
- // First, we check if the correct method is passed to us
- if (strcasecmp('CANCEL', $vObject->{'METHOD'}->getValue()) !== 0) {
- $this->logger->warning('Wrong method provided for processing');
+ if (!isset($vEvent->ATTENDEE)) {
+ $this->logger->warning('iMip message event dose not contains any attendees');
return false;
}
$attendee = substr($vEvent->{'ATTENDEE'}->getValue(), 7);
if (strcasecmp($recipient, $attendee) !== 0) {
- $this->logger->warning('Recipient must be an ATTENDEE of this event');
+ $this->logger->warning('iMip message event could not be processed because recipient must be an ATTENDEE of this event');
return false;
}
@@ -426,7 +488,7 @@ class Manager implements IManager {
$organizer = substr($vEvent->{'ORGANIZER'}->getValue(), 7);
$isNotOrganizer = ($replyTo !== null) ? (strcasecmp($sender, $organizer) !== 0 && strcasecmp($replyTo, $organizer) !== 0) : (strcasecmp($sender, $organizer) !== 0);
if ($isNotOrganizer) {
- $this->logger->warning('Sender must be the ORGANIZER of this event');
+ $this->logger->warning('iMip message event could not be processed because sender must be the ORGANIZER of this event');
return false;
}
@@ -434,14 +496,7 @@ class Manager implements IManager {
/** @var DateTime $eventTime */
$eventTime = $vEvent->{'DTSTART'};
if ($eventTime->getDateTime()->getTimeStamp() < $this->timeFactory->getTime()) { // this might cause issues with recurrences
- $this->logger->warning('Only events in the future are processed');
- return false;
- }
-
- // Check if we have a calendar to work with
- $calendars = $this->getCalendarsForPrincipal($principalUri);
- if (empty($calendars)) {
- $this->logger->warning('Could not find any calendars for principal ' . $principalUri);
+ $this->logger->warning('iMip message event could not be processed because the event is in the past');
return false;
}
@@ -463,17 +518,15 @@ class Manager implements IManager {
}
if (empty($found)) {
- $this->logger->info('Event not found in any calendar for principal ' . $principalUri . 'and UID' . $vEvent->{'UID'}->getValue());
- // this is a safe operation
- // we can ignore events that have been cancelled but were not in the calendar anyway
- return true;
+ $this->logger->warning('iMip message event could not be processed because no corresponding event was found in any calendar ' . $principalUri . 'and UID' . $vEvent->{'UID'}->getValue());
+ return false;
}
try {
$found->handleIMipMessage($name, $calendarData); // sabre will handle the scheduling behind the scenes
return true;
} catch (CalendarException $e) {
- $this->logger->error('Could not update calendar for iMIP processing', ['exception' => $e]);
+ $this->logger->error('An error occurred while processing the iMip message event', ['exception' => $e]);
return false;
}
}
diff --git a/lib/private/Collaboration/Reference/File/FileReferenceEventListener.php b/lib/private/Collaboration/Reference/File/FileReferenceEventListener.php
index e468ad4eb4c..9c18531c8e7 100644
--- a/lib/private/Collaboration/Reference/File/FileReferenceEventListener.php
+++ b/lib/private/Collaboration/Reference/File/FileReferenceEventListener.php
@@ -15,6 +15,7 @@ use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\EventDispatcher\IEventListener;
use OCP\Files\Events\Node\NodeDeletedEvent;
+use OCP\Files\Events\Node\NodeRenamedEvent;
use OCP\Share\Events\ShareCreatedEvent;
use OCP\Share\Events\ShareDeletedEvent;
@@ -27,6 +28,7 @@ class FileReferenceEventListener implements IEventListener {
public static function register(IEventDispatcher $eventDispatcher): void {
$eventDispatcher->addServiceListener(NodeDeletedEvent::class, FileReferenceEventListener::class);
+ $eventDispatcher->addServiceListener(NodeRenamedEvent::class, FileReferenceEventListener::class);
$eventDispatcher->addServiceListener(ShareDeletedEvent::class, FileReferenceEventListener::class);
$eventDispatcher->addServiceListener(ShareCreatedEvent::class, FileReferenceEventListener::class);
}
@@ -42,6 +44,9 @@ class FileReferenceEventListener implements IEventListener {
$this->manager->invalidateCache((string)$event->getNode()->getId());
}
+ if ($event instanceof NodeRenamedEvent) {
+ $this->manager->invalidateCache((string)$event->getTarget()->getId());
+ }
if ($event instanceof ShareDeletedEvent) {
$this->manager->invalidateCache((string)$event->getShare()->getNodeId());
}
diff --git a/lib/private/Config/ConfigManager.php b/lib/private/Config/ConfigManager.php
new file mode 100644
index 00000000000..1980269e2ca
--- /dev/null
+++ b/lib/private/Config/ConfigManager.php
@@ -0,0 +1,250 @@
+<?php
+
+declare(strict_types=1);
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace OC\Config;
+
+use JsonException;
+use NCU\Config\Exceptions\TypeConflictException;
+use NCU\Config\IUserConfig;
+use NCU\Config\Lexicon\ConfigLexiconEntry;
+use NCU\Config\ValueType;
+use OC\AppConfig;
+use OCP\App\IAppManager;
+use OCP\IAppConfig;
+use OCP\Server;
+use Psr\Log\LoggerInterface;
+
+/**
+ * tools to maintains configurations
+ *
+ * @since 32.0.0
+ */
+class ConfigManager {
+ /** @var AppConfig|null $appConfig */
+ private ?IAppConfig $appConfig = null;
+ /** @var UserConfig|null $userConfig */
+ private ?IUserConfig $userConfig = null;
+
+ public function __construct(
+ private readonly LoggerInterface $logger,
+ ) {
+ }
+
+ /**
+ * Use the rename values from the list of ConfigLexiconEntry defined in each app ConfigLexicon
+ * to migrate config value to a new config key.
+ * Migration will only occur if new config key has no value in database.
+ * The previous value from the key set in rename will be deleted from the database when migration
+ * is over.
+ *
+ * This method should be mainly called during a new upgrade or when a new app is enabled.
+ *
+ * @see ConfigLexiconEntry
+ * @internal
+ * @since 32.0.0
+ * @param string|null $appId when set to NULL the method will be executed for all enabled apps of the instance
+ */
+ public function migrateConfigLexiconKeys(?string $appId = null): void {
+ if ($appId === null) {
+ $this->migrateConfigLexiconKeys('core');
+ $appManager = Server::get(IAppManager::class);
+ foreach ($appManager->getEnabledApps() as $app) {
+ $this->migrateConfigLexiconKeys($app);
+ }
+
+ return;
+ }
+
+ $this->loadConfigServices();
+
+ // it is required to ignore aliases when moving config values
+ $this->appConfig->ignoreLexiconAliases(true);
+ $this->userConfig->ignoreLexiconAliases(true);
+
+ $this->migrateAppConfigKeys($appId);
+ $this->migrateUserConfigKeys($appId);
+
+ // switch back to normal behavior
+ $this->appConfig->ignoreLexiconAliases(false);
+ $this->userConfig->ignoreLexiconAliases(false);
+ }
+
+ /**
+ * config services cannot be load at __construct() or install will fail
+ */
+ private function loadConfigServices(): void {
+ if ($this->appConfig === null) {
+ $this->appConfig = Server::get(IAppConfig::class);
+ }
+ if ($this->userConfig === null) {
+ $this->userConfig = Server::get(IUserConfig::class);
+ }
+ }
+
+ /**
+ * Get details from lexicon related to AppConfig and search for entries with rename to initiate
+ * a migration to new config key
+ */
+ private function migrateAppConfigKeys(string $appId): void {
+ $lexicon = $this->appConfig->getConfigDetailsFromLexicon($appId);
+ foreach ($lexicon['entries'] as $entry) {
+ // only interested in entries with rename set
+ if ($entry->getRename() === null) {
+ continue;
+ }
+
+ // only migrate if rename config key has a value and the new config key hasn't
+ if ($this->appConfig->hasKey($appId, $entry->getRename())
+ && !$this->appConfig->hasKey($appId, $entry->getKey())) {
+ try {
+ $this->migrateAppConfigValue($appId, $entry);
+ } catch (TypeConflictException $e) {
+ $this->logger->error('could not migrate AppConfig value', ['appId' => $appId, 'entry' => $entry, 'exception' => $e]);
+ continue;
+ }
+ }
+
+ // we only delete previous config value if migration went fine.
+ $this->appConfig->deleteKey($appId, $entry->getRename());
+ }
+ }
+
+ /**
+ * Get details from lexicon related to UserConfig and search for entries with rename to initiate
+ * a migration to new config key
+ */
+ private function migrateUserConfigKeys(string $appId): void {
+ $lexicon = $this->userConfig->getConfigDetailsFromLexicon($appId);
+ foreach ($lexicon['entries'] as $entry) {
+ // only interested in keys with rename set
+ if ($entry->getRename() === null) {
+ continue;
+ }
+
+ foreach ($this->userConfig->getValuesByUsers($appId, $entry->getRename()) as $userId => $value) {
+ if ($this->userConfig->hasKey($userId, $appId, $entry->getKey())) {
+ continue;
+ }
+
+ try {
+ $this->migrateUserConfigValue($userId, $appId, $entry);
+ } catch (TypeConflictException $e) {
+ $this->logger->error('could not migrate UserConfig value', ['userId' => $userId, 'appId' => $appId, 'entry' => $entry, 'exception' => $e]);
+ continue;
+ }
+
+ $this->userConfig->deleteUserConfig($userId, $appId, $entry->getRename());
+ }
+ }
+ }
+
+
+ /**
+ * converting value from rename to the new key
+ *
+ * @throws TypeConflictException if previous value does not fit the expected type
+ */
+ private function migrateAppConfigValue(string $appId, ConfigLexiconEntry $entry): void {
+ $value = $this->appConfig->getValueMixed($appId, $entry->getRename(), lazy: null);
+ switch ($entry->getValueType()) {
+ case ValueType::STRING:
+ $this->appConfig->setValueString($appId, $entry->getKey(), $value);
+ return;
+
+ case ValueType::INT:
+ $this->appConfig->setValueInt($appId, $entry->getKey(), $this->convertToInt($value));
+ return;
+
+ case ValueType::FLOAT:
+ $this->appConfig->setValueFloat($appId, $entry->getKey(), $this->convertToFloat($value));
+ return;
+
+ case ValueType::BOOL:
+ $this->appConfig->setValueBool($appId, $entry->getKey(), $this->convertToBool($value, $entry));
+ return;
+
+ case ValueType::ARRAY:
+ $this->appConfig->setValueArray($appId, $entry->getKey(), $this->convertToArray($value));
+ return;
+ }
+ }
+
+ /**
+ * converting value from rename to the new key
+ *
+ * @throws TypeConflictException if previous value does not fit the expected type
+ */
+ private function migrateUserConfigValue(string $userId, string $appId, ConfigLexiconEntry $entry): void {
+ $value = $this->userConfig->getValueMixed($userId, $appId, $entry->getRename(), lazy: null);
+ switch ($entry->getValueType()) {
+ case ValueType::STRING:
+ $this->userConfig->setValueString($userId, $appId, $entry->getKey(), $value);
+ return;
+
+ case ValueType::INT:
+ $this->userConfig->setValueInt($userId, $appId, $entry->getKey(), $this->convertToInt($value));
+ return;
+
+ case ValueType::FLOAT:
+ $this->userConfig->setValueFloat($userId, $appId, $entry->getKey(), $this->convertToFloat($value));
+ return;
+
+ case ValueType::BOOL:
+ $this->userConfig->setValueBool($userId, $appId, $entry->getKey(), $this->convertToBool($value, $entry));
+ return;
+
+ case ValueType::ARRAY:
+ $this->userConfig->setValueArray($userId, $appId, $entry->getKey(), $this->convertToArray($value));
+ return;
+ }
+ }
+
+ public function convertToInt(string $value): int {
+ if (!is_numeric($value) || (float)$value <> (int)$value) {
+ throw new TypeConflictException('Value is not an integer');
+ }
+
+ return (int)$value;
+ }
+
+ public function convertToFloat(string $value): float {
+ if (!is_numeric($value)) {
+ throw new TypeConflictException('Value is not a float');
+ }
+
+ return (float)$value;
+ }
+
+ public function convertToBool(string $value, ?ConfigLexiconEntry $entry = null): bool {
+ if (in_array(strtolower($value), ['true', '1', 'on', 'yes'])) {
+ $valueBool = true;
+ } elseif (in_array(strtolower($value), ['false', '0', 'off', 'no'])) {
+ $valueBool = false;
+ } else {
+ throw new TypeConflictException('Value cannot be converted to boolean');
+ }
+ if ($entry?->hasOption(ConfigLexiconEntry::RENAME_INVERT_BOOLEAN) === true) {
+ $valueBool = !$valueBool;
+ }
+
+ return $valueBool;
+ }
+
+ public function convertToArray(string $value): array {
+ try {
+ $valueArray = json_decode($value, true, flags: JSON_THROW_ON_ERROR);
+ } catch (JsonException) {
+ throw new TypeConflictException('Value is not a valid json');
+ }
+ if (!is_array($valueArray)) {
+ throw new TypeConflictException('Value is not an array');
+ }
+
+ return $valueArray;
+ }
+}
diff --git a/lib/private/Config/UserConfig.php b/lib/private/Config/UserConfig.php
index 77a86a5e1c7..f8c59a13d3d 100644
--- a/lib/private/Config/UserConfig.php
+++ b/lib/private/Config/UserConfig.php
@@ -25,6 +25,7 @@ use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IConfig;
use OCP\IDBConnection;
use OCP\Security\ICrypto;
+use OCP\Server;
use Psr\Log\LoggerInterface;
/**
@@ -62,8 +63,9 @@ class UserConfig implements IUserConfig {
private array $fastLoaded = [];
/** @var array<string, boolean> ['user_id' => bool] */
private array $lazyLoaded = [];
- /** @var array<array-key, array{entries: array<array-key, ConfigLexiconEntry>, strictness: ConfigLexiconStrictness}> ['app_id' => ['strictness' => ConfigLexiconStrictness, 'entries' => ['config_key' => ConfigLexiconEntry[]]] */
+ /** @var array<string, array{entries: array<string, ConfigLexiconEntry>, aliases: array<string, string>, strictness: ConfigLexiconStrictness}> ['app_id' => ['strictness' => ConfigLexiconStrictness, 'entries' => ['config_key' => ConfigLexiconEntry[]]] */
private array $configLexiconDetails = [];
+ private bool $ignoreLexiconAliases = false;
public function __construct(
protected IDBConnection $connection,
@@ -150,6 +152,7 @@ class UserConfig implements IUserConfig {
public function hasKey(string $userId, string $app, string $key, ?bool $lazy = false): bool {
$this->assertParams($userId, $app, $key);
$this->loadConfig($userId, $lazy);
+ $this->matchAndApplyLexiconDefinition($userId, $app, $key);
if ($lazy === null) {
$appCache = $this->getValues($userId, $app);
@@ -178,6 +181,7 @@ class UserConfig implements IUserConfig {
public function isSensitive(string $userId, string $app, string $key, ?bool $lazy = false): bool {
$this->assertParams($userId, $app, $key);
$this->loadConfig($userId, $lazy);
+ $this->matchAndApplyLexiconDefinition($userId, $app, $key);
if (!isset($this->valueDetails[$userId][$app][$key])) {
throw new UnknownKeyException('unknown config key');
@@ -201,6 +205,7 @@ class UserConfig implements IUserConfig {
public function isIndexed(string $userId, string $app, string $key, ?bool $lazy = false): bool {
$this->assertParams($userId, $app, $key);
$this->loadConfig($userId, $lazy);
+ $this->matchAndApplyLexiconDefinition($userId, $app, $key);
if (!isset($this->valueDetails[$userId][$app][$key])) {
throw new UnknownKeyException('unknown config key');
@@ -222,6 +227,8 @@ class UserConfig implements IUserConfig {
* @since 31.0.0
*/
public function isLazy(string $userId, string $app, string $key): bool {
+ $this->matchAndApplyLexiconDefinition($userId, $app, $key);
+
// there is a huge probability the non-lazy config are already loaded
// meaning that we can start by only checking if a current non-lazy key exists
if ($this->hasKey($userId, $app, $key, false)) {
@@ -349,6 +356,7 @@ class UserConfig implements IUserConfig {
?array $userIds = null,
): array {
$this->assertParams('', $app, $key, allowEmptyUser: true);
+ $this->matchAndApplyLexiconDefinition('', $app, $key);
$qb = $this->connection->getQueryBuilder();
$qb->select('userid', 'configvalue', 'type')
@@ -464,6 +472,7 @@ class UserConfig implements IUserConfig {
*/
private function searchUsersByTypedValue(string $app, string $key, string|array $value, bool $caseInsensitive = false): Generator {
$this->assertParams('', $app, $key, allowEmptyUser: true);
+ $this->matchAndApplyLexiconDefinition('', $app, $key);
$qb = $this->connection->getQueryBuilder();
$qb->from('preferences');
@@ -541,6 +550,7 @@ class UserConfig implements IUserConfig {
string $default = '',
?bool $lazy = false,
): string {
+ $this->matchAndApplyLexiconDefinition($userId, $app, $key);
try {
$lazy ??= $this->isLazy($userId, $app, $key);
} catch (UnknownKeyException) {
@@ -710,6 +720,7 @@ class UserConfig implements IUserConfig {
ValueType $type,
): string {
$this->assertParams($userId, $app, $key);
+ $origKey = $key;
if (!$this->matchAndApplyLexiconDefinition($userId, $app, $key, $lazy, $type, default: $default)) {
// returns default if strictness of lexicon is set to WARNING (block and report)
return $default;
@@ -746,6 +757,15 @@ class UserConfig implements IUserConfig {
}
$this->decryptSensitiveValue($userId, $app, $key, $value);
+
+ // in case the key was modified while running matchAndApplyLexiconDefinition() we are
+ // interested to check options in case a modification of the value is needed
+ // ie inverting value from previous key when using lexicon option RENAME_INVERT_BOOLEAN
+ if ($origKey !== $key && $type === ValueType::BOOL) {
+ $configManager = Server::get(ConfigManager::class);
+ $value = ($configManager->convertToBool($value, $this->getLexiconEntry($app, $key))) ? '1' : '0';
+ }
+
return $value;
}
@@ -764,6 +784,7 @@ class UserConfig implements IUserConfig {
public function getValueType(string $userId, string $app, string $key, ?bool $lazy = null): ValueType {
$this->assertParams($userId, $app, $key);
$this->loadConfig($userId, $lazy);
+ $this->matchAndApplyLexiconDefinition($userId, $app, $key);
if (!isset($this->valueDetails[$userId][$app][$key]['type'])) {
throw new UnknownKeyException('unknown config key');
@@ -788,6 +809,7 @@ class UserConfig implements IUserConfig {
public function getValueFlags(string $userId, string $app, string $key, bool $lazy = false): int {
$this->assertParams($userId, $app, $key);
$this->loadConfig($userId, $lazy);
+ $this->matchAndApplyLexiconDefinition($userId, $app, $key);
if (!isset($this->valueDetails[$userId][$app][$key])) {
throw new UnknownKeyException('unknown config key');
@@ -1045,6 +1067,11 @@ class UserConfig implements IUserConfig {
int $flags,
ValueType $type,
): bool {
+ // Primary email addresses are always(!) expected to be lowercase
+ if ($app === 'settings' && $key === 'email') {
+ $value = strtolower($value);
+ }
+
$this->assertParams($userId, $app, $key);
if (!$this->matchAndApplyLexiconDefinition($userId, $app, $key, $lazy, $type, $flags)) {
// returns false as database is not updated
@@ -1197,8 +1224,8 @@ class UserConfig implements IUserConfig {
public function updateType(string $userId, string $app, string $key, ValueType $type = ValueType::MIXED): bool {
$this->assertParams($userId, $app, $key);
$this->loadConfigAll($userId);
- // confirm key exists
- $this->isLazy($userId, $app, $key);
+ $this->matchAndApplyLexiconDefinition($userId, $app, $key);
+ $this->isLazy($userId, $app, $key); // confirm key exists
$update = $this->connection->getQueryBuilder();
$update->update('preferences')
@@ -1227,6 +1254,7 @@ class UserConfig implements IUserConfig {
public function updateSensitive(string $userId, string $app, string $key, bool $sensitive): bool {
$this->assertParams($userId, $app, $key);
$this->loadConfigAll($userId);
+ $this->matchAndApplyLexiconDefinition($userId, $app, $key);
try {
if ($sensitive === $this->isSensitive($userId, $app, $key, null)) {
@@ -1282,6 +1310,8 @@ class UserConfig implements IUserConfig {
*/
public function updateGlobalSensitive(string $app, string $key, bool $sensitive): void {
$this->assertParams('', $app, $key, allowEmptyUser: true);
+ $this->matchAndApplyLexiconDefinition('', $app, $key);
+
foreach (array_keys($this->getValuesByUsers($app, $key)) as $userId) {
try {
$this->updateSensitive($userId, $app, $key, $sensitive);
@@ -1311,6 +1341,7 @@ class UserConfig implements IUserConfig {
public function updateIndexed(string $userId, string $app, string $key, bool $indexed): bool {
$this->assertParams($userId, $app, $key);
$this->loadConfigAll($userId);
+ $this->matchAndApplyLexiconDefinition($userId, $app, $key);
try {
if ($indexed === $this->isIndexed($userId, $app, $key, null)) {
@@ -1366,6 +1397,8 @@ class UserConfig implements IUserConfig {
*/
public function updateGlobalIndexed(string $app, string $key, bool $indexed): void {
$this->assertParams('', $app, $key, allowEmptyUser: true);
+ $this->matchAndApplyLexiconDefinition('', $app, $key);
+
foreach (array_keys($this->getValuesByUsers($app, $key)) as $userId) {
try {
$this->updateIndexed($userId, $app, $key, $indexed);
@@ -1392,6 +1425,7 @@ class UserConfig implements IUserConfig {
public function updateLazy(string $userId, string $app, string $key, bool $lazy): bool {
$this->assertParams($userId, $app, $key);
$this->loadConfigAll($userId);
+ $this->matchAndApplyLexiconDefinition($userId, $app, $key);
try {
if ($lazy === $this->isLazy($userId, $app, $key)) {
@@ -1426,6 +1460,7 @@ class UserConfig implements IUserConfig {
*/
public function updateGlobalLazy(string $app, string $key, bool $lazy): void {
$this->assertParams('', $app, $key, allowEmptyUser: true);
+ $this->matchAndApplyLexiconDefinition('', $app, $key);
$update = $this->connection->getQueryBuilder();
$update->update('preferences')
@@ -1451,6 +1486,8 @@ class UserConfig implements IUserConfig {
public function getDetails(string $userId, string $app, string $key): array {
$this->assertParams($userId, $app, $key);
$this->loadConfigAll($userId);
+ $this->matchAndApplyLexiconDefinition($userId, $app, $key);
+
$lazy = $this->isLazy($userId, $app, $key);
if ($lazy) {
@@ -1498,6 +1535,8 @@ class UserConfig implements IUserConfig {
*/
public function deleteUserConfig(string $userId, string $app, string $key): void {
$this->assertParams($userId, $app, $key);
+ $this->matchAndApplyLexiconDefinition($userId, $app, $key);
+
$qb = $this->connection->getQueryBuilder();
$qb->delete('preferences')
->where($qb->expr()->eq('userid', $qb->createNamedParameter($userId)))
@@ -1520,6 +1559,8 @@ class UserConfig implements IUserConfig {
*/
public function deleteKey(string $app, string $key): void {
$this->assertParams('', $app, $key, allowEmptyUser: true);
+ $this->matchAndApplyLexiconDefinition('', $app, $key);
+
$qb = $this->connection->getQueryBuilder();
$qb->delete('preferences')
->where($qb->expr()->eq('appid', $qb->createNamedParameter($app)))
@@ -1538,6 +1579,7 @@ class UserConfig implements IUserConfig {
*/
public function deleteApp(string $app): void {
$this->assertParams('', $app, allowEmptyUser: true);
+
$qb = $this->connection->getQueryBuilder();
$qb->delete('preferences')
->where($qb->expr()->eq('appid', $qb->createNamedParameter($app)));
@@ -1830,7 +1872,8 @@ class UserConfig implements IUserConfig {
}
/**
- * match and apply current use of config values with defined lexicon
+ * Match and apply current use of config values with defined lexicon.
+ * Set $lazy to NULL only if only interested into checking that $key is alias.
*
* @throws UnknownKeyException
* @throws TypeConflictException
@@ -1839,17 +1882,27 @@ class UserConfig implements IUserConfig {
private function matchAndApplyLexiconDefinition(
string $userId,
string $app,
- string $key,
- bool &$lazy,
- ValueType &$type,
+ string &$key,
+ ?bool &$lazy = null,
+ ValueType &$type = ValueType::MIXED,
int &$flags = 0,
string &$default = '',
): bool {
$configDetails = $this->getConfigDetailsFromLexicon($app);
+ if (array_key_exists($key, $configDetails['aliases']) && !$this->ignoreLexiconAliases) {
+ // in case '$rename' is set in ConfigLexiconEntry, we use the new config key
+ $key = $configDetails['aliases'][$key];
+ }
+
if (!array_key_exists($key, $configDetails['entries'])) {
return $this->applyLexiconStrictness($configDetails['strictness'], 'The user config key ' . $app . '/' . $key . ' is not defined in the config lexicon');
}
+ // if lazy is NULL, we ignore all check on the type/lazyness/default from Lexicon
+ if ($lazy === null) {
+ return true;
+ }
+
/** @var ConfigLexiconEntry $configValue */
$configValue = $configDetails['entries'][$key];
if ($type === ValueType::MIXED) {
@@ -1934,24 +1987,42 @@ class UserConfig implements IUserConfig {
* extract details from registered $appId's config lexicon
*
* @param string $appId
+ * @internal
*
- * @return array{entries: array<array-key, ConfigLexiconEntry>, strictness: ConfigLexiconStrictness}
+ * @return array{entries: array<string, ConfigLexiconEntry>, aliases: array<string, string>, strictness: ConfigLexiconStrictness}
*/
- private function getConfigDetailsFromLexicon(string $appId): array {
+ public function getConfigDetailsFromLexicon(string $appId): array {
if (!array_key_exists($appId, $this->configLexiconDetails)) {
- $entries = [];
+ $entries = $aliases = [];
$bootstrapCoordinator = \OCP\Server::get(Coordinator::class);
$configLexicon = $bootstrapCoordinator->getRegistrationContext()?->getConfigLexicon($appId);
foreach ($configLexicon?->getUserConfigs() ?? [] as $configEntry) {
$entries[$configEntry->getKey()] = $configEntry;
+ if ($configEntry->getRename() !== null) {
+ $aliases[$configEntry->getRename()] = $configEntry->getKey();
+ }
}
$this->configLexiconDetails[$appId] = [
'entries' => $entries,
+ 'aliases' => $aliases,
'strictness' => $configLexicon?->getStrictness() ?? ConfigLexiconStrictness::IGNORE
];
}
return $this->configLexiconDetails[$appId];
}
+
+ private function getLexiconEntry(string $appId, string $key): ?ConfigLexiconEntry {
+ return $this->getConfigDetailsFromLexicon($appId)['entries'][$key] ?? null;
+ }
+
+ /**
+ * if set to TRUE, ignore aliases defined in Config Lexicon during the use of the methods of this class
+ *
+ * @internal
+ */
+ public function ignoreLexiconAliases(bool $ignore): void {
+ $this->ignoreLexiconAliases = $ignore;
+ }
}
diff --git a/lib/private/DB/QueryBuilder/Partitioned/PartitionedQueryBuilder.php b/lib/private/DB/QueryBuilder/Partitioned/PartitionedQueryBuilder.php
index 2942eeccdf7..8b051561a2e 100644
--- a/lib/private/DB/QueryBuilder/Partitioned/PartitionedQueryBuilder.php
+++ b/lib/private/DB/QueryBuilder/Partitioned/PartitionedQueryBuilder.php
@@ -444,4 +444,19 @@ class PartitionedQueryBuilder extends ShardedQueryBuilder {
public function getPartitionCount(): int {
return count($this->splitQueries) + 1;
}
+
+ public function hintShardKey(string $column, mixed $value, bool $overwrite = false): self {
+ if (str_contains($column, '.')) {
+ [$alias, $column] = explode('.', $column);
+ $partition = $this->getPartition($alias);
+ if ($partition) {
+ $this->splitQueries[$partition->name]->query->hintShardKey($column, $value, $overwrite);
+ } else {
+ parent::hintShardKey($column, $value, $overwrite);
+ }
+ } else {
+ parent::hintShardKey($column, $value, $overwrite);
+ }
+ return $this;
+ }
}
diff --git a/lib/private/Encryption/EncryptionEventListener.php b/lib/private/Encryption/EncryptionEventListener.php
new file mode 100644
index 00000000000..d51b4b0d531
--- /dev/null
+++ b/lib/private/Encryption/EncryptionEventListener.php
@@ -0,0 +1,100 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+namespace OC\Encryption;
+
+use OC\Files\SetupManager;
+use OC\Files\View;
+use OCA\Files_Trashbin\Events\NodeRestoredEvent;
+use OCP\Encryption\IFile;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventDispatcher;
+use OCP\EventDispatcher\IEventListener;
+use OCP\Files\Events\Node\NodeRenamedEvent;
+use OCP\Files\NotFoundException;
+use OCP\IUser;
+use OCP\IUserManager;
+use OCP\IUserSession;
+use OCP\Share\Events\ShareCreatedEvent;
+use OCP\Share\Events\ShareDeletedEvent;
+use Psr\Log\LoggerInterface;
+
+/** @template-implements IEventListener<NodeRenamedEvent|ShareCreatedEvent|ShareDeletedEvent|NodeRestoredEvent> */
+class EncryptionEventListener implements IEventListener {
+ private ?Update $updater = null;
+
+ public function __construct(
+ private IUserSession $userSession,
+ private SetupManager $setupManager,
+ private Manager $encryptionManager,
+ private IUserManager $userManager,
+ ) {
+ }
+
+ public static function register(IEventDispatcher $dispatcher): void {
+ $dispatcher->addServiceListener(NodeRenamedEvent::class, static::class);
+ $dispatcher->addServiceListener(ShareCreatedEvent::class, static::class);
+ $dispatcher->addServiceListener(ShareDeletedEvent::class, static::class);
+ $dispatcher->addServiceListener(NodeRestoredEvent::class, static::class);
+ }
+
+ public function handle(Event $event): void {
+ if (!$this->encryptionManager->isEnabled()) {
+ return;
+ }
+ if ($event instanceof NodeRenamedEvent) {
+ $this->getUpdate()->postRename($event->getSource(), $event->getTarget());
+ } elseif ($event instanceof ShareCreatedEvent) {
+ $this->getUpdate()->postShared($event->getShare()->getNode());
+ } elseif ($event instanceof ShareDeletedEvent) {
+ try {
+ // In case the unsharing happens in a background job, we don't have
+ // a session and we load instead the user from the UserManager
+ $owner = $this->userManager->get($event->getShare()->getShareOwner());
+ $this->getUpdate($owner)->postUnshared($event->getShare()->getNode());
+ } catch (NotFoundException $e) {
+ /* The node was deleted already, nothing to update */
+ }
+ } elseif ($event instanceof NodeRestoredEvent) {
+ $this->getUpdate()->postRestore($event->getTarget());
+ }
+ }
+
+ private function getUpdate(?IUser $owner = null): Update {
+ if (is_null($this->updater)) {
+ $user = $this->userSession->getUser();
+ if (!$user && ($owner !== null)) {
+ $user = $owner;
+ }
+ if (!$user) {
+ throw new \Exception('Inconsistent data, File unshared, but owner not found. Should not happen');
+ }
+
+ $uid = $user->getUID();
+
+ if (!$this->setupManager->isSetupComplete($user)) {
+ $this->setupManager->setupForUser($user);
+ }
+
+ $this->updater = new Update(
+ new Util(
+ new View(),
+ $this->userManager,
+ \OC::$server->getGroupManager(),
+ \OC::$server->getConfig()),
+ \OC::$server->getEncryptionManager(),
+ \OC::$server->get(IFile::class),
+ \OC::$server->get(LoggerInterface::class),
+ $uid
+ );
+ }
+
+ return $this->updater;
+ }
+}
diff --git a/lib/private/Encryption/EncryptionWrapper.php b/lib/private/Encryption/EncryptionWrapper.php
index 7f355b603d6..b9db9616538 100644
--- a/lib/private/Encryption/EncryptionWrapper.php
+++ b/lib/private/Encryption/EncryptionWrapper.php
@@ -75,15 +75,6 @@ class EncryptionWrapper {
\OC::$server->getGroupManager(),
\OC::$server->getConfig()
);
- $update = new Update(
- new View(),
- $util,
- Filesystem::getMountManager(),
- $this->manager,
- $fileHelper,
- $this->logger,
- $uid
- );
return new Encryption(
$parameters,
$this->manager,
@@ -92,7 +83,6 @@ class EncryptionWrapper {
$fileHelper,
$uid,
$keyStorage,
- $update,
$mountManager,
$this->arrayCache
);
diff --git a/lib/private/Encryption/HookManager.php b/lib/private/Encryption/HookManager.php
deleted file mode 100644
index 39e7edabb95..00000000000
--- a/lib/private/Encryption/HookManager.php
+++ /dev/null
@@ -1,75 +0,0 @@
-<?php
-
-/**
- * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
- * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
- * SPDX-License-Identifier: AGPL-3.0-only
- */
-namespace OC\Encryption;
-
-use OC\Files\Filesystem;
-use OC\Files\SetupManager;
-use OC\Files\View;
-use OCP\Encryption\IFile;
-use Psr\Log\LoggerInterface;
-
-class HookManager {
- private static ?Update $updater = null;
-
- public static function postShared($params): void {
- self::getUpdate()->postShared($params);
- }
- public static function postUnshared($params): void {
- // In case the unsharing happens in a background job, we don't have
- // a session and we load instead the user from the UserManager
- $path = Filesystem::getPath($params['fileSource']);
- $owner = Filesystem::getOwner($path);
- self::getUpdate($owner)->postUnshared($params);
- }
-
- public static function postRename($params): void {
- self::getUpdate()->postRename($params);
- }
-
- public static function postRestore($params): void {
- self::getUpdate()->postRestore($params);
- }
-
- private static function getUpdate(?string $owner = null): Update {
- if (is_null(self::$updater)) {
- $user = \OC::$server->getUserSession()->getUser();
- if (!$user && $owner) {
- $user = \OC::$server->getUserManager()->get($owner);
- }
- if (!$user) {
- throw new \Exception('Inconsistent data, File unshared, but owner not found. Should not happen');
- }
-
- $uid = '';
- if ($user) {
- $uid = $user->getUID();
- }
-
- $setupManager = \OC::$server->get(SetupManager::class);
- if (!$setupManager->isSetupComplete($user)) {
- $setupManager->setupForUser($user);
- }
-
- self::$updater = new Update(
- new View(),
- new Util(
- new View(),
- \OC::$server->getUserManager(),
- \OC::$server->getGroupManager(),
- \OC::$server->getConfig()),
- Filesystem::getMountManager(),
- \OC::$server->getEncryptionManager(),
- \OC::$server->get(IFile::class),
- \OC::$server->get(LoggerInterface::class),
- $uid
- );
- }
-
- return self::$updater;
- }
-}
diff --git a/lib/private/Encryption/Update.php b/lib/private/Encryption/Update.php
index 0b27d63c19a..293a1ce653c 100644
--- a/lib/private/Encryption/Update.php
+++ b/lib/private/Encryption/Update.php
@@ -1,146 +1,85 @@
<?php
+declare(strict_types=1);
+
/**
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
* SPDX-License-Identifier: AGPL-3.0-only
*/
+
namespace OC\Encryption;
use InvalidArgumentException;
-use OC\Files\Filesystem;
-use OC\Files\Mount;
use OC\Files\View;
use OCP\Encryption\Exceptions\GenericEncryptionException;
+use OCP\Files\File as OCPFile;
+use OCP\Files\Folder;
+use OCP\Files\NotFoundException;
use Psr\Log\LoggerInterface;
/**
* update encrypted files, e.g. because a file was shared
*/
class Update {
- /** @var View */
- protected $view;
-
- /** @var Util */
- protected $util;
-
- /** @var \OC\Files\Mount\Manager */
- protected $mountManager;
-
- /** @var Manager */
- protected $encryptionManager;
-
- /** @var string */
- protected $uid;
-
- /** @var File */
- protected $file;
-
- /** @var LoggerInterface */
- protected $logger;
-
- /**
- * @param string $uid
- */
public function __construct(
- View $view,
- Util $util,
- Mount\Manager $mountManager,
- Manager $encryptionManager,
- File $file,
- LoggerInterface $logger,
- $uid,
+ protected Util $util,
+ protected Manager $encryptionManager,
+ protected File $file,
+ protected LoggerInterface $logger,
+ protected string $uid,
) {
- $this->view = $view;
- $this->util = $util;
- $this->mountManager = $mountManager;
- $this->encryptionManager = $encryptionManager;
- $this->file = $file;
- $this->logger = $logger;
- $this->uid = $uid;
}
/**
* hook after file was shared
- *
- * @param array $params
*/
- public function postShared($params) {
- if ($this->encryptionManager->isEnabled()) {
- if ($params['itemType'] === 'file' || $params['itemType'] === 'folder') {
- $path = Filesystem::getPath($params['fileSource']);
- [$owner, $ownerPath] = $this->getOwnerPath($path);
- $absPath = '/' . $owner . '/files/' . $ownerPath;
- $this->update($absPath);
- }
- }
+ public function postShared(OCPFile|Folder $node): void {
+ $this->update($node);
}
/**
* hook after file was unshared
- *
- * @param array $params
*/
- public function postUnshared($params) {
- if ($this->encryptionManager->isEnabled()) {
- if ($params['itemType'] === 'file' || $params['itemType'] === 'folder') {
- $path = Filesystem::getPath($params['fileSource']);
- [$owner, $ownerPath] = $this->getOwnerPath($path);
- $absPath = '/' . $owner . '/files/' . $ownerPath;
- $this->update($absPath);
- }
- }
+ public function postUnshared(OCPFile|Folder $node): void {
+ $this->update($node);
}
/**
* inform encryption module that a file was restored from the trash bin,
* e.g. to update the encryption keys
- *
- * @param array $params
*/
- public function postRestore($params) {
- if ($this->encryptionManager->isEnabled()) {
- $path = Filesystem::normalizePath('/' . $this->uid . '/files/' . $params['filePath']);
- $this->update($path);
- }
+ public function postRestore(OCPFile|Folder $node): void {
+ $this->update($node);
}
/**
* inform encryption module that a file was renamed,
* e.g. to update the encryption keys
- *
- * @param array $params
*/
- public function postRename($params) {
- $source = $params['oldpath'];
- $target = $params['newpath'];
- if (
- $this->encryptionManager->isEnabled() &&
- dirname($source) !== dirname($target)
- ) {
- [$owner, $ownerPath] = $this->getOwnerPath($target);
- $absPath = '/' . $owner . '/files/' . $ownerPath;
- $this->update($absPath);
+ public function postRename(OCPFile|Folder $source, OCPFile|Folder $target): void {
+ if (dirname($source->getPath()) !== dirname($target->getPath())) {
+ $this->update($target);
}
}
/**
- * get owner and path relative to data/<owner>/files
+ * get owner and path relative to data/
*
- * @param string $path path to file for current user
- * @return array ['owner' => $owner, 'path' => $path]
* @throws \InvalidArgumentException
*/
- protected function getOwnerPath($path) {
- $info = Filesystem::getFileInfo($path);
- $owner = Filesystem::getOwner($path);
+ protected function getOwnerPath(OCPFile|Folder $node): string {
+ $owner = $node->getOwner()?->getUID();
+ if ($owner === null) {
+ throw new InvalidArgumentException('No owner found for ' . $node->getId());
+ }
$view = new View('/' . $owner . '/files');
- $path = $view->getPath($info->getId());
- if ($path === null) {
- throw new InvalidArgumentException('No file found for ' . $info->getId());
+ try {
+ $path = $view->getPath($node->getId());
+ } catch (NotFoundException $e) {
+ throw new InvalidArgumentException('No file found for ' . $node->getId(), previous:$e);
}
-
- return [$owner, $path];
+ return '/' . $owner . '/files/' . $path;
}
/**
@@ -149,7 +88,7 @@ class Update {
* @param string $path relative to data/
* @throws Exceptions\ModuleDoesNotExistsException
*/
- public function update($path) {
+ public function update(OCPFile|Folder $node): void {
$encryptionModule = $this->encryptionManager->getEncryptionModule();
// if the encryption module doesn't encrypt the files on a per-user basis
@@ -158,15 +97,14 @@ class Update {
return;
}
+ $path = $this->getOwnerPath($node);
// if a folder was shared, get a list of all (sub-)folders
- if ($this->view->is_dir($path)) {
+ if ($node instanceof Folder) {
$allFiles = $this->util->getAllFiles($path);
} else {
$allFiles = [$path];
}
-
-
foreach ($allFiles as $file) {
$usersSharing = $this->file->getAccessList($file);
try {
diff --git a/lib/private/Encryption/Util.php b/lib/private/Encryption/Util.php
index 1fb08b15696..0566ab9a760 100644
--- a/lib/private/Encryption/Util.php
+++ b/lib/private/Encryption/Util.php
@@ -304,7 +304,7 @@ class Util {
// detect user specific folders
if ($this->userManager->userExists($root[1])
- && in_array($root[2], $this->excludedPaths)) {
+ && in_array($root[2] ?? '', $this->excludedPaths)) {
return true;
}
}
diff --git a/lib/private/Files/Cache/Cache.php b/lib/private/Files/Cache/Cache.php
index 2c190720c23..cb160115851 100644
--- a/lib/private/Files/Cache/Cache.php
+++ b/lib/private/Files/Cache/Cache.php
@@ -663,7 +663,7 @@ class Cache implements ICache {
$sourceData = $sourceCache->get($sourcePath);
if (!$sourceData) {
- throw new \Exception('Invalid source storage path: ' . $sourcePath);
+ throw new \Exception('Source path not found in cache: ' . $sourcePath);
}
$shardDefinition = $this->connection->getShardDefinition('filecache');
diff --git a/lib/private/Files/Cache/Scanner.php b/lib/private/Files/Cache/Scanner.php
index 1fb408a0655..b067f70b8cb 100644
--- a/lib/private/Files/Cache/Scanner.php
+++ b/lib/private/Files/Cache/Scanner.php
@@ -210,7 +210,7 @@ class Scanner extends BasicEmitter implements IScanner {
* @var \OC\Files\Cache\CacheEntry $cacheData
*/
$newData = $this->array_diff_assoc_multi($data, $cacheData->getData());
-
+
// make it known to the caller that etag has been changed and needs propagation
if (isset($newData['etag'])) {
$data['etag_changed'] = true;
@@ -351,23 +351,23 @@ class Scanner extends BasicEmitter implements IScanner {
*
*/
protected function array_diff_assoc_multi(array $array1, array $array2) {
-
+
$result = [];
foreach ($array1 as $key => $value) {
-
+
// if $array2 doesn't have the same key, that's a result
if (!array_key_exists($key, $array2)) {
$result[$key] = $value;
continue;
}
-
+
// if $array2's value for the same key is different, that's a result
if ($array2[$key] !== $value && !is_array($value)) {
$result[$key] = $value;
continue;
}
-
+
if (is_array($value)) {
$nestedDiff = $this->array_diff_assoc_multi($value, $array2[$key]);
if (!empty($nestedDiff)) {
diff --git a/lib/private/Files/Cache/Storage.php b/lib/private/Files/Cache/Storage.php
index 2b49e65f0b4..1a3bda58e6a 100644
--- a/lib/private/Files/Cache/Storage.php
+++ b/lib/private/Files/Cache/Storage.php
@@ -213,6 +213,7 @@ class Storage {
$query = $db->getQueryBuilder();
$query->delete('filecache')
->where($query->expr()->in('storage', $query->createNamedParameter($storageIds, IQueryBuilder::PARAM_INT_ARRAY)));
+ $query->runAcrossAllShards();
$query->executeStatement();
$query = $db->getQueryBuilder();
diff --git a/lib/private/Files/Cache/Wrapper/CacheJail.php b/lib/private/Files/Cache/Wrapper/CacheJail.php
index 5c7bd4334f3..5bc4ee8529d 100644
--- a/lib/private/Files/Cache/Wrapper/CacheJail.php
+++ b/lib/private/Files/Cache/Wrapper/CacheJail.php
@@ -31,10 +31,13 @@ class CacheJail extends CacheWrapper {
) {
parent::__construct($cache, $dependencies);
- if ($cache instanceof CacheJail) {
- $this->unjailedRoot = $cache->getSourcePath($root);
- } else {
- $this->unjailedRoot = $root;
+ $this->unjailedRoot = $root;
+ $parent = $cache;
+ while ($parent instanceof CacheWrapper) {
+ if ($parent instanceof CacheJail) {
+ $this->unjailedRoot = $parent->getSourcePath($this->unjailedRoot);
+ }
+ $parent = $parent->getCache();
}
}
@@ -50,7 +53,7 @@ class CacheJail extends CacheWrapper {
*
* @return string
*/
- protected function getGetUnjailedRoot() {
+ public function getGetUnjailedRoot() {
return $this->unjailedRoot;
}
diff --git a/lib/private/Files/Config/MountProviderCollection.php b/lib/private/Files/Config/MountProviderCollection.php
index 6a5407934c8..9d63184e05f 100644
--- a/lib/private/Files/Config/MountProviderCollection.php
+++ b/lib/private/Files/Config/MountProviderCollection.php
@@ -24,60 +24,43 @@ class MountProviderCollection implements IMountProviderCollection, Emitter {
use EmitterTrait;
/**
- * @var \OCP\Files\Config\IHomeMountProvider[]
+ * @var list<IHomeMountProvider>
*/
- private $homeProviders = [];
+ private array $homeProviders = [];
/**
- * @var \OCP\Files\Config\IMountProvider[]
+ * @var list<IMountProvider>
*/
- private $providers = [];
+ private array $providers = [];
- /** @var \OCP\Files\Config\IRootMountProvider[] */
- private $rootProviders = [];
+ /** @var list<IRootMountProvider> */
+ private array $rootProviders = [];
- /**
- * @var \OCP\Files\Storage\IStorageFactory
- */
- private $loader;
-
- /**
- * @var \OCP\Files\Config\IUserMountCache
- */
- private $mountCache;
-
- /** @var callable[] */
- private $mountFilters = [];
+ /** @var list<callable> */
+ private array $mountFilters = [];
- private IEventLogger $eventLogger;
-
- /**
- * @param \OCP\Files\Storage\IStorageFactory $loader
- * @param IUserMountCache $mountCache
- */
public function __construct(
- IStorageFactory $loader,
- IUserMountCache $mountCache,
- IEventLogger $eventLogger,
+ private IStorageFactory $loader,
+ private IUserMountCache $mountCache,
+ private IEventLogger $eventLogger,
) {
- $this->loader = $loader;
- $this->mountCache = $mountCache;
- $this->eventLogger = $eventLogger;
}
+ /**
+ * @return list<IMountPoint>
+ */
private function getMountsFromProvider(IMountProvider $provider, IUser $user, IStorageFactory $loader): array {
$class = str_replace('\\', '_', get_class($provider));
$uid = $user->getUID();
$this->eventLogger->start('fs:setup:provider:' . $class, "Getting mounts from $class for $uid");
$mounts = $provider->getMountsForUser($user, $loader) ?? [];
$this->eventLogger->end('fs:setup:provider:' . $class);
- return $mounts;
+ return array_values($mounts);
}
/**
- * @param IUser $user
- * @param IMountProvider[] $providers
- * @return IMountPoint[]
+ * @param list<IMountProvider> $providers
+ * @return list<IMountPoint>
*/
private function getUserMountsForProviders(IUser $user, array $providers): array {
$loader = $this->loader;
@@ -90,10 +73,16 @@ class MountProviderCollection implements IMountProviderCollection, Emitter {
return $this->filterMounts($user, $mounts);
}
+ /**
+ * @return list<IMountPoint>
+ */
public function getMountsForUser(IUser $user): array {
return $this->getUserMountsForProviders($user, $this->providers);
}
+ /**
+ * @return list<IMountPoint>
+ */
public function getUserMountsForProviderClasses(IUser $user, array $mountProviderClasses): array {
$providers = array_filter(
$this->providers,
@@ -102,7 +91,10 @@ class MountProviderCollection implements IMountProviderCollection, Emitter {
return $this->getUserMountsForProviders($user, $providers);
}
- public function addMountForUser(IUser $user, IMountManager $mountManager, ?callable $providerFilter = null) {
+ /**
+ * @return list<IMountPoint>
+ */
+ public function addMountForUser(IUser $user, IMountManager $mountManager, ?callable $providerFilter = null): array {
// shared mount provider gets to go last since it needs to know existing files
// to check for name collisions
$firstMounts = [];
@@ -135,18 +127,15 @@ class MountProviderCollection implements IMountProviderCollection, Emitter {
array_walk($lateMounts, [$mountManager, 'addMount']);
$this->eventLogger->end('fs:setup:add-mounts');
- return array_merge($lateMounts, $firstMounts);
+ return array_values(array_merge($lateMounts, $firstMounts));
}
/**
* Get the configured home mount for this user
*
- * @param \OCP\IUser $user
- * @return \OCP\Files\Mount\IMountPoint
* @since 9.1.0
*/
- public function getHomeMountForUser(IUser $user) {
- /** @var \OCP\Files\Config\IHomeMountProvider[] $providers */
+ public function getHomeMountForUser(IUser $user): IMountPoint {
$providers = array_reverse($this->homeProviders); // call the latest registered provider first to give apps an opportunity to overwrite builtin
foreach ($providers as $homeProvider) {
if ($mount = $homeProvider->getHomeMountForUser($user, $this->loader)) {
@@ -159,34 +148,36 @@ class MountProviderCollection implements IMountProviderCollection, Emitter {
/**
* Add a provider for mount points
- *
- * @param \OCP\Files\Config\IMountProvider $provider
*/
- public function registerProvider(IMountProvider $provider) {
+ public function registerProvider(IMountProvider $provider): void {
$this->providers[] = $provider;
$this->emit('\OC\Files\Config', 'registerMountProvider', [$provider]);
}
- public function registerMountFilter(callable $filter) {
+ public function registerMountFilter(callable $filter): void {
$this->mountFilters[] = $filter;
}
- private function filterMounts(IUser $user, array $mountPoints) {
- return array_filter($mountPoints, function (IMountPoint $mountPoint) use ($user) {
+ /**
+ * @param list<IMountPoint> $mountPoints
+ * @return list<IMountPoint>
+ */
+ private function filterMounts(IUser $user, array $mountPoints): array {
+ return array_values(array_filter($mountPoints, function (IMountPoint $mountPoint) use ($user) {
foreach ($this->mountFilters as $filter) {
if ($filter($mountPoint, $user) === false) {
return false;
}
}
return true;
- });
+ }));
}
/**
* Add a provider for home mount points
*
- * @param \OCP\Files\Config\IHomeMountProvider $provider
+ * @param IHomeMountProvider $provider
* @since 9.1.0
*/
public function registerHomeProvider(IHomeMountProvider $provider) {
@@ -196,21 +187,19 @@ class MountProviderCollection implements IMountProviderCollection, Emitter {
/**
* Get the mount cache which can be used to search for mounts without setting up the filesystem
- *
- * @return IUserMountCache
*/
- public function getMountCache() {
+ public function getMountCache(): IUserMountCache {
return $this->mountCache;
}
- public function registerRootProvider(IRootMountProvider $provider) {
+ public function registerRootProvider(IRootMountProvider $provider): void {
$this->rootProviders[] = $provider;
}
/**
* Get all root mountpoints
*
- * @return \OCP\Files\Mount\IMountPoint[]
+ * @return list<IMountPoint>
* @since 20.0.0
*/
public function getRootMounts(): array {
@@ -226,16 +215,33 @@ class MountProviderCollection implements IMountProviderCollection, Emitter {
throw new \Exception('No root mounts provided by any provider');
}
- return $mounts;
+ return array_values($mounts);
}
- public function clearProviders() {
+ public function clearProviders(): void {
$this->providers = [];
$this->homeProviders = [];
$this->rootProviders = [];
}
+ /**
+ * @return list<IMountProvider>
+ */
public function getProviders(): array {
return $this->providers;
}
+
+ /**
+ * @return list<IHomeMountProvider>
+ */
+ public function getHomeProviders(): array {
+ return $this->homeProviders;
+ }
+
+ /**
+ * @return list<IRootMountProvider>
+ */
+ public function getRootProviders(): array {
+ return $this->rootProviders;
+ }
}
diff --git a/lib/private/Files/Config/UserMountCache.php b/lib/private/Files/Config/UserMountCache.php
index 9c1e2314262..09ac6d1416a 100644
--- a/lib/private/Files/Config/UserMountCache.php
+++ b/lib/private/Files/Config/UserMountCache.php
@@ -11,6 +11,10 @@ use OC\User\LazyUser;
use OCP\Cache\CappedMemoryCache;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Diagnostics\IEventLogger;
+use OCP\EventDispatcher\IEventDispatcher;
+use OCP\Files\Config\Event\UserMountAddedEvent;
+use OCP\Files\Config\Event\UserMountRemovedEvent;
+use OCP\Files\Config\Event\UserMountUpdatedEvent;
use OCP\Files\Config\ICachedMountFileInfo;
use OCP\Files\Config\ICachedMountInfo;
use OCP\Files\Config\IUserMountCache;
@@ -46,6 +50,7 @@ class UserMountCache implements IUserMountCache {
private IUserManager $userManager,
private LoggerInterface $logger,
private IEventLogger $eventLogger,
+ private IEventDispatcher $eventDispatcher,
) {
$this->cacheInfoCache = new CappedMemoryCache();
$this->internalPathCache = new CappedMemoryCache();
@@ -108,17 +113,29 @@ class UserMountCache implements IUserMountCache {
$this->removeFromCache($mount);
unset($this->mountsForUsers[$userUID][$mount->getKey()]);
}
- foreach ($changedMounts as $mount) {
- $this->logger->debug("Updating mount '{$mount->getKey()}' for user '$userUID'", ['app' => 'files', 'mount_provider' => $mount->getMountProvider()]);
- $this->updateCachedMount($mount);
+ foreach ($changedMounts as $mountPair) {
+ $newMount = $mountPair[1];
+ $this->logger->debug("Updating mount '{$newMount->getKey()}' for user '$userUID'", ['app' => 'files', 'mount_provider' => $newMount->getMountProvider()]);
+ $this->updateCachedMount($newMount);
/** @psalm-suppress InvalidArgument */
- $this->mountsForUsers[$userUID][$mount->getKey()] = $mount;
+ $this->mountsForUsers[$userUID][$newMount->getKey()] = $newMount;
}
$this->connection->commit();
} catch (\Throwable $e) {
$this->connection->rollBack();
throw $e;
}
+
+ // Only fire events after all mounts have already been adjusted in the database.
+ foreach ($addedMounts as $mount) {
+ $this->eventDispatcher->dispatchTyped(new UserMountAddedEvent($mount));
+ }
+ foreach ($removedMounts as $mount) {
+ $this->eventDispatcher->dispatchTyped(new UserMountRemovedEvent($mount));
+ }
+ foreach ($changedMounts as $mountPair) {
+ $this->eventDispatcher->dispatchTyped(new UserMountUpdatedEvent($mountPair[0], $mountPair[1]));
+ }
}
$this->eventLogger->end('fs:setup:user:register');
}
@@ -126,9 +143,9 @@ class UserMountCache implements IUserMountCache {
/**
* @param array<string, ICachedMountInfo> $newMounts
* @param array<string, ICachedMountInfo> $cachedMounts
- * @return ICachedMountInfo[]
+ * @return list<list{0: ICachedMountInfo, 1: ICachedMountInfo}> Pairs of old and new mounts
*/
- private function findChangedMounts(array $newMounts, array $cachedMounts) {
+ private function findChangedMounts(array $newMounts, array $cachedMounts): array {
$changed = [];
foreach ($cachedMounts as $key => $cachedMount) {
if (isset($newMounts[$key])) {
@@ -138,7 +155,7 @@ class UserMountCache implements IUserMountCache {
$newMount->getMountId() !== $cachedMount->getMountId() ||
$newMount->getMountProvider() !== $cachedMount->getMountProvider()
) {
- $changed[] = $newMount;
+ $changed[] = [$cachedMount, $newMount];
}
}
}
diff --git a/lib/private/Files/FilenameValidator.php b/lib/private/Files/FilenameValidator.php
index b1979789ec8..a78c6d3cc3c 100644
--- a/lib/private/Files/FilenameValidator.php
+++ b/lib/private/Files/FilenameValidator.php
@@ -228,6 +228,43 @@ class FilenameValidator implements IFilenameValidator {
return false;
}
+ public function sanitizeFilename(string $name, ?string $charReplacement = null): string {
+ $forbiddenCharacters = $this->getForbiddenCharacters();
+
+ if ($charReplacement === null) {
+ $charReplacement = array_diff(['_', '-', ' '], $forbiddenCharacters);
+ $charReplacement = reset($charReplacement) ?: '';
+ }
+ if (mb_strlen($charReplacement) !== 1) {
+ throw new \InvalidArgumentException('No or invalid character replacement given');
+ }
+
+ $nameLowercase = mb_strtolower($name);
+ foreach ($this->getForbiddenExtensions() as $extension) {
+ if (str_ends_with($nameLowercase, $extension)) {
+ $name = substr($name, 0, strlen($name) - strlen($extension));
+ }
+ }
+
+ $basename = strlen($name) > 1
+ ? substr($name, 0, strpos($name, '.', 1) ?: null)
+ : $name;
+ if (in_array(mb_strtolower($basename), $this->getForbiddenBasenames())) {
+ $name = str_replace($basename, $this->l10n->t('%1$s (renamed)', [$basename]), $name);
+ }
+
+ if ($name === '') {
+ $name = $this->l10n->t('renamed file');
+ }
+
+ if (in_array(mb_strtolower($name), $this->getForbiddenFilenames())) {
+ $name = $this->l10n->t('%1$s (renamed)', [$name]);
+ }
+
+ $name = str_replace($forbiddenCharacters, $charReplacement, $name);
+ return $name;
+ }
+
protected function checkForbiddenName(string $filename): void {
$filename = mb_strtolower($filename);
if ($this->isForbidden($filename)) {
diff --git a/lib/private/Files/Mount/ObjectHomeMountProvider.php b/lib/private/Files/Mount/ObjectHomeMountProvider.php
index 99c52108fa8..4b088f2c808 100644
--- a/lib/private/Files/Mount/ObjectHomeMountProvider.php
+++ b/lib/private/Files/Mount/ObjectHomeMountProvider.php
@@ -7,117 +7,39 @@
*/
namespace OC\Files\Mount;
+use OC\Files\ObjectStore\HomeObjectStoreStorage;
+use OC\Files\ObjectStore\PrimaryObjectStoreConfig;
use OCP\Files\Config\IHomeMountProvider;
+use OCP\Files\Mount\IMountPoint;
use OCP\Files\Storage\IStorageFactory;
-use OCP\IConfig;
use OCP\IUser;
-use Psr\Log\LoggerInterface;
/**
* Mount provider for object store home storages
*/
class ObjectHomeMountProvider implements IHomeMountProvider {
- /**
- * @var IConfig
- */
- private $config;
-
- /**
- * ObjectStoreHomeMountProvider constructor.
- *
- * @param IConfig $config
- */
- public function __construct(IConfig $config) {
- $this->config = $config;
+ public function __construct(
+ private PrimaryObjectStoreConfig $objectStoreConfig,
+ ) {
}
/**
- * Get the cache mount for a user
+ * Get the home mount for a user
*
* @param IUser $user
* @param IStorageFactory $loader
- * @return \OCP\Files\Mount\IMountPoint
+ * @return ?IMountPoint
*/
- public function getHomeMountForUser(IUser $user, IStorageFactory $loader) {
- $config = $this->getMultiBucketObjectStoreConfig($user);
- if ($config === null) {
- $config = $this->getSingleBucketObjectStoreConfig($user);
- }
-
- if ($config === null) {
+ public function getHomeMountForUser(IUser $user, IStorageFactory $loader): ?IMountPoint {
+ $objectStoreConfig = $this->objectStoreConfig->getObjectStoreConfigForUser($user);
+ if ($objectStoreConfig === null) {
return null;
}
+ $arguments = array_merge($objectStoreConfig['arguments'], [
+ 'objectstore' => $this->objectStoreConfig->buildObjectStore($objectStoreConfig),
+ 'user' => $user,
+ ]);
- return new HomeMountPoint($user, '\OC\Files\ObjectStore\HomeObjectStoreStorage', '/' . $user->getUID(), $config['arguments'], $loader, null, null, self::class);
- }
-
- /**
- * @param IUser $user
- * @return array|null
- */
- private function getSingleBucketObjectStoreConfig(IUser $user) {
- $config = $this->config->getSystemValue('objectstore');
- if (!is_array($config)) {
- return null;
- }
-
- // sanity checks
- if (empty($config['class'])) {
- \OC::$server->get(LoggerInterface::class)->error('No class given for objectstore', ['app' => 'files']);
- }
- if (!isset($config['arguments'])) {
- $config['arguments'] = [];
- }
- // instantiate object store implementation
- $config['arguments']['objectstore'] = new $config['class']($config['arguments']);
-
- $config['arguments']['user'] = $user;
-
- return $config;
- }
-
- /**
- * @param IUser $user
- * @return array|null
- */
- private function getMultiBucketObjectStoreConfig(IUser $user) {
- $config = $this->config->getSystemValue('objectstore_multibucket');
- if (!is_array($config)) {
- return null;
- }
-
- // sanity checks
- if (empty($config['class'])) {
- \OC::$server->get(LoggerInterface::class)->error('No class given for objectstore', ['app' => 'files']);
- }
- if (!isset($config['arguments'])) {
- $config['arguments'] = [];
- }
-
- $bucket = $this->config->getUserValue($user->getUID(), 'homeobjectstore', 'bucket', null);
-
- if ($bucket === null) {
- /*
- * Use any provided bucket argument as prefix
- * and add the mapping from username => bucket
- */
- if (!isset($config['arguments']['bucket'])) {
- $config['arguments']['bucket'] = '';
- }
- $mapper = new \OC\Files\ObjectStore\Mapper($user, $this->config);
- $numBuckets = $config['arguments']['num_buckets'] ?? 64;
- $config['arguments']['bucket'] .= $mapper->getBucket($numBuckets);
-
- $this->config->setUserValue($user->getUID(), 'homeobjectstore', 'bucket', $config['arguments']['bucket']);
- } else {
- $config['arguments']['bucket'] = $bucket;
- }
-
- // instantiate object store implementation
- $config['arguments']['objectstore'] = new $config['class']($config['arguments']);
-
- $config['arguments']['user'] = $user;
-
- return $config;
+ return new HomeMountPoint($user, HomeObjectStoreStorage::class, '/' . $user->getUID(), $arguments, $loader, null, null, self::class);
}
}
diff --git a/lib/private/Files/Mount/RootMountProvider.php b/lib/private/Files/Mount/RootMountProvider.php
index 86f8188978f..5e0c924ad38 100644
--- a/lib/private/Files/Mount/RootMountProvider.php
+++ b/lib/private/Files/Mount/RootMountProvider.php
@@ -10,79 +10,41 @@ namespace OC\Files\Mount;
use OC;
use OC\Files\ObjectStore\ObjectStoreStorage;
+use OC\Files\ObjectStore\PrimaryObjectStoreConfig;
use OC\Files\Storage\LocalRootStorage;
-use OC_App;
use OCP\Files\Config\IRootMountProvider;
use OCP\Files\Storage\IStorageFactory;
use OCP\IConfig;
-use Psr\Log\LoggerInterface;
class RootMountProvider implements IRootMountProvider {
+ private PrimaryObjectStoreConfig $objectStoreConfig;
private IConfig $config;
- private LoggerInterface $logger;
- public function __construct(IConfig $config, LoggerInterface $logger) {
+ public function __construct(PrimaryObjectStoreConfig $objectStoreConfig, IConfig $config) {
+ $this->objectStoreConfig = $objectStoreConfig;
$this->config = $config;
- $this->logger = $logger;
}
public function getRootMounts(IStorageFactory $loader): array {
- $objectStore = $this->config->getSystemValue('objectstore', null);
- $objectStoreMultiBucket = $this->config->getSystemValue('objectstore_multibucket', null);
+ $objectStoreConfig = $this->objectStoreConfig->getObjectStoreConfigForRoot();
- if ($objectStoreMultiBucket) {
- return [$this->getMultiBucketStoreRootMount($loader, $objectStoreMultiBucket)];
- } elseif ($objectStore) {
- return [$this->getObjectStoreRootMount($loader, $objectStore)];
+ if ($objectStoreConfig) {
+ return [$this->getObjectStoreRootMount($loader, $objectStoreConfig)];
} else {
return [$this->getLocalRootMount($loader)];
}
}
- private function validateObjectStoreConfig(array &$config) {
- if (empty($config['class'])) {
- $this->logger->error('No class given for objectstore', ['app' => 'files']);
- }
- if (!isset($config['arguments'])) {
- $config['arguments'] = [];
- }
-
- // instantiate object store implementation
- $name = $config['class'];
- if (str_starts_with($name, 'OCA\\') && substr_count($name, '\\') >= 2) {
- $segments = explode('\\', $name);
- OC_App::loadApp(strtolower($segments[1]));
- }
- }
-
private function getLocalRootMount(IStorageFactory $loader): MountPoint {
$configDataDirectory = $this->config->getSystemValue('datadirectory', OC::$SERVERROOT . '/data');
return new MountPoint(LocalRootStorage::class, '/', ['datadir' => $configDataDirectory], $loader, null, null, self::class);
}
- private function getObjectStoreRootMount(IStorageFactory $loader, array $config): MountPoint {
- $this->validateObjectStoreConfig($config);
-
- $config['arguments']['objectstore'] = new $config['class']($config['arguments']);
- // mount with plain / root object store implementation
- $config['class'] = ObjectStoreStorage::class;
-
- return new MountPoint($config['class'], '/', $config['arguments'], $loader, null, null, self::class);
- }
-
- private function getMultiBucketStoreRootMount(IStorageFactory $loader, array $config): MountPoint {
- $this->validateObjectStoreConfig($config);
-
- if (!isset($config['arguments']['bucket'])) {
- $config['arguments']['bucket'] = '';
- }
- // put the root FS always in first bucket for multibucket configuration
- $config['arguments']['bucket'] .= '0';
-
- $config['arguments']['objectstore'] = new $config['class']($config['arguments']);
- // mount with plain / root object store implementation
- $config['class'] = ObjectStoreStorage::class;
+ private function getObjectStoreRootMount(IStorageFactory $loader, array $objectStoreConfig): MountPoint {
+ $arguments = array_merge($objectStoreConfig['arguments'], [
+ 'objectstore' => $this->objectStoreConfig->buildObjectStore($objectStoreConfig),
+ ]);
- return new MountPoint($config['class'], '/', $config['arguments'], $loader, null, null, self::class);
+ return new MountPoint(ObjectStoreStorage::class, '/', $arguments, $loader, null, null, self::class);
}
}
diff --git a/lib/private/Files/Node/Folder.php b/lib/private/Files/Node/Folder.php
index a894c69649a..c41838fd6b0 100644
--- a/lib/private/Files/Node/Folder.php
+++ b/lib/private/Files/Node/Folder.php
@@ -126,8 +126,21 @@ class Folder extends Node implements \OCP\Files\Folder {
$fullPath = $this->getFullPath($path);
$nonExisting = new NonExistingFolder($this->root, $this->view, $fullPath);
$this->sendHooks(['preWrite', 'preCreate'], [$nonExisting]);
- if (!$this->view->mkdir($fullPath) && !$this->view->is_dir($fullPath)) {
- throw new NotPermittedException('Could not create folder "' . $fullPath . '"');
+ if (!$this->view->mkdir($fullPath)) {
+ // maybe another concurrent process created the folder already
+ if (!$this->view->is_dir($fullPath)) {
+ throw new NotPermittedException('Could not create folder "' . $fullPath . '"');
+ } else {
+ // we need to ensure we don't return before the concurrent request has finished updating the cache
+ $tries = 5;
+ while (!$this->view->getFileInfo($fullPath)) {
+ if ($tries < 1) {
+ throw new NotPermittedException('Could not create folder "' . $fullPath . '", folder exists but unable to get cache entry');
+ }
+ usleep(5 * 1000);
+ $tries--;
+ }
+ }
}
$parent = dirname($fullPath) === $this->getPath() ? $this : null;
$node = new Folder($this->root, $this->view, $fullPath, null, $parent);
@@ -447,4 +460,12 @@ class Folder extends Node implements \OCP\Files\Folder {
return $this->search($query);
}
+
+ public function verifyPath($fileName, $readonly = false): void {
+ $this->view->verifyPath(
+ $this->getPath(),
+ $fileName,
+ $readonly,
+ );
+ }
}
diff --git a/lib/private/Files/Node/LazyFolder.php b/lib/private/Files/Node/LazyFolder.php
index 5879748d951..37b1efa0fad 100644
--- a/lib/private/Files/Node/LazyFolder.php
+++ b/lib/private/Files/Node/LazyFolder.php
@@ -561,4 +561,8 @@ class LazyFolder implements Folder {
public function getMetadata(): array {
return $this->data['metadata'] ?? $this->__call(__FUNCTION__, func_get_args());
}
+
+ public function verifyPath($fileName, $readonly = false): void {
+ $this->__call(__FUNCTION__, func_get_args());
+ }
}
diff --git a/lib/private/Files/ObjectStore/ObjectStoreStorage.php b/lib/private/Files/ObjectStore/ObjectStoreStorage.php
index 16ef4e7de63..752c3cf4fb7 100644
--- a/lib/private/Files/ObjectStore/ObjectStoreStorage.php
+++ b/lib/private/Files/ObjectStore/ObjectStoreStorage.php
@@ -22,6 +22,7 @@ use OCP\Files\FileInfo;
use OCP\Files\GenericFileException;
use OCP\Files\NotFoundException;
use OCP\Files\ObjectStore\IObjectStore;
+use OCP\Files\ObjectStore\IObjectStoreMetaData;
use OCP\Files\ObjectStore\IObjectStoreMultiPartUpload;
use OCP\Files\Storage\IChunkedFileWrite;
use OCP\Files\Storage\IStorage;
@@ -66,7 +67,7 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common implements IChunkedFil
$this->logger = \OCP\Server::get(LoggerInterface::class);
}
- public function mkdir(string $path, bool $force = false): bool {
+ public function mkdir(string $path, bool $force = false, array $metadata = []): bool {
$path = $this->normalizePath($path);
if (!$force && $this->file_exists($path)) {
$this->logger->warning("Tried to create an object store folder that already exists: $path");
@@ -76,7 +77,7 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common implements IChunkedFil
$mTime = time();
$data = [
'mimetype' => 'httpd/unix-directory',
- 'size' => 0,
+ 'size' => $metadata['size'] ?? 0,
'mtime' => $mTime,
'storage_mtime' => $mTime,
'permissions' => \OCP\Constants::PERMISSION_ALL,
@@ -412,16 +413,6 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common implements IChunkedFil
//create a empty file, need to have at least on char to make it
// work with all object storage implementations
$this->file_put_contents($path, ' ');
- $mimeType = \OC::$server->getMimeTypeDetector()->detectPath($path);
- $stat = [
- 'etag' => $this->getETag($path),
- 'mimetype' => $mimeType,
- 'size' => 0,
- 'mtime' => $mtime,
- 'storage_mtime' => $mtime,
- 'permissions' => \OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_CREATE,
- ];
- $this->getCache()->put($path, $stat);
} catch (\Exception $ex) {
$this->logger->error(
'Could not create object for ' . $path,
@@ -479,6 +470,11 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common implements IChunkedFil
$mimetypeDetector = \OC::$server->getMimeTypeDetector();
$mimetype = $mimetypeDetector->detectPath($path);
+ $metadata = [
+ 'mimetype' => $mimetype,
+ 'original-storage' => $this->getId(),
+ 'original-path' => $path,
+ ];
$stat['mimetype'] = $mimetype;
$stat['etag'] = $this->getETag($path);
@@ -507,13 +503,21 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common implements IChunkedFil
]);
$size = $writtenSize;
});
- $this->objectStore->writeObject($urn, $countStream, $mimetype);
+ if ($this->objectStore instanceof IObjectStoreMetaData) {
+ $this->objectStore->writeObjectWithMetaData($urn, $countStream, $metadata);
+ } else {
+ $this->objectStore->writeObject($urn, $countStream, $metadata['mimetype']);
+ }
if (is_resource($countStream)) {
fclose($countStream);
}
$stat['size'] = $size;
} else {
- $this->objectStore->writeObject($urn, $stream, $mimetype);
+ if ($this->objectStore instanceof IObjectStoreMetaData) {
+ $this->objectStore->writeObjectWithMetaData($urn, $stream, $metadata);
+ } else {
+ $this->objectStore->writeObject($urn, $stream, $metadata['mimetype']);
+ }
if (is_resource($stream)) {
fclose($stream);
}
@@ -695,7 +699,7 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common implements IChunkedFil
if ($cache->inCache($to)) {
$cache->remove($to);
}
- $this->mkdir($to);
+ $this->mkdir($to, false, ['size' => $sourceEntry->getSize()]);
foreach ($sourceCache->getFolderContentsById($sourceEntry->getId()) as $child) {
$this->copyInner($sourceCache, $child, $to . '/' . $child->getName());
diff --git a/lib/private/Files/ObjectStore/PrimaryObjectStoreConfig.php b/lib/private/Files/ObjectStore/PrimaryObjectStoreConfig.php
new file mode 100644
index 00000000000..fdfe989addc
--- /dev/null
+++ b/lib/private/Files/ObjectStore/PrimaryObjectStoreConfig.php
@@ -0,0 +1,140 @@
+<?php
+
+declare(strict_types=1);
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+namespace OC\Files\ObjectStore;
+
+use OCP\App\IAppManager;
+use OCP\Files\ObjectStore\IObjectStore;
+use OCP\IConfig;
+use OCP\IUser;
+
+/**
+ * @psalm-type ObjectStoreConfig array{class: class-string<IObjectStore>, arguments: array{multibucket: bool, ...}}
+ */
+class PrimaryObjectStoreConfig {
+ public function __construct(
+ private readonly IConfig $config,
+ private readonly IAppManager $appManager,
+ ) {
+ }
+
+ /**
+ * @param ObjectStoreConfig $config
+ */
+ public function buildObjectStore(array $config): IObjectStore {
+ return new $config['class']($config['arguments']);
+ }
+
+ /**
+ * @return ?ObjectStoreConfig
+ */
+ public function getObjectStoreConfigForRoot(): ?array {
+ $config = $this->getObjectStoreConfig();
+
+ if ($config && $config['arguments']['multibucket']) {
+ if (!isset($config['arguments']['bucket'])) {
+ $config['arguments']['bucket'] = '';
+ }
+
+ // put the root FS always in first bucket for multibucket configuration
+ $config['arguments']['bucket'] .= '0';
+ }
+ return $config;
+ }
+
+ /**
+ * @return ?ObjectStoreConfig
+ */
+ public function getObjectStoreConfigForUser(IUser $user): ?array {
+ $config = $this->getObjectStoreConfig();
+
+ if ($config && $config['arguments']['multibucket']) {
+ $config['arguments']['bucket'] = $this->getBucketForUser($user, $config);
+ }
+ return $config;
+ }
+
+ /**
+ * @return ?ObjectStoreConfig
+ */
+ private function getObjectStoreConfig(): ?array {
+ $objectStore = $this->config->getSystemValue('objectstore', null);
+ $objectStoreMultiBucket = $this->config->getSystemValue('objectstore_multibucket', null);
+
+ // new-style multibucket config uses the same 'objectstore' key but sets `'multibucket' => true`, transparently upgrade older style config
+ if ($objectStoreMultiBucket) {
+ $objectStoreMultiBucket['arguments']['multibucket'] = true;
+ return $this->validateObjectStoreConfig($objectStoreMultiBucket);
+ } elseif ($objectStore) {
+ return $this->validateObjectStoreConfig($objectStore);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * @return ObjectStoreConfig
+ */
+ private function validateObjectStoreConfig(array $config) {
+ if (!isset($config['class'])) {
+ throw new \Exception('No class configured for object store');
+ }
+ if (!isset($config['arguments'])) {
+ $config['arguments'] = [];
+ }
+ $class = $config['class'];
+ $arguments = $config['arguments'];
+ if (!is_array($arguments)) {
+ throw new \Exception('Configured object store arguments are not an array');
+ }
+ if (!isset($arguments['multibucket'])) {
+ $arguments['multibucket'] = false;
+ }
+ if (!is_bool($arguments['multibucket'])) {
+ throw new \Exception('arguments.multibucket must be a boolean in object store configuration');
+ }
+
+ if (!is_string($class)) {
+ throw new \Exception('Configured class for object store is not a string');
+ }
+
+ if (str_starts_with($class, 'OCA\\') && substr_count($class, '\\') >= 2) {
+ [$appId] = explode('\\', $class);
+ $this->appManager->loadApp(strtolower($appId));
+ }
+
+ if (!is_a($class, IObjectStore::class, true)) {
+ throw new \Exception('Configured class for object store is not an object store');
+ }
+ return [
+ 'class' => $class,
+ 'arguments' => $arguments,
+ ];
+ }
+
+ private function getBucketForUser(IUser $user, array $config): string {
+ $bucket = $this->config->getUserValue($user->getUID(), 'homeobjectstore', 'bucket', null);
+
+ if ($bucket === null) {
+ /*
+ * Use any provided bucket argument as prefix
+ * and add the mapping from username => bucket
+ */
+ if (!isset($config['arguments']['bucket'])) {
+ $config['arguments']['bucket'] = '';
+ }
+ $mapper = new Mapper($user, $this->config);
+ $numBuckets = isset($config['arguments']['num_buckets']) ? $config['arguments']['num_buckets'] : 64;
+ $bucket = $config['arguments']['bucket'] . $mapper->getBucket($numBuckets);
+
+ $this->config->setUserValue($user->getUID(), 'homeobjectstore', 'bucket', $bucket);
+ }
+
+ return $bucket;
+ }
+}
diff --git a/lib/private/Files/ObjectStore/S3.php b/lib/private/Files/ObjectStore/S3.php
index e970fb6ac14..23c061db174 100644
--- a/lib/private/Files/ObjectStore/S3.php
+++ b/lib/private/Files/ObjectStore/S3.php
@@ -95,6 +95,16 @@ class S3 implements IObjectStore, IObjectStoreMultiPartUpload, IObjectStoreMetaD
]);
}
+ private function parseS3Metadata(array $metadata): array {
+ $result = [];
+ foreach ($metadata as $key => $value) {
+ if (str_starts_with($key, 'x-amz-meta-')) {
+ $result[substr($key, strlen('x-amz-meta-'))] = $value;
+ }
+ }
+ return $result;
+ }
+
public function getObjectMetaData(string $urn): array {
$object = $this->getConnection()->headObject([
'Bucket' => $this->bucket,
@@ -104,7 +114,7 @@ class S3 implements IObjectStore, IObjectStoreMultiPartUpload, IObjectStoreMetaD
'mtime' => $object['LastModified'],
'etag' => trim($object['ETag'], '"'),
'size' => (int)($object['Size'] ?? $object['ContentLength']),
- ];
+ ] + $this->parseS3Metadata($object['Metadata'] ?? []);
}
public function listObjects(string $prefix = ''): \Iterator {
diff --git a/lib/private/Files/ObjectStore/S3ConfigTrait.php b/lib/private/Files/ObjectStore/S3ConfigTrait.php
index 63f14ac2d00..5b086db8f77 100644
--- a/lib/private/Files/ObjectStore/S3ConfigTrait.php
+++ b/lib/private/Files/ObjectStore/S3ConfigTrait.php
@@ -18,6 +18,10 @@ trait S3ConfigTrait {
/** Maximum number of concurrent multipart uploads */
protected int $concurrency;
+ /** Timeout, in seconds, for the connection to S3 server, not for the
+ * request. */
+ protected float $connectTimeout;
+
protected int $timeout;
protected string|false $proxy;
diff --git a/lib/private/Files/ObjectStore/S3ConnectionTrait.php b/lib/private/Files/ObjectStore/S3ConnectionTrait.php
index b7017583dc2..062d2e4bde4 100644
--- a/lib/private/Files/ObjectStore/S3ConnectionTrait.php
+++ b/lib/private/Files/ObjectStore/S3ConnectionTrait.php
@@ -39,6 +39,7 @@ trait S3ConnectionTrait {
// Default to 5 like the S3 SDK does
$this->concurrency = $params['concurrency'] ?? 5;
$this->proxy = $params['proxy'] ?? false;
+ $this->connectTimeout = $params['connect_timeout'] ?? 5;
$this->timeout = $params['timeout'] ?? 15;
$this->storageClass = !empty($params['storageClass']) ? $params['storageClass'] : 'STANDARD';
$this->uploadPartSize = $params['uploadPartSize'] ?? 524288000;
@@ -102,8 +103,7 @@ trait S3ConnectionTrait {
'use_arn_region' => false,
'http' => [
'verify' => $this->getCertificateBundlePath(),
- // Timeout for the connection to S3 server, not for the request.
- 'connect_timeout' => 5
+ 'connect_timeout' => $this->connectTimeout,
],
'use_aws_shared_config_files' => false,
'retries' => [
diff --git a/lib/private/Files/ObjectStore/S3ObjectTrait.php b/lib/private/Files/ObjectStore/S3ObjectTrait.php
index 9d7cfa644e6..5e6dcf88a42 100644
--- a/lib/private/Files/ObjectStore/S3ObjectTrait.php
+++ b/lib/private/Files/ObjectStore/S3ObjectTrait.php
@@ -77,22 +77,32 @@ trait S3ObjectTrait {
return $fh;
}
+ private function buildS3Metadata(array $metadata): array {
+ $result = [];
+ foreach ($metadata as $key => $value) {
+ $result['x-amz-meta-' . $key] = $value;
+ }
+ return $result;
+ }
/**
* Single object put helper
*
* @param string $urn the unified resource name used to identify the object
* @param StreamInterface $stream stream with the data to write
- * @param string|null $mimetype the mimetype to set for the remove object @since 22.0.0
+ * @param array $metaData the metadata to set for the object
* @throws \Exception when something goes wrong, message will be logged
*/
- protected function writeSingle(string $urn, StreamInterface $stream, ?string $mimetype = null): void {
+ protected function writeSingle(string $urn, StreamInterface $stream, array $metaData): void {
+ $mimetype = $metaData['mimetype'] ?? null;
+ unset($metaData['mimetype']);
$this->getConnection()->putObject([
'Bucket' => $this->bucket,
'Key' => $urn,
'Body' => $stream,
'ACL' => 'private',
'ContentType' => $mimetype,
+ 'Metadata' => $this->buildS3Metadata($metaData),
'StorageClass' => $this->storageClass,
] + $this->getSSECParameters());
}
@@ -103,43 +113,72 @@ trait S3ObjectTrait {
*
* @param string $urn the unified resource name used to identify the object
* @param StreamInterface $stream stream with the data to write
- * @param string|null $mimetype the mimetype to set for the remove object
+ * @param array $metaData the metadata to set for the object
* @throws \Exception when something goes wrong, message will be logged
*/
- protected function writeMultiPart(string $urn, StreamInterface $stream, ?string $mimetype = null): void {
- $uploader = new MultipartUploader($this->getConnection(), $stream, [
- 'bucket' => $this->bucket,
- 'concurrency' => $this->concurrency,
- 'key' => $urn,
- 'part_size' => $this->uploadPartSize,
- 'params' => [
- 'ContentType' => $mimetype,
- 'StorageClass' => $this->storageClass,
- ] + $this->getSSECParameters(),
- ]);
+ protected function writeMultiPart(string $urn, StreamInterface $stream, array $metaData): void {
+ $mimetype = $metaData['mimetype'] ?? null;
+ unset($metaData['mimetype']);
+
+ $attempts = 0;
+ $uploaded = false;
+ $concurrency = $this->concurrency;
+ $exception = null;
+ $state = null;
+
+ // retry multipart upload once with concurrency at half on failure
+ while (!$uploaded && $attempts <= 1) {
+ $uploader = new MultipartUploader($this->getConnection(), $stream, [
+ 'bucket' => $this->bucket,
+ 'concurrency' => $concurrency,
+ 'key' => $urn,
+ 'part_size' => $this->uploadPartSize,
+ 'state' => $state,
+ 'params' => [
+ 'ContentType' => $mimetype,
+ 'Metadata' => $this->buildS3Metadata($metaData),
+ 'StorageClass' => $this->storageClass,
+ ] + $this->getSSECParameters(),
+ ]);
+
+ try {
+ $uploader->upload();
+ $uploaded = true;
+ } catch (S3MultipartUploadException $e) {
+ $exception = $e;
+ $attempts++;
+
+ if ($concurrency > 1) {
+ $concurrency = round($concurrency / 2);
+ }
- try {
- $uploader->upload();
- } catch (S3MultipartUploadException $e) {
+ if ($stream->isSeekable()) {
+ $stream->rewind();
+ }
+ }
+ }
+
+ if (!$uploaded) {
// if anything goes wrong with multipart, make sure that you don´t poison and
// slow down s3 bucket with orphaned fragments
- $uploadInfo = $e->getState()->getId();
- if ($e->getState()->isInitiated() && (array_key_exists('UploadId', $uploadInfo))) {
+ $uploadInfo = $exception->getState()->getId();
+ if ($exception->getState()->isInitiated() && (array_key_exists('UploadId', $uploadInfo))) {
$this->getConnection()->abortMultipartUpload($uploadInfo);
}
- throw new \OCA\DAV\Connector\Sabre\Exception\BadGateway('Error while uploading to S3 bucket', 0, $e);
+
+ throw new \OCA\DAV\Connector\Sabre\Exception\BadGateway('Error while uploading to S3 bucket', 0, $exception);
}
}
-
- /**
- * @param string $urn the unified resource name used to identify the object
- * @param resource $stream stream with the data to write
- * @param string|null $mimetype the mimetype to set for the remove object @since 22.0.0
- * @throws \Exception when something goes wrong, message will be logged
- * @since 7.0.0
- */
public function writeObject($urn, $stream, ?string $mimetype = null) {
+ $metaData = [];
+ if ($mimetype) {
+ $metaData['mimetype'] = $mimetype;
+ }
+ $this->writeObjectWithMetaData($urn, $stream, $metaData);
+ }
+
+ public function writeObjectWithMetaData(string $urn, $stream, array $metaData): void {
$canSeek = fseek($stream, 0, SEEK_CUR) === 0;
$psrStream = Utils::streamFor($stream);
@@ -154,16 +193,16 @@ trait S3ObjectTrait {
$buffer->seek(0);
if ($buffer->getSize() < $this->putSizeLimit) {
// buffer is fully seekable, so use it directly for the small upload
- $this->writeSingle($urn, $buffer, $mimetype);
+ $this->writeSingle($urn, $buffer, $metaData);
} else {
$loadStream = new Psr7\AppendStream([$buffer, $psrStream]);
- $this->writeMultiPart($urn, $loadStream, $mimetype);
+ $this->writeMultiPart($urn, $loadStream, $metaData);
}
} else {
if ($size < $this->putSizeLimit) {
- $this->writeSingle($urn, $psrStream, $mimetype);
+ $this->writeSingle($urn, $psrStream, $metaData);
} else {
- $this->writeMultiPart($urn, $psrStream, $mimetype);
+ $this->writeMultiPart($urn, $psrStream, $metaData);
}
}
$psrStream->close();
diff --git a/lib/private/Files/Search/QueryOptimizer/OrEqualsToIn.php b/lib/private/Files/Search/QueryOptimizer/OrEqualsToIn.php
index 3f2b36823ab..42d960cc22a 100644
--- a/lib/private/Files/Search/QueryOptimizer/OrEqualsToIn.php
+++ b/lib/private/Files/Search/QueryOptimizer/OrEqualsToIn.php
@@ -32,7 +32,7 @@ class OrEqualsToIn extends ReplacingOptimizerStep {
$value = $comparison->getValue();
return $value;
}, $group);
- $in = new SearchComparison(ISearchComparison::COMPARE_IN, $field, $values);
+ $in = new SearchComparison(ISearchComparison::COMPARE_IN, $field, $values, $group[0]->getExtra());
$pathEqHash = array_reduce($group, function ($pathEqHash, ISearchComparison $comparison) {
return $comparison->getQueryHint(ISearchComparison::HINT_PATH_EQ_HASH, true) && $pathEqHash;
}, true);
diff --git a/lib/private/Files/Search/QueryOptimizer/SplitLargeIn.php b/lib/private/Files/Search/QueryOptimizer/SplitLargeIn.php
index 5c7655b49c1..3e5258a715f 100644
--- a/lib/private/Files/Search/QueryOptimizer/SplitLargeIn.php
+++ b/lib/private/Files/Search/QueryOptimizer/SplitLargeIn.php
@@ -24,7 +24,7 @@ class SplitLargeIn extends ReplacingOptimizerStep {
) {
$chunks = array_chunk($operator->getValue(), 1000);
$chunkComparisons = array_map(function (array $values) use ($operator) {
- return new SearchComparison(ISearchComparison::COMPARE_IN, $operator->getField(), $values);
+ return new SearchComparison(ISearchComparison::COMPARE_IN, $operator->getField(), $values, $operator->getExtra());
}, $chunks);
$operator = new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, $chunkComparisons);
diff --git a/lib/private/Files/SetupManager.php b/lib/private/Files/SetupManager.php
index 2b8121a529d..4ab40b01f4a 100644
--- a/lib/private/Files/SetupManager.php
+++ b/lib/private/Files/SetupManager.php
@@ -23,7 +23,6 @@ use OC\Share\Share;
use OC\Share20\ShareDisableChecker;
use OC_App;
use OC_Hook;
-use OC_Util;
use OCA\Files_External\Config\ExternalMountPoint;
use OCA\Files_Sharing\External\Mount;
use OCA\Files_Sharing\ISharedMountPoint;
@@ -34,6 +33,7 @@ use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\Config\ICachedMountInfo;
use OCP\Files\Config\IHomeMountProvider;
use OCP\Files\Config\IMountProvider;
+use OCP\Files\Config\IRootMountProvider;
use OCP\Files\Config\IUserMountCache;
use OCP\Files\Events\BeforeFileSystemSetupEvent;
use OCP\Files\Events\InvalidateMountCacheEvent;
@@ -156,7 +156,7 @@ class SetupManager {
if ($mount instanceof HomeMountPoint) {
$user = $mount->getUser();
return new Quota(['storage' => $storage, 'quotaCallback' => function () use ($user) {
- return OC_Util::getUserQuota($user);
+ return $user->getQuotaBytes();
}, 'root' => 'files', 'include_external_storage' => $quotaIncludeExternal]);
}
@@ -280,9 +280,13 @@ class SetupManager {
$mounts = array_filter($mounts, function (IMountPoint $mount) use ($userRoot) {
return str_starts_with($mount->getMountPoint(), $userRoot);
});
- $allProviders = array_map(function (IMountProvider $provider) {
+ $allProviders = array_map(function (IMountProvider|IHomeMountProvider|IRootMountProvider $provider) {
return get_class($provider);
- }, $this->mountProviderCollection->getProviders());
+ }, array_merge(
+ $this->mountProviderCollection->getProviders(),
+ $this->mountProviderCollection->getHomeProviders(),
+ $this->mountProviderCollection->getRootProviders(),
+ ));
$newProviders = array_diff($allProviders, $previouslySetupProviders);
$mounts = array_filter($mounts, function (IMountPoint $mount) use ($previouslySetupProviders) {
return !in_array($mount->getMountProvider(), $previouslySetupProviders);
diff --git a/lib/private/Files/SimpleFS/SimpleFile.php b/lib/private/Files/SimpleFS/SimpleFile.php
index cbb3af4db29..0bfaea21788 100644
--- a/lib/private/Files/SimpleFS/SimpleFile.php
+++ b/lib/private/Files/SimpleFS/SimpleFile.php
@@ -6,9 +6,11 @@
namespace OC\Files\SimpleFS;
use OCP\Files\File;
+use OCP\Files\GenericFileException;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
use OCP\Files\SimpleFS\ISimpleFile;
+use OCP\Lock\LockedException;
class SimpleFile implements ISimpleFile {
private File $file;
@@ -48,8 +50,10 @@ class SimpleFile implements ISimpleFile {
/**
* Get the content
*
- * @throws NotPermittedException
+ * @throws GenericFileException
+ * @throws LockedException
* @throws NotFoundException
+ * @throws NotPermittedException
*/
public function getContent(): string {
$result = $this->file->getContent();
@@ -65,8 +69,10 @@ class SimpleFile implements ISimpleFile {
* Overwrite the file
*
* @param string|resource $data
- * @throws NotPermittedException
+ * @throws GenericFileException
+ * @throws LockedException
* @throws NotFoundException
+ * @throws NotPermittedException
*/
public function putContent($data): void {
try {
diff --git a/lib/private/Files/Storage/Common.php b/lib/private/Files/Storage/Common.php
index ca0e38774c8..b1e02cf2e6c 100644
--- a/lib/private/Files/Storage/Common.php
+++ b/lib/private/Files/Storage/Common.php
@@ -19,6 +19,7 @@ use OC\Files\ObjectStore\ObjectStoreStorage;
use OC\Files\Storage\Wrapper\Encryption;
use OC\Files\Storage\Wrapper\Jail;
use OC\Files\Storage\Wrapper\Wrapper;
+use OCP\Files;
use OCP\Files\Cache\ICache;
use OCP\Files\Cache\IPropagator;
use OCP\Files\Cache\IScanner;
@@ -205,7 +206,7 @@ abstract class Common implements Storage, ILockingStorage, IWriteStreamStorage,
} else {
$sourceStream = $this->fopen($source, 'r');
$targetStream = $this->fopen($target, 'w');
- [, $result] = \OC_Helper::streamCopy($sourceStream, $targetStream);
+ [, $result] = Files::streamCopy($sourceStream, $targetStream, true);
if (!$result) {
Server::get(LoggerInterface::class)->warning("Failed to write data while copying $source to $target");
}
@@ -734,7 +735,7 @@ abstract class Common implements Storage, ILockingStorage, IWriteStreamStorage,
throw new GenericFileException("Failed to open $path for writing");
}
try {
- [$count, $result] = \OC_Helper::streamCopy($stream, $target);
+ [$count, $result] = Files::streamCopy($stream, $target, true);
if (!$result) {
throw new GenericFileException('Failed to copy stream');
}
diff --git a/lib/private/Files/Storage/DAV.php b/lib/private/Files/Storage/DAV.php
index 10670d6331a..afd8f87e2de 100644
--- a/lib/private/Files/Storage/DAV.php
+++ b/lib/private/Files/Storage/DAV.php
@@ -350,7 +350,13 @@ class DAV extends Common {
}
}
- return $response->getBody();
+ $content = $response->getBody();
+
+ if ($content === null || is_string($content)) {
+ return false;
+ }
+
+ return $content;
case 'w':
case 'wb':
case 'a':
@@ -390,6 +396,8 @@ class DAV extends Common {
$this->writeBack($tmpFile, $path);
});
}
+
+ return false;
}
public function writeBack(string $tmpFile, string $path): void {
diff --git a/lib/private/Files/Storage/LocalTempFileTrait.php b/lib/private/Files/Storage/LocalTempFileTrait.php
index c8e3588f2e8..fffc3e789f3 100644
--- a/lib/private/Files/Storage/LocalTempFileTrait.php
+++ b/lib/private/Files/Storage/LocalTempFileTrait.php
@@ -7,6 +7,8 @@
*/
namespace OC\Files\Storage;
+use OCP\Files;
+
/**
* Storage backend class for providing common filesystem operation methods
* which are not storage-backend specific.
@@ -45,7 +47,7 @@ trait LocalTempFileTrait {
}
$tmpFile = \OC::$server->getTempManager()->getTemporaryFile($extension);
$target = fopen($tmpFile, 'w');
- \OC_Helper::streamCopy($source, $target);
+ Files::streamCopy($source, $target);
fclose($target);
return $tmpFile;
}
diff --git a/lib/private/Files/Storage/Temporary.php b/lib/private/Files/Storage/Temporary.php
index ff7a816930d..ecf8a1315a9 100644
--- a/lib/private/Files/Storage/Temporary.php
+++ b/lib/private/Files/Storage/Temporary.php
@@ -7,16 +7,20 @@
*/
namespace OC\Files\Storage;
+use OCP\Files;
+use OCP\ITempManager;
+use OCP\Server;
+
/**
* local storage backend in temporary folder for testing purpose
*/
class Temporary extends Local {
public function __construct(array $parameters = []) {
- parent::__construct(['datadir' => \OC::$server->getTempManager()->getTemporaryFolder()]);
+ parent::__construct(['datadir' => Server::get(ITempManager::class)->getTemporaryFolder()]);
}
public function cleanUp(): void {
- \OC_Helper::rmdirr($this->datadir);
+ Files::rmdirr($this->datadir);
}
public function __destruct() {
diff --git a/lib/private/Files/Storage/Wrapper/Encryption.php b/lib/private/Files/Storage/Wrapper/Encryption.php
index ba23f3c43ec..4d38d2d37aa 100644
--- a/lib/private/Files/Storage/Wrapper/Encryption.php
+++ b/lib/private/Files/Storage/Wrapper/Encryption.php
@@ -8,7 +8,6 @@
namespace OC\Files\Storage\Wrapper;
use OC\Encryption\Exceptions\ModuleDoesNotExistsException;
-use OC\Encryption\Update;
use OC\Encryption\Util;
use OC\Files\Cache\CacheEntry;
use OC\Files\Filesystem;
@@ -18,9 +17,11 @@ use OC\Files\Storage\Common;
use OC\Files\Storage\LocalTempFileTrait;
use OC\Memcache\ArrayCache;
use OCP\Cache\CappedMemoryCache;
+use OCP\Encryption\Exceptions\InvalidHeaderException;
use OCP\Encryption\IFile;
use OCP\Encryption\IManager;
use OCP\Encryption\Keys\IStorage;
+use OCP\Files;
use OCP\Files\Cache\ICacheEntry;
use OCP\Files\Mount\IMountPoint;
use OCP\Files\Storage;
@@ -49,7 +50,6 @@ class Encryption extends Wrapper {
private IFile $fileHelper,
private ?string $uid,
private IStorage $keyStorage,
- private Update $update,
private Manager $mountManager,
private ArrayCache $arrayCache,
) {
@@ -64,7 +64,8 @@ class Encryption extends Wrapper {
$info = $this->getCache()->get($path);
if ($info === false) {
- return false;
+ /* Pass call to wrapped storage, it may be a special file like a part file */
+ return $this->storage->filesize($path);
}
if (isset($this->unencryptedSize[$fullPath])) {
$size = $this->unencryptedSize[$fullPath];
@@ -318,7 +319,7 @@ class Encryption extends Wrapper {
if (!empty($encryptionModuleId)) {
$encryptionModule = $this->encryptionManager->getEncryptionModule($encryptionModuleId);
$shouldEncrypt = true;
- } elseif (empty($encryptionModuleId) && $info['encrypted'] === true) {
+ } elseif ($info !== false && $info['encrypted'] === true) {
// we come from a old installation. No header and/or no module defined
// but the file is encrypted. In this case we need to use the
// OC_DEFAULT_MODULE to read the file
@@ -344,6 +345,16 @@ class Encryption extends Wrapper {
if ($shouldEncrypt === true && $encryptionModule !== null) {
$this->encryptedPaths->set($this->util->stripPartialFileExtension($path), true);
$headerSize = $this->getHeaderSize($path);
+ if ($mode === 'r' && $headerSize === 0) {
+ $firstBlock = $this->readFirstBlock($path);
+ if (!$firstBlock) {
+ throw new InvalidHeaderException("Unable to get header block for $path");
+ } elseif (!str_starts_with($firstBlock, Util::HEADER_START)) {
+ throw new InvalidHeaderException("Unable to get header size for $path, file doesn't start with encryption header");
+ } else {
+ throw new InvalidHeaderException("Unable to get header size for $path, even though file does start with encryption header");
+ }
+ }
$source = $this->storage->fopen($path, $mode);
if (!is_resource($source)) {
return false;
@@ -526,10 +537,22 @@ class Encryption extends Wrapper {
$result = $this->copyBetweenStorage($sourceStorage, $sourceInternalPath, $targetInternalPath, $preserveMtime, true);
if ($result) {
- if ($sourceStorage->is_dir($sourceInternalPath)) {
- $result = $sourceStorage->rmdir($sourceInternalPath);
- } else {
- $result = $sourceStorage->unlink($sourceInternalPath);
+ $setPreserveCacheOnDelete = $sourceStorage->instanceOfStorage(ObjectStoreStorage::class) && !$this->instanceOfStorage(ObjectStoreStorage::class);
+ if ($setPreserveCacheOnDelete) {
+ /** @var ObjectStoreStorage $sourceStorage */
+ $sourceStorage->setPreserveCacheOnDelete(true);
+ }
+ try {
+ if ($sourceStorage->is_dir($sourceInternalPath)) {
+ $result = $sourceStorage->rmdir($sourceInternalPath);
+ } else {
+ $result = $sourceStorage->unlink($sourceInternalPath);
+ }
+ } finally {
+ if ($setPreserveCacheOnDelete) {
+ /** @var ObjectStoreStorage $sourceStorage */
+ $sourceStorage->setPreserveCacheOnDelete(false);
+ }
}
}
return $result;
@@ -654,7 +677,7 @@ class Encryption extends Wrapper {
if (is_resource($dh)) {
while ($result && ($file = readdir($dh)) !== false) {
if (!Filesystem::isIgnoredDir($file)) {
- $result &= $this->copyFromStorage($sourceStorage, $sourceInternalPath . '/' . $file, $targetInternalPath . '/' . $file, false, $isRename);
+ $result = $this->copyFromStorage($sourceStorage, $sourceInternalPath . '/' . $file, $targetInternalPath . '/' . $file, $preserveMtime, $isRename);
}
}
}
@@ -662,7 +685,7 @@ class Encryption extends Wrapper {
try {
$source = $sourceStorage->fopen($sourceInternalPath, 'r');
$target = $this->fopen($targetInternalPath, 'w');
- [, $result] = \OC_Helper::streamCopy($source, $target);
+ [, $result] = Files::streamCopy($source, $target, true);
} finally {
if (is_resource($source)) {
fclose($source);
@@ -871,7 +894,7 @@ class Encryption extends Wrapper {
public function writeStream(string $path, $stream, ?int $size = null): int {
// always fall back to fopen
$target = $this->fopen($path, 'w');
- [$count, $result] = \OC_Helper::streamCopy($stream, $target);
+ [$count, $result] = Files::streamCopy($stream, $target, true);
fclose($stream);
fclose($target);
@@ -894,4 +917,16 @@ class Encryption extends Wrapper {
public function setEnabled(bool $enabled): void {
$this->enabled = $enabled;
}
+
+ /**
+ * Check if the on-disk data for a file has a valid encrypted header
+ *
+ * @param string $path
+ * @return bool
+ */
+ public function hasValidHeader(string $path): bool {
+ $firstBlock = $this->readFirstBlock($path);
+ $header = $this->util->parseRawHeader($firstBlock);
+ return (count($header) > 0);
+ }
}
diff --git a/lib/private/Files/Storage/Wrapper/Jail.php b/lib/private/Files/Storage/Wrapper/Jail.php
index c8db0e94e59..38b113cef88 100644
--- a/lib/private/Files/Storage/Wrapper/Jail.php
+++ b/lib/private/Files/Storage/Wrapper/Jail.php
@@ -11,6 +11,7 @@ use OC\Files\Cache\Wrapper\CacheJail;
use OC\Files\Cache\Wrapper\JailPropagator;
use OC\Files\Cache\Wrapper\JailWatcher;
use OC\Files\Filesystem;
+use OCP\Files;
use OCP\Files\Cache\ICache;
use OCP\Files\Cache\IPropagator;
use OCP\Files\Cache\IWatcher;
@@ -253,7 +254,7 @@ class Jail extends Wrapper {
return $storage->writeStream($this->getUnjailedPath($path), $stream, $size);
} else {
$target = $this->fopen($path, 'w');
- [$count, $result] = \OC_Helper::streamCopy($stream, $target);
+ $count = Files::streamCopy($stream, $target);
fclose($stream);
fclose($target);
return $count;
diff --git a/lib/private/Files/Storage/Wrapper/Quota.php b/lib/private/Files/Storage/Wrapper/Quota.php
index 3be77ba1b37..35a265f8c8e 100644
--- a/lib/private/Files/Storage/Wrapper/Quota.php
+++ b/lib/private/Files/Storage/Wrapper/Quota.php
@@ -21,6 +21,7 @@ class Quota extends Wrapper {
protected string $sizeRoot;
private SystemConfig $config;
private bool $quotaIncludeExternalStorage;
+ private bool $enabled = true;
/**
* @param array $parameters
@@ -46,6 +47,9 @@ class Quota extends Wrapper {
}
private function hasQuota(): bool {
+ if (!$this->enabled) {
+ return false;
+ }
return $this->getQuota() !== FileInfo::SPACE_UNLIMITED;
}
@@ -197,4 +201,8 @@ class Quota extends Wrapper {
return parent::touch($path, $mtime);
}
+
+ public function enableQuota(bool $enabled): void {
+ $this->enabled = $enabled;
+ }
}
diff --git a/lib/private/Files/Storage/Wrapper/Wrapper.php b/lib/private/Files/Storage/Wrapper/Wrapper.php
index 6dea439fe25..7af11dd5ef7 100644
--- a/lib/private/Files/Storage/Wrapper/Wrapper.php
+++ b/lib/private/Files/Storage/Wrapper/Wrapper.php
@@ -9,6 +9,7 @@ namespace OC\Files\Storage\Wrapper;
use OC\Files\Storage\FailedStorage;
use OC\Files\Storage\Storage;
+use OCP\Files;
use OCP\Files\Cache\ICache;
use OCP\Files\Cache\IPropagator;
use OCP\Files\Cache\IScanner;
@@ -322,7 +323,7 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage, IWriteStrea
return $storage->writeStream($path, $stream, $size);
} else {
$target = $this->fopen($path, 'w');
- [$count, $result] = \OC_Helper::streamCopy($stream, $target);
+ $count = Files::streamCopy($stream, $target);
fclose($stream);
fclose($target);
return $count;
diff --git a/lib/private/Files/Template/TemplateManager.php b/lib/private/Files/Template/TemplateManager.php
index 8032cdf941f..80ef5a14786 100644
--- a/lib/private/Files/Template/TemplateManager.php
+++ b/lib/private/Files/Template/TemplateManager.php
@@ -19,6 +19,7 @@ use OCP\Files\IRootFolder;
use OCP\Files\Node;
use OCP\Files\NotFoundException;
use OCP\Files\Template\BeforeGetTemplatesEvent;
+use OCP\Files\Template\Field;
use OCP\Files\Template\FileCreatedFromTemplateEvent;
use OCP\Files\Template\ICustomTemplateProvider;
use OCP\Files\Template\ITemplateManager;
@@ -125,6 +126,19 @@ class TemplateManager implements ITemplateManager {
}, $this->listCreators()));
}
+ public function listTemplateFields(int $fileId): array {
+ foreach ($this->listCreators() as $creator) {
+ $fields = $this->getTemplateFields($creator, $fileId);
+ if (empty($fields)) {
+ continue;
+ }
+
+ return $fields;
+ }
+
+ return [];
+ }
+
/**
* @param string $filePath
* @param string $templateId
@@ -187,6 +201,20 @@ class TemplateManager implements ITemplateManager {
* @return list<Template>
*/
private function getTemplateFiles(TemplateFileCreator $type): array {
+ $templates = array_merge(
+ $this->getProviderTemplates($type),
+ $this->getUserTemplates($type)
+ );
+
+ $this->eventDispatcher->dispatchTyped(new BeforeGetTemplatesEvent($templates, false));
+
+ return $templates;
+ }
+
+ /**
+ * @return list<Template>
+ */
+ private function getProviderTemplates(TemplateFileCreator $type): array {
$templates = [];
foreach ($this->getRegisteredProviders() as $provider) {
foreach ($type->getMimetypes() as $mimetype) {
@@ -195,11 +223,22 @@ class TemplateManager implements ITemplateManager {
}
}
}
+
+ return $templates;
+ }
+
+ /**
+ * @return list<Template>
+ */
+ private function getUserTemplates(TemplateFileCreator $type): array {
+ $templates = [];
+
try {
$userTemplateFolder = $this->getTemplateFolder();
} catch (\Exception $e) {
return $templates;
}
+
foreach ($type->getMimetypes() as $mimetype) {
foreach ($userTemplateFolder->searchByMime($mimetype) as $templateFile) {
$template = new Template(
@@ -212,11 +251,33 @@ class TemplateManager implements ITemplateManager {
}
}
- $this->eventDispatcher->dispatchTyped(new BeforeGetTemplatesEvent($templates));
-
return $templates;
}
+ /*
+ * @return list<Field>
+ */
+ private function getTemplateFields(TemplateFileCreator $type, int $fileId): array {
+ $providerTemplates = $this->getProviderTemplates($type);
+ $userTemplates = $this->getUserTemplates($type);
+
+ $matchedTemplates = array_filter(
+ array_merge($providerTemplates, $userTemplates),
+ function (Template $template) use ($fileId) {
+ return $template->jsonSerialize()['fileid'] === $fileId;
+ });
+
+ if (empty($matchedTemplates)) {
+ return [];
+ }
+
+ $this->eventDispatcher->dispatchTyped(new BeforeGetTemplatesEvent($matchedTemplates, true));
+
+ return array_values(array_map(function (Template $template) {
+ return $template->jsonSerialize()['fields'] ?? [];
+ }, $matchedTemplates));
+ }
+
/**
* @param Node|File $file
* @return array
diff --git a/lib/private/Files/Type/Detection.php b/lib/private/Files/Type/Detection.php
index 42315247dbf..d5810a90868 100644
--- a/lib/private/Files/Type/Detection.php
+++ b/lib/private/Files/Type/Detection.php
@@ -9,6 +9,7 @@ declare(strict_types=1);
namespace OC\Files\Type;
use OCP\Files\IMimeTypeDetector;
+use OCP\IBinaryFinder;
use OCP\ITempManager;
use OCP\IURLGenerator;
use Psr\Log\LoggerInterface;
@@ -23,6 +24,7 @@ use Psr\Log\LoggerInterface;
class Detection implements IMimeTypeDetector {
private const CUSTOM_MIMETYPEMAPPING = 'mimetypemapping.json';
private const CUSTOM_MIMETYPEALIASES = 'mimetypealiases.json';
+ private const CUSTOM_MIMETYPENAMES = 'mimetypenames.json';
/** @var array<list{string, string|null}> */
protected array $mimeTypes = [];
@@ -31,6 +33,8 @@ class Detection implements IMimeTypeDetector {
protected array $mimeTypeIcons = [];
/** @var array<string,string> */
protected array $mimeTypeAlias = [];
+ /** @var array<string,string> */
+ protected array $mimeTypesNames = [];
public function __construct(
private IURLGenerator $urlGenerator,
@@ -148,6 +152,25 @@ class Detection implements IMimeTypeDetector {
return $this->mimeTypes;
}
+ private function loadNamings(): void {
+ if (!empty($this->mimeTypesNames)) {
+ return;
+ }
+
+ $mimeTypeMapping = json_decode(file_get_contents($this->defaultConfigDir . '/mimetypenames.dist.json'), true);
+ $mimeTypeMapping = $this->loadCustomDefinitions(self::CUSTOM_MIMETYPENAMES, $mimeTypeMapping);
+
+ $this->mimeTypesNames = $mimeTypeMapping;
+ }
+
+ /**
+ * @return array<string,string>
+ */
+ public function getAllNamings(): array {
+ $this->loadNamings();
+ return $this->mimeTypesNames;
+ }
+
/**
* detect MIME type only based on filename, content of file is not used
*
@@ -225,11 +248,13 @@ class Detection implements IMimeTypeDetector {
}
}
- if (\OC_Helper::canExecute('file')) {
+ $binaryFinder = \OCP\Server::get(IBinaryFinder::class);
+ $program = $binaryFinder->findBinaryPath('file');
+ if ($program !== false) {
// it looks like we have a 'file' command,
// lets see if it does have mime support
$path = escapeshellarg($path);
- $fp = popen("test -f $path && file -b --mime-type $path", 'r');
+ $fp = popen("test -f $path && $program -b --mime-type $path", 'r');
if ($fp !== false) {
$mimeType = fgets($fp);
pclose($fp);
diff --git a/lib/private/Files/Utils/Scanner.php b/lib/private/Files/Utils/Scanner.php
index 4d94629443f..e9ed351b27b 100644
--- a/lib/private/Files/Utils/Scanner.php
+++ b/lib/private/Files/Utils/Scanner.php
@@ -29,6 +29,7 @@ use OCP\Files\Storage\IStorage;
use OCP\Files\StorageNotAvailableException;
use OCP\IDBConnection;
use OCP\Lock\ILockingProvider;
+use OCP\Lock\LockedException;
use Psr\Log\LoggerInterface;
/**
@@ -260,7 +261,15 @@ class Scanner extends PublicEmitter {
try {
$propagator = $storage->getPropagator();
$propagator->beginBatch();
- $scanner->scan($relativePath, $recursive, \OC\Files\Cache\Scanner::REUSE_ETAG | \OC\Files\Cache\Scanner::REUSE_SIZE);
+ try {
+ $scanner->scan($relativePath, $recursive, \OC\Files\Cache\Scanner::REUSE_ETAG | \OC\Files\Cache\Scanner::REUSE_SIZE);
+ } catch (LockedException $e) {
+ if (is_string($e->getReadablePath()) && str_starts_with($e->getReadablePath(), 'scanner::')) {
+ throw new LockedException("scanner::$dir", $e, $e->getExistingLock());
+ } else {
+ throw $e;
+ }
+ }
$cache = $storage->getCache();
if ($cache instanceof Cache) {
// only re-calculate for the root folder we scanned, anything below that is taken care of by the scanner
diff --git a/lib/private/Files/View.php b/lib/private/Files/View.php
index bbad24d3e43..63eecf5e1d6 100644
--- a/lib/private/Files/View.php
+++ b/lib/private/Files/View.php
@@ -10,12 +10,14 @@ namespace OC\Files;
use Icewind\Streams\CallbackWrapper;
use OC\Files\Mount\MoveableMount;
use OC\Files\Storage\Storage;
+use OC\Files\Storage\Wrapper\Quota;
use OC\Share\Share;
use OC\User\LazyUser;
use OC\User\Manager as UserManager;
use OC\User\User;
use OCA\Files_Sharing\SharedMount;
use OCP\Constants;
+use OCP\Files;
use OCP\Files\Cache\ICacheEntry;
use OCP\Files\ConnectionLostException;
use OCP\Files\EmptyFileNameException;
@@ -628,7 +630,7 @@ class View {
[$storage, $internalPath] = $this->resolvePath($path);
$target = $storage->fopen($internalPath, 'w');
if ($target) {
- [, $result] = \OC_Helper::streamCopy($data, $target);
+ [, $result] = Files::streamCopy($data, $target, true);
fclose($target);
fclose($data);
@@ -936,7 +938,7 @@ class View {
try {
$exists = $this->file_exists($target);
- if ($this->shouldEmitHooks()) {
+ if ($this->shouldEmitHooks($target)) {
\OC_Hook::emit(
Filesystem::CLASSNAME,
Filesystem::signal_copy,
@@ -976,7 +978,7 @@ class View {
$this->changeLock($target, ILockingProvider::LOCK_SHARED);
$lockTypePath2 = ILockingProvider::LOCK_SHARED;
- if ($this->shouldEmitHooks() && $result !== false) {
+ if ($this->shouldEmitHooks($target) && $result !== false) {
\OC_Hook::emit(
Filesystem::CLASSNAME,
Filesystem::signal_post_copy,
@@ -1466,8 +1468,7 @@ class View {
public function addSubMounts(FileInfo $info, $extOnly = false): void {
$mounts = Filesystem::getMountManager()->findIn($info->getPath());
$info->setSubMounts(array_filter($mounts, function (IMountPoint $mount) use ($extOnly) {
- $subStorage = $mount->getStorage();
- return !($extOnly && $subStorage instanceof \OCA\Files_Sharing\SharedStorage);
+ return !($extOnly && $mount instanceof SharedMount);
}));
}
@@ -1579,12 +1580,22 @@ class View {
// Create parent folders if the mountpoint is inside a subfolder that doesn't exist yet
if (!isset($files[$entryName])) {
try {
+ [$storage, ] = $this->resolvePath($path . '/' . $entryName);
+ // make sure we can create the mountpoint folder, even if the user has a quota of 0
+ if ($storage->instanceOfStorage(Quota::class)) {
+ $storage->enableQuota(false);
+ }
+
if ($this->mkdir($path . '/' . $entryName) !== false) {
$info = $this->getFileInfo($path . '/' . $entryName);
if ($info !== false) {
$files[$entryName] = $info;
}
}
+
+ if ($storage->instanceOfStorage(Quota::class)) {
+ $storage->enableQuota(true);
+ }
} catch (\Exception $e) {
// Creating the parent folder might not be possible, for example due to a lack of permissions.
$this->logger->debug('Failed to create non-existent parent', ['exception' => $e, 'path' => $path . '/' . $entryName]);
diff --git a/lib/private/Group/Group.php b/lib/private/Group/Group.php
index 147c5baf543..6e42fad8b9f 100644
--- a/lib/private/Group/Group.php
+++ b/lib/private/Group/Group.php
@@ -377,7 +377,7 @@ class Group implements IGroup {
*/
public function hideFromCollaboration(): bool {
return array_reduce($this->backends, function (bool $hide, GroupInterface $backend) {
- return $hide | ($backend instanceof IHideFromCollaborationBackend && $backend->hideGroup($this->gid));
+ return $hide || ($backend instanceof IHideFromCollaborationBackend && $backend->hideGroup($this->gid));
}, false);
}
}
diff --git a/lib/private/Http/Client/Response.php b/lib/private/Http/Client/Response.php
index adf83306d07..dc0b17ab075 100644
--- a/lib/private/Http/Client/Response.php
+++ b/lib/private/Http/Client/Response.php
@@ -11,49 +11,25 @@ namespace OC\Http\Client;
use OCP\Http\Client\IResponse;
use Psr\Http\Message\ResponseInterface;
-/**
- * Class Response
- *
- * @package OC\Http
- */
class Response implements IResponse {
- /** @var ResponseInterface */
- private $response;
-
- /**
- * @var bool
- */
- private $stream;
+ private ResponseInterface $response;
+ private bool $stream;
- /**
- * @param ResponseInterface $response
- * @param bool $stream
- */
- public function __construct(ResponseInterface $response, $stream = false) {
+ public function __construct(ResponseInterface $response, bool $stream = false) {
$this->response = $response;
$this->stream = $stream;
}
- /**
- * @return string|resource
- */
public function getBody() {
return $this->stream ?
$this->response->getBody()->detach():
$this->response->getBody()->getContents();
}
- /**
- * @return int
- */
public function getStatusCode(): int {
return $this->response->getStatusCode();
}
- /**
- * @param string $key
- * @return string
- */
public function getHeader(string $key): string {
$headers = $this->response->getHeader($key);
@@ -64,9 +40,6 @@ class Response implements IResponse {
return $headers[0];
}
- /**
- * @return array
- */
public function getHeaders(): array {
return $this->response->getHeaders();
}
diff --git a/lib/private/Installer.php b/lib/private/Installer.php
index 00fdd84c1bc..3bbef3252f4 100644
--- a/lib/private/Installer.php
+++ b/lib/private/Installer.php
@@ -10,20 +10,23 @@ declare(strict_types=1);
namespace OC;
use Doctrine\DBAL\Exception\TableExistsException;
+use OC\App\AppStore\AppNotFoundException;
use OC\App\AppStore\Bundles\Bundle;
use OC\App\AppStore\Fetcher\AppFetcher;
use OC\AppFramework\Bootstrap\Coordinator;
use OC\Archive\TAR;
use OC\DB\Connection;
use OC\DB\MigrationService;
+use OC\Files\FilenameValidator;
use OC_App;
-use OC_Helper;
use OCP\App\IAppManager;
+use OCP\Files;
use OCP\HintException;
use OCP\Http\Client\IClientService;
use OCP\IConfig;
use OCP\ITempManager;
use OCP\Migration\IOutput;
+use OCP\Server;
use phpseclib\File\X509;
use Psr\Log\LoggerInterface;
@@ -172,6 +175,7 @@ class Installer {
* @param string $appId
* @param bool [$allowUnstable]
*
+ * @throws AppNotFoundException If the app is not found on the appstore
* @throws \Exception If the installation was not successful
*/
public function downloadApp(string $appId, bool $allowUnstable = false): void {
@@ -241,6 +245,10 @@ class Installer {
// Download the release
$tempFile = $this->tempManager->getTemporaryFile('.tar.gz');
+ if ($tempFile === false) {
+ throw new \RuntimeException('Could not create temporary file for downloading app archive.');
+ }
+
$timeout = $this->isCLI ? 0 : 120;
$client = $this->clientService->newClient();
$client->get($app['releases'][0]['download'], ['sink' => $tempFile, 'timeout' => $timeout]);
@@ -252,8 +260,11 @@ class Installer {
if ($verified === true) {
// Seems to match, let's proceed
$extractDir = $this->tempManager->getTemporaryFolder();
- $archive = new TAR($tempFile);
+ if ($extractDir === false) {
+ throw new \RuntimeException('Could not create temporary directory for unpacking app.');
+ }
+ $archive = new TAR($tempFile);
if (!$archive->extract($extractDir)) {
$errorMessage = 'Could not extract app ' . $appId;
@@ -324,14 +335,17 @@ class Installer {
$baseDir = OC_App::getInstallPath() . '/' . $appId;
// Remove old app with the ID if existent
- OC_Helper::rmdirr($baseDir);
+ Files::rmdirr($baseDir);
// Move to app folder
if (@mkdir($baseDir)) {
$extractDir .= '/' . $folders[0];
- OC_Helper::copyr($extractDir, $baseDir);
}
- OC_Helper::copyr($extractDir, $baseDir);
- OC_Helper::rmdirr($extractDir);
+ // otherwise we just copy the outer directory
+ $this->copyRecursive($extractDir, $baseDir);
+ Files::rmdirr($extractDir);
+ if (function_exists('opcache_reset')) {
+ opcache_reset();
+ }
return;
}
// Signature does not match
@@ -344,9 +358,9 @@ class Installer {
}
}
- throw new \Exception(
+ throw new AppNotFoundException(
sprintf(
- 'Could not download app %s',
+ 'Could not download app %s, it was not found on the appstore',
$appId
)
);
@@ -450,7 +464,7 @@ class Installer {
return false;
}
$appDir = OC_App::getInstallPath() . '/' . $appId;
- OC_Helper::rmdirr($appDir);
+ Files::rmdirr($appDir);
return true;
} else {
$this->logger->error('can\'t remove app ' . $appId . '. It is not installed.');
@@ -587,4 +601,33 @@ class Installer {
include $script;
}
}
+
+ /**
+ * Recursive copying of local folders.
+ *
+ * @param string $src source folder
+ * @param string $dest target folder
+ */
+ private function copyRecursive(string $src, string $dest): void {
+ if (!file_exists($src)) {
+ return;
+ }
+
+ if (is_dir($src)) {
+ if (!is_dir($dest)) {
+ mkdir($dest);
+ }
+ $files = scandir($src);
+ foreach ($files as $file) {
+ if ($file != '.' && $file != '..') {
+ $this->copyRecursive("$src/$file", "$dest/$file");
+ }
+ }
+ } else {
+ $validator = Server::get(FilenameValidator::class);
+ if (!$validator->isForbidden($src)) {
+ copy($src, $dest);
+ }
+ }
+ }
}
diff --git a/lib/private/IntegrityCheck/Checker.php b/lib/private/IntegrityCheck/Checker.php
index 361fe8e9b2d..2bd6e426b79 100644
--- a/lib/private/IntegrityCheck/Checker.php
+++ b/lib/private/IntegrityCheck/Checker.php
@@ -148,10 +148,10 @@ class Checker {
}
if ($filename === $this->environmentHelper->getServerRoot() . '/core/js/mimetypelist.js') {
$oldMimetypeList = new GenerateMimetypeFileBuilder();
- $newFile = $oldMimetypeList->generateFile($this->mimeTypeDetector->getAllAliases());
+ $newFile = $oldMimetypeList->generateFile($this->mimeTypeDetector->getAllAliases(), $this->mimeTypeDetector->getAllNamings());
$oldFile = $this->fileAccessHelper->file_get_contents($filename);
if ($newFile === $oldFile) {
- $hashes[$relativeFileName] = hash('sha512', $oldMimetypeList->generateFile($this->mimeTypeDetector->getOnlyDefaultAliases()));
+ $hashes[$relativeFileName] = hash('sha512', $oldMimetypeList->generateFile($this->mimeTypeDetector->getOnlyDefaultAliases(), $this->mimeTypeDetector->getAllNamings()));
continue;
}
}
diff --git a/lib/private/Lockdown/Filesystem/NullCache.php b/lib/private/Lockdown/Filesystem/NullCache.php
index e84ff40e00c..fcd9e7f1340 100644
--- a/lib/private/Lockdown/Filesystem/NullCache.php
+++ b/lib/private/Lockdown/Filesystem/NullCache.php
@@ -21,20 +21,23 @@ class NullCache implements ICache {
}
public function get($file) {
- return $file !== '' ? null :
- new CacheEntry([
- 'fileid' => -1,
- 'parent' => -1,
- 'name' => '',
- 'path' => '',
- 'size' => '0',
- 'mtime' => time(),
- 'storage_mtime' => time(),
- 'etag' => '',
- 'mimetype' => FileInfo::MIMETYPE_FOLDER,
- 'mimepart' => 'httpd',
- 'permissions' => Constants::PERMISSION_READ
- ]);
+ if ($file !== '') {
+ return false;
+ }
+
+ return new CacheEntry([
+ 'fileid' => -1,
+ 'parent' => -1,
+ 'name' => '',
+ 'path' => '',
+ 'size' => '0',
+ 'mtime' => time(),
+ 'storage_mtime' => time(),
+ 'etag' => '',
+ 'mimetype' => FileInfo::MIMETYPE_FOLDER,
+ 'mimepart' => 'httpd',
+ 'permissions' => Constants::PERMISSION_READ
+ ]);
}
public function getFolderContents($folder) {
diff --git a/lib/private/Log/ErrorHandler.php b/lib/private/Log/ErrorHandler.php
index e1faf336118..6597274a868 100644
--- a/lib/private/Log/ErrorHandler.php
+++ b/lib/private/Log/ErrorHandler.php
@@ -72,9 +72,9 @@ class ErrorHandler {
private static function errnoToLogLevel(int $errno): int {
return match ($errno) {
- E_USER_WARNING => ILogger::WARN,
+ E_WARNING, E_USER_WARNING => ILogger::WARN,
E_DEPRECATED, E_USER_DEPRECATED => ILogger::DEBUG,
- E_USER_NOTICE => ILogger::INFO,
+ E_NOTICE, E_USER_NOTICE => ILogger::INFO,
default => ILogger::ERROR,
};
}
diff --git a/lib/private/Log/LogDetails.php b/lib/private/Log/LogDetails.php
index b3ae23a3770..8c1efaea20d 100644
--- a/lib/private/Log/LogDetails.php
+++ b/lib/private/Log/LogDetails.php
@@ -59,6 +59,10 @@ abstract class LogDetails {
'userAgent',
'version'
);
+ $clientReqId = $request->getHeader('X-Request-Id');
+ if ($clientReqId !== '') {
+ $entry['clientReqId'] = $clientReqId;
+ }
if (is_array($message)) {
// Exception messages are extracted and the exception is put into a separate field
diff --git a/lib/private/Log/Rotate.php b/lib/private/Log/Rotate.php
index 839c40726b7..ee1593b87ac 100644
--- a/lib/private/Log/Rotate.php
+++ b/lib/private/Log/Rotate.php
@@ -7,6 +7,8 @@
*/
namespace OC\Log;
+use OCP\AppFramework\Utility\ITimeFactory;
+use OCP\BackgroundJob\TimedJob;
use OCP\IConfig;
use OCP\Log\RotationTrait;
use Psr\Log\LoggerInterface;
@@ -17,9 +19,15 @@ use Psr\Log\LoggerInterface;
* For more professional log management set the 'logfile' config to a different
* location and manage that with your own tools.
*/
-class Rotate extends \OCP\BackgroundJob\Job {
+class Rotate extends TimedJob {
use RotationTrait;
+ public function __construct(ITimeFactory $time) {
+ parent::__construct($time);
+
+ $this->setInterval(3600);
+ }
+
public function run($argument): void {
$config = \OCP\Server::get(IConfig::class);
$this->filePath = $config->getSystemValueString('logfile', $config->getSystemValueString('datadirectory', \OC::$SERVERROOT . '/data') . '/nextcloud.log');
diff --git a/lib/private/NavigationManager.php b/lib/private/NavigationManager.php
index c2125bc6f8a..fb0795376bb 100644
--- a/lib/private/NavigationManager.php
+++ b/lib/private/NavigationManager.php
@@ -77,7 +77,7 @@ class NavigationManager implements INavigationManager {
$this->closureEntries[] = $entry;
return;
}
- $this->init();
+ $this->init(false);
$id = $entry['id'];
@@ -123,10 +123,6 @@ class NavigationManager implements INavigationManager {
*/
public function getAll(string $type = 'link'): array {
$this->init();
- foreach ($this->closureEntries as $c) {
- $this->add($c());
- }
- $this->closureEntries = [];
$result = $this->entries;
if ($type !== 'all') {
@@ -212,7 +208,13 @@ class NavigationManager implements INavigationManager {
return $this->activeEntry;
}
- private function init() {
+ private function init(bool $resolveClosures = true): void {
+ if ($resolveClosures) {
+ while ($c = array_pop($this->closureEntries)) {
+ $this->add($c());
+ }
+ }
+
if ($this->init) {
return;
}
@@ -420,11 +422,6 @@ class NavigationManager implements INavigationManager {
public function get(string $id): ?array {
$this->init();
- foreach ($this->closureEntries as $c) {
- $this->add($c());
- }
- $this->closureEntries = [];
-
return $this->entries[$id];
}
diff --git a/lib/private/Notification/Manager.php b/lib/private/Notification/Manager.php
index b75e52deacb..8c457db8beb 100644
--- a/lib/private/Notification/Manager.php
+++ b/lib/private/Notification/Manager.php
@@ -217,7 +217,9 @@ class Manager implements IManager {
* @since 8.2.0
*/
public function hasNotifiers(): bool {
- return !empty($this->notifiers) || !empty($this->notifierClasses);
+ return !empty($this->notifiers)
+ || !empty($this->notifierClasses)
+ || (!$this->parsedRegistrationContext && !empty($this->coordinator->getRegistrationContext()->getNotifierServices()));
}
/**
diff --git a/lib/private/OCM/Model/OCMProvider.php b/lib/private/OCM/Model/OCMProvider.php
index f4b0ac584de..be13d65a40f 100644
--- a/lib/private/OCM/Model/OCMProvider.php
+++ b/lib/private/OCM/Model/OCMProvider.php
@@ -11,18 +11,22 @@ namespace OC\OCM\Model;
use NCU\Security\Signature\Model\Signatory;
use OCP\EventDispatcher\IEventDispatcher;
+use OCP\IConfig;
use OCP\OCM\Events\ResourceTypeRegisterEvent;
use OCP\OCM\Exceptions\OCMArgumentException;
use OCP\OCM\Exceptions\OCMProviderException;
-use OCP\OCM\IOCMProvider;
+use OCP\OCM\ICapabilityAwareOCMProvider;
use OCP\OCM\IOCMResource;
/**
* @since 28.0.0
*/
-class OCMProvider implements IOCMProvider {
+class OCMProvider implements ICapabilityAwareOCMProvider {
+ private string $provider;
private bool $enabled = false;
private string $apiVersion = '';
+ private string $inviteAcceptDialog = '';
+ private array $capabilities = [];
private string $endPoint = '';
/** @var IOCMResource[] */
private array $resourceTypes = [];
@@ -31,7 +35,9 @@ class OCMProvider implements IOCMProvider {
public function __construct(
protected IEventDispatcher $dispatcher,
+ protected IConfig $config,
) {
+ $this->provider = 'Nextcloud ' . $config->getSystemValue('version');
}
/**
@@ -71,6 +77,30 @@ class OCMProvider implements IOCMProvider {
}
/**
+ * returns the invite accept dialog
+ *
+ * @return string
+ * @since 32.0.0
+ */
+ public function getInviteAcceptDialog(): string {
+ return $this->inviteAcceptDialog;
+ }
+
+ /**
+ * set the invite accept dialog
+ *
+ * @param string $inviteAcceptDialog
+ *
+ * @return $this
+ * @since 32.0.0
+ */
+ public function setInviteAcceptDialog(string $inviteAcceptDialog): static {
+ $this->inviteAcceptDialog = $inviteAcceptDialog;
+
+ return $this;
+ }
+
+ /**
* @param string $endPoint
*
* @return $this
@@ -89,6 +119,34 @@ class OCMProvider implements IOCMProvider {
}
/**
+ * @return string
+ */
+ public function getProvider(): string {
+ return $this->provider;
+ }
+
+ /**
+ * @param array $capabilities
+ *
+ * @return $this
+ */
+ public function setCapabilities(array $capabilities): static {
+ foreach ($capabilities as $value) {
+ if (!in_array($value, $this->capabilities)) {
+ array_push($this->capabilities, $value);
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * @return array
+ */
+ public function getCapabilities(): array {
+ return $this->capabilities;
+ }
+ /**
* create a new resource to later add it with {@see IOCMProvider::addResourceType()}
* @return IOCMResource
*/
@@ -166,9 +224,8 @@ class OCMProvider implements IOCMProvider {
*
* @param array $data
*
- * @return $this
+ * @return OCMProvider&static
* @throws OCMProviderException in case a descent provider cannot be generated from data
- * @see self::jsonSerialize()
*/
public function import(array $data): static {
$this->setEnabled(is_bool($data['enabled'] ?? '') ? $data['enabled'] : false)
@@ -209,21 +266,7 @@ class OCMProvider implements IOCMProvider {
}
/**
- * @return array{
- * enabled: bool,
- * apiVersion: '1.0-proposal1',
- * endPoint: string,
- * publicKey?: array{
- * keyId: string,
- * publicKeyPem: string
- * },
- * resourceTypes: list<array{
- * name: string,
- * shareTypes: list<string>,
- * protocols: array<string, string>
- * }>,
- * version: string
- * }
+ * @since 28.0.0
*/
public function jsonSerialize(): array {
$resourceTypes = [];
@@ -231,7 +274,7 @@ class OCMProvider implements IOCMProvider {
$resourceTypes[] = $res->jsonSerialize();
}
- return [
+ $response = [
'enabled' => $this->isEnabled(),
'apiVersion' => '1.0-proposal1', // deprecated, but keep it to stay compatible with old version
'version' => $this->getApiVersion(), // informative but real version
@@ -239,5 +282,16 @@ class OCMProvider implements IOCMProvider {
'publicKey' => $this->getSignatory()?->jsonSerialize(),
'resourceTypes' => $resourceTypes
];
+
+ $capabilities = $this->getCapabilities();
+ $inviteAcceptDialog = $this->getInviteAcceptDialog();
+ if ($capabilities) {
+ $response['capabilities'] = $capabilities;
+ }
+ if ($inviteAcceptDialog) {
+ $response['inviteAcceptDialog'] = $inviteAcceptDialog;
+ }
+ return $response;
+
}
}
diff --git a/lib/private/OCM/OCMDiscoveryService.php b/lib/private/OCM/OCMDiscoveryService.php
index af612416372..a151bbc753c 100644
--- a/lib/private/OCM/OCMDiscoveryService.php
+++ b/lib/private/OCM/OCMDiscoveryService.php
@@ -17,8 +17,8 @@ use OCP\ICache;
use OCP\ICacheFactory;
use OCP\IConfig;
use OCP\OCM\Exceptions\OCMProviderException;
+use OCP\OCM\ICapabilityAwareOCMProvider;
use OCP\OCM\IOCMDiscoveryService;
-use OCP\OCM\IOCMProvider;
use Psr\Log\LoggerInterface;
/**
@@ -31,7 +31,7 @@ class OCMDiscoveryService implements IOCMDiscoveryService {
ICacheFactory $cacheFactory,
private IClientService $clientService,
private IConfig $config,
- private IOCMProvider $provider,
+ private ICapabilityAwareOCMProvider $provider,
private LoggerInterface $logger,
) {
$this->cache = $cacheFactory->createDistributed('ocm-discovery');
@@ -42,10 +42,10 @@ class OCMDiscoveryService implements IOCMDiscoveryService {
* @param string $remote
* @param bool $skipCache
*
- * @return IOCMProvider
+ * @return ICapabilityAwareOCMProvider
* @throws OCMProviderException
*/
- public function discover(string $remote, bool $skipCache = false): IOCMProvider {
+ public function discover(string $remote, bool $skipCache = false): ICapabilityAwareOCMProvider {
$remote = rtrim($remote, '/');
if (!str_starts_with($remote, 'http://') && !str_starts_with($remote, 'https://')) {
// if scheme not specified, we test both;
diff --git a/lib/private/Preview/Generator.php b/lib/private/Preview/Generator.php
index b95971d0085..4a7341896ef 100644
--- a/lib/private/Preview/Generator.php
+++ b/lib/private/Preview/Generator.php
@@ -12,6 +12,7 @@ use OCP\Files\IAppData;
use OCP\Files\InvalidPathException;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
+use OCP\Files\SimpleFS\InMemoryFile;
use OCP\Files\SimpleFS\ISimpleFile;
use OCP\Files\SimpleFS\ISimpleFolder;
use OCP\IConfig;
@@ -43,17 +44,19 @@ class Generator {
* The cache is searched first and if nothing usable was found then a preview is
* generated by one of the providers
*
- * @param File $file
- * @param int $width
- * @param int $height
- * @param bool $crop
- * @param string $mode
- * @param string|null $mimeType
* @return ISimpleFile
* @throws NotFoundException
* @throws \InvalidArgumentException if the preview would be invalid (in case the original image is invalid)
*/
- public function getPreview(File $file, $width = -1, $height = -1, $crop = false, $mode = IPreview::MODE_FILL, $mimeType = null) {
+ public function getPreview(
+ File $file,
+ int $width = -1,
+ int $height = -1,
+ bool $crop = false,
+ string $mode = IPreview::MODE_FILL,
+ ?string $mimeType = null,
+ bool $cacheResult = true,
+ ): ISimpleFile {
$specification = [
'width' => $width,
'height' => $height,
@@ -78,23 +81,19 @@ class Generator {
'mode' => $mode,
'mimeType' => $mimeType,
]);
-
+
// since we only ask for one preview, and the generate method return the last one it created, it returns the one we want
- return $this->generatePreviews($file, [$specification], $mimeType);
+ return $this->generatePreviews($file, [$specification], $mimeType, $cacheResult);
}
/**
* Generates previews of a file
*
- * @param File $file
- * @param non-empty-array $specifications
- * @param string $mimeType
- * @return ISimpleFile the last preview that was generated
* @throws NotFoundException
* @throws \InvalidArgumentException if the preview would be invalid (in case the original image is invalid)
*/
- public function generatePreviews(File $file, array $specifications, $mimeType = null) {
+ public function generatePreviews(File $file, array $specifications, ?string $mimeType = null, bool $cacheResult = true): ISimpleFile {
//Make sure that we can read the file
if (!$file->isReadable()) {
$this->logger->warning('Cannot read file: {path}, skipping preview generation.', ['path' => $file->getPath()]);
@@ -166,8 +165,8 @@ class Generator {
$maxPreviewImage = $this->helper->getImage($maxPreview);
}
- $this->logger->warning('Cached preview not found for file {path}, generating a new preview.', ['path' => $file->getPath()]);
- $preview = $this->generatePreview($previewFolder, $maxPreviewImage, $width, $height, $crop, $maxWidth, $maxHeight, $previewVersion);
+ $this->logger->debug('Cached preview not found for file {path}, generating a new preview.', ['path' => $file->getPath()]);
+ $preview = $this->generatePreview($previewFolder, $maxPreviewImage, $width, $height, $crop, $maxWidth, $maxHeight, $previewVersion, $cacheResult);
// New file, augment our array
$previewFiles[] = $preview;
}
@@ -351,11 +350,10 @@ class Generator {
$path = $this->generatePath($preview->width(), $preview->height(), $crop, $max, $preview->dataMimeType(), $prefix);
try {
- $file = $previewFolder->newFile($path);
if ($preview instanceof IStreamImage) {
- $file->putContent($preview->resource());
+ return $previewFolder->newFile($path, $preview->resource());
} else {
- $file->putContent($preview->data());
+ return $previewFolder->newFile($path, $preview->data());
}
} catch (NotPermittedException $e) {
throw new NotFoundException();
@@ -490,19 +488,20 @@ class Generator {
}
/**
- * @param ISimpleFolder $previewFolder
- * @param ISimpleFile $maxPreview
- * @param int $width
- * @param int $height
- * @param bool $crop
- * @param int $maxWidth
- * @param int $maxHeight
- * @param string $prefix
- * @return ISimpleFile
* @throws NotFoundException
* @throws \InvalidArgumentException if the preview would be invalid (in case the original image is invalid)
*/
- private function generatePreview(ISimpleFolder $previewFolder, IImage $maxPreview, $width, $height, $crop, $maxWidth, $maxHeight, $prefix) {
+ private function generatePreview(
+ ISimpleFolder $previewFolder,
+ IImage $maxPreview,
+ int $width,
+ int $height,
+ bool $crop,
+ int $maxWidth,
+ int $maxHeight,
+ string $prefix,
+ bool $cacheResult,
+ ): ISimpleFile {
$preview = $maxPreview;
if (!$preview->valid()) {
throw new \InvalidArgumentException('Failed to generate preview, failed to load image');
@@ -539,12 +538,14 @@ class Generator {
$path = $this->generatePath($width, $height, $crop, false, $preview->dataMimeType(), $prefix);
try {
- $file = $previewFolder->newFile($path);
- $file->putContent($preview->data());
+ if ($cacheResult) {
+ return $previewFolder->newFile($path, $preview->data());
+ } else {
+ return new InMemoryFile($path, $preview->data());
+ }
} catch (NotPermittedException $e) {
throw new NotFoundException();
}
-
return $file;
}
diff --git a/lib/private/Preview/Movie.php b/lib/private/Preview/Movie.php
index 7de543198f4..47895f999d8 100644
--- a/lib/private/Preview/Movie.php
+++ b/lib/private/Preview/Movie.php
@@ -166,8 +166,8 @@ class Movie extends ProviderV2 {
$returnCode = -1;
$output = '';
if (is_resource($proc)) {
- $stdout = trim(stream_get_contents($pipes[1]));
$stderr = trim(stream_get_contents($pipes[2]));
+ $stdout = trim(stream_get_contents($pipes[1]));
$returnCode = proc_close($proc);
$output = $stdout . $stderr;
}
diff --git a/lib/private/PreviewManager.php b/lib/private/PreviewManager.php
index bc77dcfe483..0bb0280406c 100644
--- a/lib/private/PreviewManager.php
+++ b/lib/private/PreviewManager.php
@@ -145,29 +145,20 @@ class PreviewManager implements IPreview {
return $this->generator;
}
- /**
- * Returns a preview of a file
- *
- * The cache is searched first and if nothing usable was found then a preview is
- * generated by one of the providers
- *
- * @param File $file
- * @param int $width
- * @param int $height
- * @param bool $crop
- * @param string $mode
- * @param string $mimeType
- * @return ISimpleFile
- * @throws NotFoundException
- * @throws \InvalidArgumentException if the preview would be invalid (in case the original image is invalid)
- * @since 11.0.0 - \InvalidArgumentException was added in 12.0.0
- */
- public function getPreview(File $file, $width = -1, $height = -1, $crop = false, $mode = IPreview::MODE_FILL, $mimeType = null) {
- $this->throwIfPreviewsDisabled();
+ public function getPreview(
+ File $file,
+ $width = -1,
+ $height = -1,
+ $crop = false,
+ $mode = IPreview::MODE_FILL,
+ $mimeType = null,
+ bool $cacheResult = true,
+ ): ISimpleFile {
+ $this->throwIfPreviewsDisabled($file, $mimeType);
$previewConcurrency = $this->getGenerator()->getNumConcurrentPreviews('preview_concurrency_all');
$sem = Generator::guardWithSemaphore(Generator::SEMAPHORE_ID_ALL, $previewConcurrency);
try {
- $preview = $this->getGenerator()->getPreview($file, $width, $height, $crop, $mode, $mimeType);
+ $preview = $this->getGenerator()->getPreview($file, $width, $height, $crop, $mode, $mimeType, $cacheResult);
} finally {
Generator::unguardWithSemaphore($sem);
}
@@ -187,7 +178,7 @@ class PreviewManager implements IPreview {
* @since 19.0.0
*/
public function generatePreviews(File $file, array $specifications, $mimeType = null) {
- $this->throwIfPreviewsDisabled();
+ $this->throwIfPreviewsDisabled($file, $mimeType);
return $this->getGenerator()->generatePreviews($file, $specifications, $mimeType);
}
@@ -222,13 +213,15 @@ class PreviewManager implements IPreview {
/**
* Check if a preview can be generated for a file
*/
- public function isAvailable(\OCP\Files\FileInfo $file): bool {
+ public function isAvailable(\OCP\Files\FileInfo $file, ?string $mimeType = null): bool {
if (!$this->enablePreviews) {
return false;
}
+ $fileMimeType = $mimeType ?? $file->getMimeType();
+
$this->registerCoreProviders();
- if (!$this->isMimeSupported($file->getMimetype())) {
+ if (!$this->isMimeSupported($fileMimeType)) {
return false;
}
@@ -238,7 +231,7 @@ class PreviewManager implements IPreview {
}
foreach ($this->providers as $supportedMimeType => $providers) {
- if (preg_match($supportedMimeType, $file->getMimetype())) {
+ if (preg_match($supportedMimeType, $fileMimeType)) {
foreach ($providers as $providerClosure) {
$provider = $this->helper->getProvider($providerClosure);
if (!($provider instanceof IProviderV2)) {
@@ -464,8 +457,8 @@ class PreviewManager implements IPreview {
/**
* @throws NotFoundException if preview generation is disabled
*/
- private function throwIfPreviewsDisabled(): void {
- if (!$this->enablePreviews) {
+ private function throwIfPreviewsDisabled(File $file, ?string $mimeType = null): void {
+ if (!$this->isAvailable($file, $mimeType)) {
throw new NotFoundException('Previews disabled');
}
}
diff --git a/lib/private/Remote/Instance.php b/lib/private/Remote/Instance.php
index ac3233b93c9..b85813ebf71 100644
--- a/lib/private/Remote/Instance.php
+++ b/lib/private/Remote/Instance.php
@@ -123,7 +123,13 @@ class Instance implements IInstance {
private function downloadStatus($url) {
try {
$request = $this->clientService->newClient()->get($url);
- return $request->getBody();
+ $content = $request->getBody();
+
+ // IResponse.getBody responds with null|resource if returning a stream response was requested.
+ // As that's not the case here, we can just ignore the psalm warning by adding an assertion.
+ assert(is_string($content));
+
+ return $content;
} catch (\Exception $e) {
return false;
}
diff --git a/lib/private/Repair.php b/lib/private/Repair.php
index c5069bff48e..7fbf776d9a1 100644
--- a/lib/private/Repair.php
+++ b/lib/private/Repair.php
@@ -61,6 +61,7 @@ use OCP\AppFramework\QueryException;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\Collaboration\Resources\IManager;
use OCP\EventDispatcher\IEventDispatcher;
+use OCP\Files\AppData\IAppDataFactory;
use OCP\IAppConfig;
use OCP\IConfig;
use OCP\IDBConnection;
@@ -173,7 +174,7 @@ class Repair implements IOutput {
\OCP\Server::get(ClearGeneratedAvatarCache::class),
new AddPreviewBackgroundCleanupJob(\OC::$server->getJobList()),
new AddCleanupUpdaterBackupsJob(\OC::$server->getJobList()),
- new CleanupCardDAVPhotoCache(\OC::$server->getConfig(), \OC::$server->getAppDataDir('dav-photocache'), \OC::$server->get(LoggerInterface::class)),
+ new CleanupCardDAVPhotoCache(\OC::$server->getConfig(), \OCP\Server::get(IAppDataFactory::class), \OC::$server->get(LoggerInterface::class)),
new AddClenupLoginFlowV2BackgroundJob(\OC::$server->getJobList()),
new RemoveLinkShares(\OC::$server->getDatabaseConnection(), \OC::$server->getConfig(), \OC::$server->getGroupManager(), \OC::$server->get(INotificationManager::class), \OCP\Server::get(ITimeFactory::class)),
new ClearCollectionsAccessCache(\OC::$server->getConfig(), \OCP\Server::get(IManager::class)),
diff --git a/lib/private/Repair/ConfigKeyMigration.php b/lib/private/Repair/ConfigKeyMigration.php
new file mode 100644
index 00000000000..da4aa153dc5
--- /dev/null
+++ b/lib/private/Repair/ConfigKeyMigration.php
@@ -0,0 +1,29 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace OC\Repair;
+
+use OC\Config\ConfigManager;
+use OCP\Migration\IOutput;
+use OCP\Migration\IRepairStep;
+
+class ConfigKeyMigration implements IRepairStep {
+ public function __construct(
+ private ConfigManager $configManager,
+ ) {
+ }
+
+ public function getName(): string {
+ return 'Migrate config keys';
+ }
+
+ public function run(IOutput $output) {
+ $this->configManager->migrateConfigLexiconKeys();
+ }
+}
diff --git a/lib/private/Repair/MoveUpdaterStepFile.php b/lib/private/Repair/MoveUpdaterStepFile.php
index c9b51b308c4..eb9f78b0a39 100644
--- a/lib/private/Repair/MoveUpdaterStepFile.php
+++ b/lib/private/Repair/MoveUpdaterStepFile.php
@@ -5,6 +5,7 @@
*/
namespace OC\Repair;
+use OCP\Files;
use OCP\Migration\IOutput;
use OCP\Migration\IRepairStep;
@@ -40,7 +41,7 @@ class MoveUpdaterStepFile implements IRepairStep {
// cleanup
if (file_exists($previousStepFile)) {
- if (\OC_Helper::rmdirr($previousStepFile)) {
+ if (Files::rmdirr($previousStepFile)) {
$output->info('.step-previous-update removed');
} else {
$output->info('.step-previous-update can\'t be removed - abort move of .step file');
diff --git a/lib/private/Repair/NC16/CleanupCardDAVPhotoCache.php b/lib/private/Repair/NC16/CleanupCardDAVPhotoCache.php
index a9cbbb4cbbf..646dd2c5e83 100644
--- a/lib/private/Repair/NC16/CleanupCardDAVPhotoCache.php
+++ b/lib/private/Repair/NC16/CleanupCardDAVPhotoCache.php
@@ -6,9 +6,10 @@ declare(strict_types=1);
* SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
+
namespace OC\Repair\NC16;
-use OCP\Files\IAppData;
+use OCP\Files\AppData\IAppDataFactory;
use OCP\Files\NotFoundException;
use OCP\Files\SimpleFS\ISimpleFolder;
use OCP\IConfig;
@@ -27,18 +28,11 @@ use RuntimeException;
* photo could be returned for this vcard. These invalid files are removed by this migration step.
*/
class CleanupCardDAVPhotoCache implements IRepairStep {
- /** @var IConfig */
- private $config;
-
- /** @var IAppData */
- private $appData;
-
- private LoggerInterface $logger;
-
- public function __construct(IConfig $config, IAppData $appData, LoggerInterface $logger) {
- $this->config = $config;
- $this->appData = $appData;
- $this->logger = $logger;
+ public function __construct(
+ private IConfig $config,
+ private IAppDataFactory $appDataFactory,
+ private LoggerInterface $logger,
+ ) {
}
public function getName(): string {
@@ -46,8 +40,10 @@ class CleanupCardDAVPhotoCache implements IRepairStep {
}
private function repair(IOutput $output): void {
+ $photoCacheAppData = $this->appDataFactory->get('dav-photocache');
+
try {
- $folders = $this->appData->getDirectoryListing();
+ $folders = $photoCacheAppData->getDirectoryListing();
} catch (NotFoundException $e) {
return;
} catch (RuntimeException $e) {
diff --git a/lib/private/Route/CachingRouter.php b/lib/private/Route/CachingRouter.php
index 7dd26827d3c..becdb807f73 100644
--- a/lib/private/Route/CachingRouter.php
+++ b/lib/private/Route/CachingRouter.php
@@ -15,10 +15,16 @@ use OCP\IConfig;
use OCP\IRequest;
use Psr\Container\ContainerInterface;
use Psr\Log\LoggerInterface;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\Matcher\CompiledUrlMatcher;
+use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherDumper;
+use Symfony\Component\Routing\RouteCollection;
class CachingRouter extends Router {
protected ICache $cache;
+ protected array $legacyCreatedRoutes = [];
+
public function __construct(
ICacheFactory $cacheFactory,
LoggerInterface $logger,
@@ -54,4 +60,98 @@ class CachingRouter extends Router {
return $url;
}
}
+
+ private function serializeRouteCollection(RouteCollection $collection): array {
+ $dumper = new CompiledUrlMatcherDumper($collection);
+ return $dumper->getCompiledRoutes();
+ }
+
+ /**
+ * Find the route matching $url
+ *
+ * @param string $url The url to find
+ * @throws \Exception
+ * @return array
+ */
+ public function findMatchingRoute(string $url): array {
+ $this->eventLogger->start('cacheroute:match', 'Match route');
+ $key = $this->context->getHost() . '#' . $this->context->getBaseUrl() . '#rootCollection';
+ $cachedRoutes = $this->cache->get($key);
+ if (!$cachedRoutes) {
+ parent::loadRoutes();
+ $cachedRoutes = $this->serializeRouteCollection($this->root);
+ $this->cache->set($key, $cachedRoutes, ($this->config->getSystemValueBool('debug') ? 3 : 3600));
+ }
+ $matcher = new CompiledUrlMatcher($cachedRoutes, $this->context);
+ $this->eventLogger->start('cacheroute:url:match', 'Symfony URL match call');
+ try {
+ $parameters = $matcher->match($url);
+ } catch (ResourceNotFoundException $e) {
+ if (!str_ends_with($url, '/')) {
+ // We allow links to apps/files? for backwards compatibility reasons
+ // However, since Symfony does not allow empty route names, the route
+ // we need to match is '/', so we need to append the '/' here.
+ try {
+ $parameters = $matcher->match($url . '/');
+ } catch (ResourceNotFoundException $newException) {
+ // If we still didn't match a route, we throw the original exception
+ throw $e;
+ }
+ } else {
+ throw $e;
+ }
+ }
+ $this->eventLogger->end('cacheroute:url:match');
+
+ $this->eventLogger->end('cacheroute:match');
+ return $parameters;
+ }
+
+ /**
+ * @param array{action:mixed, ...} $parameters
+ */
+ protected function callLegacyActionRoute(array $parameters): void {
+ /*
+ * Closures cannot be serialized to cache, so for legacy routes calling an action we have to include the routes.php file again
+ */
+ $app = $parameters['app'];
+ $this->useCollection($app);
+ parent::requireRouteFile($parameters['route-file'], $app);
+ $collection = $this->getCollection($app);
+ $parameters['action'] = $collection->get($parameters['_route'])?->getDefault('action');
+ parent::callLegacyActionRoute($parameters);
+ }
+
+ /**
+ * Create a \OC\Route\Route.
+ * Deprecated
+ *
+ * @param string $name Name of the route to create.
+ * @param string $pattern The pattern to match
+ * @param array $defaults An array of default parameter values
+ * @param array $requirements An array of requirements for parameters (regexes)
+ */
+ public function create($name, $pattern, array $defaults = [], array $requirements = []): Route {
+ $this->legacyCreatedRoutes[] = $name;
+ return parent::create($name, $pattern, $defaults, $requirements);
+ }
+
+ /**
+ * Require a routes.php file
+ */
+ protected function requireRouteFile(string $file, string $appName): void {
+ $this->legacyCreatedRoutes = [];
+ parent::requireRouteFile($file, $appName);
+ foreach ($this->legacyCreatedRoutes as $routeName) {
+ $route = $this->collection?->get($routeName);
+ if ($route === null) {
+ /* Should never happen */
+ throw new \Exception("Could not find route $routeName");
+ }
+ if ($route->hasDefault('action')) {
+ $route->setDefault('route-file', $file);
+ $route->setDefault('app', $appName);
+ }
+ }
+ }
}
diff --git a/lib/private/Route/Route.php b/lib/private/Route/Route.php
index ab5a1f6b59a..08231649e76 100644
--- a/lib/private/Route/Route.php
+++ b/lib/private/Route/Route.php
@@ -124,15 +124,9 @@ class Route extends SymfonyRoute implements IRoute {
* The action to execute when this route matches, includes a file like
* it is called directly
* @param string $file
- * @return void
*/
public function actionInclude($file) {
- $function = function ($param) use ($file) {
- unset($param['_route']);
- $_GET = array_merge($_GET, $param);
- unset($param);
- require_once "$file";
- } ;
- $this->action($function);
+ $this->setDefault('file', $file);
+ return $this;
}
}
diff --git a/lib/private/Route/Router.php b/lib/private/Route/Router.php
index d073132516d..90225212e9a 100644
--- a/lib/private/Route/Router.php
+++ b/lib/private/Route/Router.php
@@ -53,10 +53,10 @@ class Router implements IRouter {
public function __construct(
protected LoggerInterface $logger,
IRequest $request,
- private IConfig $config,
- private IEventLogger $eventLogger,
+ protected IConfig $config,
+ protected IEventLogger $eventLogger,
private ContainerInterface $container,
- private IAppManager $appManager,
+ protected IAppManager $appManager,
) {
$baseUrl = \OC::$WEBROOT;
if (!($config->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true')) {
@@ -74,6 +74,14 @@ class Router implements IRouter {
$this->root = $this->getCollection('root');
}
+ public function setContext(RequestContext $context): void {
+ $this->context = $context;
+ }
+
+ public function getRouteCollection() {
+ return $this->root;
+ }
+
/**
* Get the files to load the routes from
*
@@ -82,7 +90,7 @@ class Router implements IRouter {
public function getRoutingFiles() {
if ($this->routingFiles === null) {
$this->routingFiles = [];
- foreach (\OC_APP::getEnabledApps() as $app) {
+ foreach ($this->appManager->getEnabledApps() as $app) {
try {
$appPath = $this->appManager->getAppPath($app);
$file = $appPath . '/appinfo/routes.php';
@@ -102,7 +110,7 @@ class Router implements IRouter {
*
* @param null|string $app
*/
- public function loadRoutes($app = null) {
+ public function loadRoutes(?string $app = null, bool $skipLoadingCore = false): void {
if (is_string($app)) {
$app = $this->appManager->cleanAppId($app);
}
@@ -116,9 +124,11 @@ class Router implements IRouter {
$this->loaded = true;
$routingFiles = $this->getRoutingFiles();
- foreach (\OC_App::getEnabledApps() as $enabledApp) {
+ $this->eventLogger->start('route:load:attributes', 'Loading Routes from attributes');
+ foreach ($this->appManager->getEnabledApps() as $enabledApp) {
$this->loadAttributeRoutes($enabledApp);
}
+ $this->eventLogger->end('route:load:attributes');
} else {
if (isset($this->loadedApps[$app])) {
return;
@@ -140,6 +150,7 @@ class Router implements IRouter {
}
}
+ $this->eventLogger->start('route:load:files', 'Loading Routes from files');
foreach ($routingFiles as $app => $file) {
if (!isset($this->loadedApps[$app])) {
if (!$this->appManager->isAppLoaded($app)) {
@@ -160,12 +171,13 @@ class Router implements IRouter {
$this->root->addCollection($collection);
}
}
+ $this->eventLogger->end('route:load:files');
- if (!isset($this->loadedApps['core'])) {
+ if (!$skipLoadingCore && !isset($this->loadedApps['core'])) {
$this->loadedApps['core'] = true;
$this->useCollection('root');
$this->setupRoutes($this->getAttributeRoutes('core'), 'core');
- require __DIR__ . '/../../../core/routes.php';
+ $this->requireRouteFile(__DIR__ . '/../../../core/routes.php', 'core');
// Also add the OCS collection
$collection = $this->getCollection('root.ocs');
@@ -265,6 +277,7 @@ class Router implements IRouter {
$this->loadRoutes();
}
+ $this->eventLogger->start('route:url:match', 'Symfony url matcher call');
$matcher = new UrlMatcher($this->root, $this->context);
try {
$parameters = $matcher->match($url);
@@ -283,6 +296,7 @@ class Router implements IRouter {
throw $e;
}
}
+ $this->eventLogger->end('route:url:match');
$this->eventLogger->end('route:match');
return $parameters;
@@ -306,17 +320,11 @@ class Router implements IRouter {
$application = $this->getApplicationClass($caller[0]);
\OC\AppFramework\App::main($caller[1], $caller[2], $application->getContainer(), $parameters);
} elseif (isset($parameters['action'])) {
- $action = $parameters['action'];
- if (!is_callable($action)) {
- throw new \Exception('not a callable action');
- }
- unset($parameters['action']);
- unset($parameters['caller']);
- $this->eventLogger->start('route:run:call', 'Run callable route');
- call_user_func($action, $parameters);
- $this->eventLogger->end('route:run:call');
+ $this->logger->warning('Deprecated action route used', ['parameters' => $parameters]);
+ $this->callLegacyActionRoute($parameters);
} elseif (isset($parameters['file'])) {
- include $parameters['file'];
+ $this->logger->debug('Deprecated file route used', ['parameters' => $parameters]);
+ $this->includeLegacyFileRoute($parameters);
} else {
throw new \Exception('no action available');
}
@@ -324,6 +332,32 @@ class Router implements IRouter {
}
/**
+ * @param array{file:mixed, ...} $parameters
+ */
+ protected function includeLegacyFileRoute(array $parameters): void {
+ $param = $parameters;
+ unset($param['_route']);
+ $_GET = array_merge($_GET, $param);
+ unset($param);
+ require_once $parameters['file'];
+ }
+
+ /**
+ * @param array{action:mixed, ...} $parameters
+ */
+ protected function callLegacyActionRoute(array $parameters): void {
+ $action = $parameters['action'];
+ if (!is_callable($action)) {
+ throw new \Exception('not a callable action');
+ }
+ unset($parameters['action']);
+ unset($parameters['caller']);
+ $this->eventLogger->start('route:run:call', 'Run callable route');
+ call_user_func($action, $parameters);
+ $this->eventLogger->end('route:run:call');
+ }
+
+ /**
* Get the url generator
*
* @return \Symfony\Component\Routing\Generator\UrlGenerator
@@ -486,7 +520,7 @@ class Router implements IRouter {
* @param string $file the route file location to include
* @param string $appName
*/
- private function requireRouteFile($file, $appName) {
+ protected function requireRouteFile(string $file, string $appName): void {
$this->setupRoutes(include $file, $appName);
}
diff --git a/lib/private/Security/Bruteforce/Throttler.php b/lib/private/Security/Bruteforce/Throttler.php
index 21d50848641..574f6c80c3f 100644
--- a/lib/private/Security/Bruteforce/Throttler.php
+++ b/lib/private/Security/Bruteforce/Throttler.php
@@ -127,6 +127,13 @@ class Throttler implements IThrottler {
*/
public function getDelay(string $ip, string $action = ''): int {
$attempts = $this->getAttempts($ip, $action);
+ return $this->calculateDelay($attempts);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function calculateDelay(int $attempts): int {
if ($attempts === 0) {
return 0;
}
@@ -199,25 +206,31 @@ class Throttler implements IThrottler {
* {@inheritDoc}
*/
public function sleepDelayOrThrowOnMax(string $ip, string $action = ''): int {
- $delay = $this->getDelay($ip, $action);
- if (($delay === self::MAX_DELAY_MS) && $this->getAttempts($ip, $action, 0.5) > $this->config->getSystemValueInt('auth.bruteforce.max-attempts', self::MAX_ATTEMPTS)) {
- $this->logger->info('IP address blocked because it reached the maximum failed attempts in the last 30 minutes [action: {action}, ip: {ip}]', [
- 'action' => $action,
- 'ip' => $ip,
- ]);
- // If the ip made too many attempts within the last 30 mins we don't execute anymore
- throw new MaxDelayReached('Reached maximum delay');
- }
- if ($delay > 100) {
- $this->logger->info('IP address throttled because it reached the attempts limit in the last 30 minutes [action: {action}, delay: {delay}, ip: {ip}]', [
+ $maxAttempts = $this->config->getSystemValueInt('auth.bruteforce.max-attempts', self::MAX_ATTEMPTS);
+ $attempts = $this->getAttempts($ip, $action);
+ if ($attempts > $maxAttempts) {
+ $attempts30mins = $this->getAttempts($ip, $action, 0.5);
+ if ($attempts30mins > $maxAttempts) {
+ $this->logger->info('IP address blocked because it reached the maximum failed attempts in the last 30 minutes [action: {action}, attempts: {attempts}, ip: {ip}]', [
+ 'action' => $action,
+ 'ip' => $ip,
+ 'attempts' => $attempts30mins,
+ ]);
+ // If the ip made too many attempts within the last 30 mins we don't execute anymore
+ throw new MaxDelayReached('Reached maximum delay');
+ }
+
+ $this->logger->info('IP address throttled because it reached the attempts limit in the last 12 hours [action: {action}, attempts: {attempts}, ip: {ip}]', [
'action' => $action,
'ip' => $ip,
- 'delay' => $delay,
+ 'attempts' => $attempts,
]);
}
- if (!$this->config->getSystemValueBool('auth.bruteforce.protection.testing')) {
- usleep($delay * 1000);
+
+ if ($attempts > 0) {
+ return $this->calculateDelay($attempts);
}
- return $delay;
+
+ return 0;
}
}
diff --git a/lib/private/Security/Normalizer/IpAddress.php b/lib/private/Security/Normalizer/IpAddress.php
index b3793685a24..4d33a7bd632 100644
--- a/lib/private/Security/Normalizer/IpAddress.php
+++ b/lib/private/Security/Normalizer/IpAddress.php
@@ -42,8 +42,15 @@ class IpAddress {
$maskSize = min(64, $config->getSystemValueInt('security.ipv6_normalized_subnet_size', 56));
$maskSize = max(32, $maskSize);
if (PHP_INT_SIZE === 4) {
+ if ($maskSize === 64) {
+ $value = -1;
+ } elseif ($maskSize === 63) {
+ $value = PHP_INT_MAX;
+ } else {
+ $value = (1 << $maskSize - 32) - 1;
+ }
// as long as we support 32bit PHP we cannot use the `P` pack formatter (and not overflow 32bit integer)
- $mask = pack('VVVV', 0xFFFF, $maskSize === 64 ? 0xFFFF : ((1 << $maskSize - 32) - 1), 0, 0);
+ $mask = pack('VVVV', -1, $value, 0, 0);
} else {
$mask = pack('VVP', (1 << 32) - 1, (1 << $maskSize - 32) - 1, 0);
}
diff --git a/lib/private/Security/RateLimiting/Limiter.php b/lib/private/Security/RateLimiting/Limiter.php
index b7ac26d9132..316becfa009 100644
--- a/lib/private/Security/RateLimiting/Limiter.php
+++ b/lib/private/Security/RateLimiting/Limiter.php
@@ -13,10 +13,12 @@ use OC\Security\RateLimiting\Backend\IBackend;
use OC\Security\RateLimiting\Exception\RateLimitExceededException;
use OCP\IUser;
use OCP\Security\RateLimiting\ILimiter;
+use Psr\Log\LoggerInterface;
class Limiter implements ILimiter {
public function __construct(
private IBackend $backend,
+ private LoggerInterface $logger,
) {
}
@@ -32,6 +34,11 @@ class Limiter implements ILimiter {
): void {
$existingAttempts = $this->backend->getAttempts($methodIdentifier, $userIdentifier);
if ($existingAttempts >= $limit) {
+ $this->logger->info('Request blocked because it exceeds the rate limit [method: {method}, limit: {limit}, period: {period}]', [
+ 'method' => $methodIdentifier,
+ 'limit' => $limit,
+ 'period' => $period,
+ ]);
throw new RateLimitExceededException();
}
diff --git a/lib/private/Server.php b/lib/private/Server.php
index 545ceacbe81..c78decd90cb 100644
--- a/lib/private/Server.php
+++ b/lib/private/Server.php
@@ -1,4 +1,5 @@
<?php
+
/**
* SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
@@ -55,6 +56,7 @@ use OC\Files\Mount\RootMountProvider;
use OC\Files\Node\HookConnector;
use OC\Files\Node\LazyRoot;
use OC\Files\Node\Root;
+use OC\Files\ObjectStore\PrimaryObjectStoreConfig;
use OC\Files\SetupManager;
use OC\Files\Storage\StorageFactory;
use OC\Files\Template\TemplateManager;
@@ -124,10 +126,6 @@ use OC\User\DisplayNameCache;
use OC\User\Listeners\BeforeUserDeletedListener;
use OC\User\Listeners\UserChangedListener;
use OC\User\Session;
-use OCA\Files_External\Service\BackendService;
-use OCA\Files_External\Service\GlobalStoragesService;
-use OCA\Files_External\Service\UserGlobalStoragesService;
-use OCA\Files_External\Service\UserStoragesService;
use OCA\Theming\ImageManager;
use OCA\Theming\Service\BackgroundService;
use OCA\Theming\ThemingDefaults;
@@ -138,7 +136,6 @@ use OCP\AppFramework\Utility\ITimeFactory;
use OCP\Authentication\LoginCredentials\IStore;
use OCP\Authentication\Token\IProvider as OCPIProvider;
use OCP\BackgroundJob\IJobList;
-use OCP\Collaboration\AutoComplete\IManager;
use OCP\Collaboration\Reference\IReferenceManager;
use OCP\Command\IBus;
use OCP\Comments\ICommentsManager;
@@ -189,7 +186,6 @@ use OCP\IRequest;
use OCP\IRequestId;
use OCP\IServerContainer;
use OCP\ISession;
-use OCP\ITagManager;
use OCP\ITempManager;
use OCP\IURLGenerator;
use OCP\IUserManager;
@@ -201,6 +197,7 @@ use OCP\Lock\ILockingProvider;
use OCP\Lockdown\ILockdownManager;
use OCP\Log\ILogFactory;
use OCP\Mail\IMailer;
+use OCP\OCM\ICapabilityAwareOCMProvider;
use OCP\OCM\IOCMDiscoveryService;
use OCP\OCM\IOCMProvider;
use OCP\Preview\IMimeIconProvider;
@@ -212,7 +209,6 @@ use OCP\RichObjectStrings\IRichTextFormatter;
use OCP\RichObjectStrings\IValidator;
use OCP\Route\IRouter;
use OCP\Security\Bruteforce\IThrottler;
-use OCP\Security\IContentSecurityPolicyManager;
use OCP\Security\ICredentialsManager;
use OCP\Security\ICrypto;
use OCP\Security\IHasher;
@@ -326,7 +322,7 @@ class Server extends ServerContainer implements IServerContainer {
return new Profiler($c->get(SystemConfig::class));
});
- $this->registerService(\OCP\Encryption\IManager::class, function (Server $c): Encryption\Manager {
+ $this->registerService(Encryption\Manager::class, function (Server $c): Encryption\Manager {
$view = new View();
$util = new Encryption\Util(
$view,
@@ -343,6 +339,7 @@ class Server extends ServerContainer implements IServerContainer {
new ArrayCache()
);
});
+ $this->registerAlias(\OCP\Encryption\IManager::class, Encryption\Manager::class);
$this->registerService(IFile::class, function (ContainerInterface $c) {
$util = new Encryption\Util(
@@ -575,6 +572,7 @@ class Server extends ServerContainer implements IServerContainer {
$this->registerAlias(IAppConfig::class, \OC\AppConfig::class);
$this->registerAlias(IUserConfig::class, \OC\Config\UserConfig::class);
+ $this->registerAlias(IAppManager::class, AppManager::class);
$this->registerService(IFactory::class, function (Server $c) {
return new \OC\L10N\Factory(
@@ -611,7 +609,7 @@ class Server extends ServerContainer implements IServerContainer {
$prefixClosure = function () use ($logQuery, $serverVersion): ?string {
if (!$logQuery) {
try {
- $v = \OCP\Server::get(IAppConfig::class)->getAppInstalledVersions();
+ $v = \OCP\Server::get(IAppConfig::class)->getAppInstalledVersions(true);
} catch (\Doctrine\DBAL\Exception $e) {
// Database service probably unavailable
// Probably related to https://github.com/nextcloud/server/issues/37424
@@ -626,7 +624,7 @@ class Server extends ServerContainer implements IServerContainer {
];
}
$v['core'] = implode(',', $serverVersion->getVersion());
- $version = implode(',', $v);
+ $version = implode(',', array_keys($v)) . implode(',', $v);
$instanceId = \OC_Util::getInstanceId();
$path = \OC::$SERVERROOT;
return md5($instanceId . '-' . $version . '-' . $path);
@@ -783,21 +781,6 @@ class Server extends ServerContainer implements IServerContainer {
});
$this->registerAlias(ITempManager::class, TempManager::class);
-
- $this->registerService(AppManager::class, function (ContainerInterface $c) {
- // TODO: use auto-wiring
- return new \OC\App\AppManager(
- $c->get(IUserSession::class),
- $c->get(\OCP\IConfig::class),
- $c->get(IGroupManager::class),
- $c->get(ICacheFactory::class),
- $c->get(IEventDispatcher::class),
- $c->get(LoggerInterface::class),
- $c->get(ServerVersion::class),
- );
- });
- $this->registerAlias(IAppManager::class, AppManager::class);
-
$this->registerAlias(IDateTimeZone::class, DateTimeZone::class);
$this->registerService(IDateTimeFormatter::class, function (Server $c) {
@@ -826,10 +809,11 @@ class Server extends ServerContainer implements IServerContainer {
$config = $c->get(\OCP\IConfig::class);
$logger = $c->get(LoggerInterface::class);
+ $objectStoreConfig = $c->get(PrimaryObjectStoreConfig::class);
$manager->registerProvider(new CacheMountProvider($config));
$manager->registerHomeProvider(new LocalHomeMountProvider());
- $manager->registerHomeProvider(new ObjectHomeMountProvider($config));
- $manager->registerRootProvider(new RootMountProvider($config, $c->get(LoggerInterface::class)));
+ $manager->registerHomeProvider(new ObjectHomeMountProvider($objectStoreConfig));
+ $manager->registerRootProvider(new RootMountProvider($objectStoreConfig, $config));
$manager->registerRootProvider(new ObjectStorePreviewCacheMountProvider($logger, $config));
return $manager;
@@ -1125,7 +1109,7 @@ class Server extends ServerContainer implements IServerContainer {
$config = $c->get(\OCP\IConfig::class);
$factoryClass = $config->getSystemValue('sharing.managerFactory', ProviderFactory::class);
/** @var \OCP\Share\IProviderFactory $factory */
- return new $factoryClass($this);
+ return $c->get($factoryClass);
});
$this->registerAlias(\OCP\Share\IManager::class, \OC\Share20\Manager::class);
@@ -1276,7 +1260,8 @@ class Server extends ServerContainer implements IServerContainer {
$this->registerAlias(IPhoneNumberUtil::class, PhoneNumberUtil::class);
- $this->registerAlias(IOCMProvider::class, OCMProvider::class);
+ $this->registerAlias(ICapabilityAwareOCMProvider::class, OCMProvider::class);
+ $this->registerDeprecatedAlias(IOCMProvider::class, OCMProvider::class);
$this->registerAlias(ISetupCheckManager::class, SetupCheckManager::class);
@@ -1305,30 +1290,6 @@ class Server extends ServerContainer implements IServerContainer {
$hookConnector->viewToNode();
}
- /**
- * @return \OCP\Calendar\IManager
- * @deprecated 20.0.0
- */
- public function getCalendarManager() {
- return $this->get(\OC\Calendar\Manager::class);
- }
-
- /**
- * @return \OCP\Calendar\Resource\IManager
- * @deprecated 20.0.0
- */
- public function getCalendarResourceBackendManager() {
- return $this->get(\OC\Calendar\Resource\Manager::class);
- }
-
- /**
- * @return \OCP\Calendar\Room\IManager
- * @deprecated 20.0.0
- */
- public function getCalendarRoomBackendManager() {
- return $this->get(\OC\Calendar\Room\Manager::class);
- }
-
private function connectDispatcher(): void {
/** @var IEventDispatcher $eventDispatcher */
$eventDispatcher = $this->get(IEventDispatcher::class);
@@ -1366,14 +1327,6 @@ class Server extends ServerContainer implements IServerContainer {
}
/**
- * @return \OCP\Encryption\Keys\IStorage
- * @deprecated 20.0.0
- */
- public function getEncryptionKeyStorage() {
- return $this->get(IStorage::class);
- }
-
- /**
* The current request object holding all information about the request
* currently being processed is returned from this method.
* In case the current execution was not initiated by a web request null is returned
@@ -1386,61 +1339,6 @@ class Server extends ServerContainer implements IServerContainer {
}
/**
- * Returns the preview manager which can create preview images for a given file
- *
- * @return IPreview
- * @deprecated 20.0.0
- */
- public function getPreviewManager() {
- return $this->get(IPreview::class);
- }
-
- /**
- * Returns the tag manager which can get and set tags for different object types
- *
- * @see \OCP\ITagManager::load()
- * @return ITagManager
- * @deprecated 20.0.0
- */
- public function getTagManager() {
- return $this->get(ITagManager::class);
- }
-
- /**
- * Returns the system-tag manager
- *
- * @return ISystemTagManager
- *
- * @since 9.0.0
- * @deprecated 20.0.0
- */
- public function getSystemTagManager() {
- return $this->get(ISystemTagManager::class);
- }
-
- /**
- * Returns the system-tag object mapper
- *
- * @return ISystemTagObjectMapper
- *
- * @since 9.0.0
- * @deprecated 20.0.0
- */
- public function getSystemTagObjectMapper() {
- return $this->get(ISystemTagObjectMapper::class);
- }
-
- /**
- * Returns the avatar manager, used for avatar functionality
- *
- * @return IAvatarManager
- * @deprecated 20.0.0
- */
- public function getAvatarManager() {
- return $this->get(IAvatarManager::class);
- }
-
- /**
* Returns the root folder of ownCloud's data directory
*
* @return IRootFolder
@@ -1524,22 +1422,6 @@ class Server extends ServerContainer implements IServerContainer {
}
/**
- * @return \OC\Authentication\TwoFactorAuth\Manager
- * @deprecated 20.0.0
- */
- public function getTwoFactorAuthManager() {
- return $this->get(\OC\Authentication\TwoFactorAuth\Manager::class);
- }
-
- /**
- * @return \OC\NavigationManager
- * @deprecated 20.0.0
- */
- public function getNavigationManager() {
- return $this->get(INavigationManager::class);
- }
-
- /**
* @return \OCP\IConfig
* @deprecated 20.0.0
*/
@@ -1556,16 +1438,6 @@ class Server extends ServerContainer implements IServerContainer {
}
/**
- * Returns the app config manager
- *
- * @return IAppConfig
- * @deprecated 20.0.0
- */
- public function getAppConfig() {
- return $this->get(IAppConfig::class);
- }
-
- /**
* @return IFactory
* @deprecated 20.0.0
*/
@@ -1594,14 +1466,6 @@ class Server extends ServerContainer implements IServerContainer {
}
/**
- * @return AppFetcher
- * @deprecated 20.0.0
- */
- public function getAppFetcher() {
- return $this->get(AppFetcher::class);
- }
-
- /**
* Returns an ICache instance. Since 8.1.0 it returns a fake cache. Use
* getMemCacheFactory() instead.
*
@@ -1623,17 +1487,6 @@ class Server extends ServerContainer implements IServerContainer {
}
/**
- * Returns an \OC\RedisFactory instance
- *
- * @return \OC\RedisFactory
- * @deprecated 20.0.0
- */
- public function getGetRedisFactory() {
- return $this->get('RedisFactory');
- }
-
-
- /**
* Returns the current session
*
* @return \OCP\IDBConnection
@@ -1664,25 +1517,6 @@ class Server extends ServerContainer implements IServerContainer {
}
/**
- * @return ILogFactory
- * @throws \OCP\AppFramework\QueryException
- * @deprecated 20.0.0
- */
- public function getLogFactory() {
- return $this->get(ILogFactory::class);
- }
-
- /**
- * Returns a router for generating and matching urls
- *
- * @return IRouter
- * @deprecated 20.0.0
- */
- public function getRouter() {
- return $this->get(IRouter::class);
- }
-
- /**
* Returns a SecureRandom instance
*
* @return \OCP\Security\ISecureRandom
@@ -1713,16 +1547,6 @@ class Server extends ServerContainer implements IServerContainer {
}
/**
- * Returns a CredentialsManager instance
- *
- * @return ICredentialsManager
- * @deprecated 20.0.0
- */
- public function getCredentialsManager() {
- return $this->get(ICredentialsManager::class);
- }
-
- /**
* Get the certificate manager
*
* @return \OCP\ICertificateManager
@@ -1732,40 +1556,6 @@ class Server extends ServerContainer implements IServerContainer {
}
/**
- * Returns an instance of the HTTP client service
- *
- * @return IClientService
- * @deprecated 20.0.0
- */
- public function getHTTPClientService() {
- return $this->get(IClientService::class);
- }
-
- /**
- * Get the active event logger
- *
- * The returned logger only logs data when debug mode is enabled
- *
- * @return IEventLogger
- * @deprecated 20.0.0
- */
- public function getEventLogger() {
- return $this->get(IEventLogger::class);
- }
-
- /**
- * Get the active query logger
- *
- * The returned logger only logs data when debug mode is enabled
- *
- * @return IQueryLogger
- * @deprecated 20.0.0
- */
- public function getQueryLogger() {
- return $this->get(IQueryLogger::class);
- }
-
- /**
* Get the manager for temporary files and folders
*
* @return \OCP\ITempManager
@@ -1806,66 +1596,6 @@ class Server extends ServerContainer implements IServerContainer {
}
/**
- * @return \OC\OCSClient
- * @deprecated 20.0.0
- */
- public function getOcsClient() {
- return $this->get('OcsClient');
- }
-
- /**
- * @return IDateTimeZone
- * @deprecated 20.0.0
- */
- public function getDateTimeZone() {
- return $this->get(IDateTimeZone::class);
- }
-
- /**
- * @return IDateTimeFormatter
- * @deprecated 20.0.0
- */
- public function getDateTimeFormatter() {
- return $this->get(IDateTimeFormatter::class);
- }
-
- /**
- * @return IMountProviderCollection
- * @deprecated 20.0.0
- */
- public function getMountProviderCollection() {
- return $this->get(IMountProviderCollection::class);
- }
-
- /**
- * Get the IniWrapper
- *
- * @return IniGetWrapper
- * @deprecated 20.0.0
- */
- public function getIniWrapper() {
- return $this->get(IniGetWrapper::class);
- }
-
- /**
- * @return \OCP\Command\IBus
- * @deprecated 20.0.0
- */
- public function getCommandBus() {
- return $this->get(IBus::class);
- }
-
- /**
- * Get the trusted domain helper
- *
- * @return TrustedDomainHelper
- * @deprecated 20.0.0
- */
- public function getTrustedDomainHelper() {
- return $this->get(TrustedDomainHelper::class);
- }
-
- /**
* Get the locking provider
*
* @return ILockingProvider
@@ -1877,22 +1607,6 @@ class Server extends ServerContainer implements IServerContainer {
}
/**
- * @return IMountManager
- * @deprecated 20.0.0
- **/
- public function getMountManager() {
- return $this->get(IMountManager::class);
- }
-
- /**
- * @return IUserMountCache
- * @deprecated 20.0.0
- */
- public function getUserMountCache() {
- return $this->get(IUserMountCache::class);
- }
-
- /**
* Get the MimeTypeDetector
*
* @return IMimeTypeDetector
@@ -1913,16 +1627,6 @@ class Server extends ServerContainer implements IServerContainer {
}
/**
- * Get the manager of all the capabilities
- *
- * @return CapabilitiesManager
- * @deprecated 20.0.0
- */
- public function getCapabilitiesManager() {
- return $this->get(CapabilitiesManager::class);
- }
-
- /**
* Get the Notification Manager
*
* @return \OCP\Notification\IManager
@@ -1934,14 +1638,6 @@ class Server extends ServerContainer implements IServerContainer {
}
/**
- * @return ICommentsManager
- * @deprecated 20.0.0
- */
- public function getCommentsManager() {
- return $this->get(ICommentsManager::class);
- }
-
- /**
* @return \OCA\Theming\ThemingDefaults
* @deprecated 20.0.0
*/
@@ -1958,14 +1654,6 @@ class Server extends ServerContainer implements IServerContainer {
}
/**
- * @return \OC\Session\CryptoWrapper
- * @deprecated 20.0.0
- */
- public function getSessionCryptoWrapper() {
- return $this->get('CryptoWrapper');
- }
-
- /**
* @return CsrfTokenManager
* @deprecated 20.0.0
*/
@@ -1974,22 +1662,6 @@ class Server extends ServerContainer implements IServerContainer {
}
/**
- * @return IThrottler
- * @deprecated 20.0.0
- */
- public function getBruteForceThrottler() {
- return $this->get(Throttler::class);
- }
-
- /**
- * @return IContentSecurityPolicyManager
- * @deprecated 20.0.0
- */
- public function getContentSecurityPolicyManager() {
- return $this->get(ContentSecurityPolicyManager::class);
- }
-
- /**
* @return ContentSecurityPolicyNonceManager
* @deprecated 20.0.0
*/
@@ -1998,80 +1670,6 @@ class Server extends ServerContainer implements IServerContainer {
}
/**
- * Not a public API as of 8.2, wait for 9.0
- *
- * @return \OCA\Files_External\Service\BackendService
- * @deprecated 20.0.0
- */
- public function getStoragesBackendService() {
- return $this->get(BackendService::class);
- }
-
- /**
- * Not a public API as of 8.2, wait for 9.0
- *
- * @return \OCA\Files_External\Service\GlobalStoragesService
- * @deprecated 20.0.0
- */
- public function getGlobalStoragesService() {
- return $this->get(GlobalStoragesService::class);
- }
-
- /**
- * Not a public API as of 8.2, wait for 9.0
- *
- * @return \OCA\Files_External\Service\UserGlobalStoragesService
- * @deprecated 20.0.0
- */
- public function getUserGlobalStoragesService() {
- return $this->get(UserGlobalStoragesService::class);
- }
-
- /**
- * Not a public API as of 8.2, wait for 9.0
- *
- * @return \OCA\Files_External\Service\UserStoragesService
- * @deprecated 20.0.0
- */
- public function getUserStoragesService() {
- return $this->get(UserStoragesService::class);
- }
-
- /**
- * @return \OCP\Share\IManager
- * @deprecated 20.0.0
- */
- public function getShareManager() {
- return $this->get(\OCP\Share\IManager::class);
- }
-
- /**
- * @return \OCP\Collaboration\Collaborators\ISearch
- * @deprecated 20.0.0
- */
- public function getCollaboratorSearch() {
- return $this->get(\OCP\Collaboration\Collaborators\ISearch::class);
- }
-
- /**
- * @return \OCP\Collaboration\AutoComplete\IManager
- * @deprecated 20.0.0
- */
- public function getAutoCompleteManager() {
- return $this->get(IManager::class);
- }
-
- /**
- * Returns the LDAP Provider
- *
- * @return \OCP\LDAP\ILDAPProvider
- * @deprecated 20.0.0
- */
- public function getLDAPProvider() {
- return $this->get('LDAPProvider');
- }
-
- /**
* @return \OCP\Settings\IManager
* @deprecated 20.0.0
*/
@@ -2090,14 +1688,6 @@ class Server extends ServerContainer implements IServerContainer {
}
/**
- * @return \OCP\Lockdown\ILockdownManager
- * @deprecated 20.0.0
- */
- public function getLockdownManager() {
- return $this->get('LockdownManager');
- }
-
- /**
* @return \OCP\Federation\ICloudIdManager
* @deprecated 20.0.0
*/
@@ -2105,65 +1695,6 @@ class Server extends ServerContainer implements IServerContainer {
return $this->get(ICloudIdManager::class);
}
- /**
- * @return \OCP\GlobalScale\IConfig
- * @deprecated 20.0.0
- */
- public function getGlobalScaleConfig() {
- return $this->get(IConfig::class);
- }
-
- /**
- * @return \OCP\Federation\ICloudFederationProviderManager
- * @deprecated 20.0.0
- */
- public function getCloudFederationProviderManager() {
- return $this->get(ICloudFederationProviderManager::class);
- }
-
- /**
- * @return \OCP\Remote\Api\IApiFactory
- * @deprecated 20.0.0
- */
- public function getRemoteApiFactory() {
- return $this->get(IApiFactory::class);
- }
-
- /**
- * @return \OCP\Federation\ICloudFederationFactory
- * @deprecated 20.0.0
- */
- public function getCloudFederationFactory() {
- return $this->get(ICloudFederationFactory::class);
- }
-
- /**
- * @return \OCP\Remote\IInstanceFactory
- * @deprecated 20.0.0
- */
- public function getRemoteInstanceFactory() {
- return $this->get(IInstanceFactory::class);
- }
-
- /**
- * @return IStorageFactory
- * @deprecated 20.0.0
- */
- public function getStorageFactory() {
- return $this->get(IStorageFactory::class);
- }
-
- /**
- * Get the Preview GeneratorHelper
- *
- * @return GeneratorHelper
- * @since 17.0.0
- * @deprecated 20.0.0
- */
- public function getGeneratorHelper() {
- return $this->get(\OC\Preview\GeneratorHelper::class);
- }
-
private function registerDeprecatedAlias(string $alias, string $target) {
$this->registerService($alias, function (ContainerInterface $container) use ($target, $alias) {
try {
diff --git a/lib/private/ServerContainer.php b/lib/private/ServerContainer.php
index 9f887b2d48a..b5bcbdaeb6f 100644
--- a/lib/private/ServerContainer.php
+++ b/lib/private/ServerContainer.php
@@ -128,18 +128,17 @@ class ServerContainer extends SimpleContainer {
} catch (QueryException $e) {
// Continue with general autoloading then
}
- }
-
- // In case the service starts with OCA\ we try to find the service in
- // the apps container first.
- if (($appContainer = $this->getAppContainerForService($name)) !== null) {
- try {
- return $appContainer->queryNoFallback($name);
- } catch (QueryException $e) {
- // Didn't find the service or the respective app container
- // In this case the service won't be part of the core container,
- // so we can throw directly
- throw $e;
+ // In case the service starts with OCA\ we try to find the service in
+ // the apps container first.
+ if (($appContainer = $this->getAppContainerForService($name)) !== null) {
+ try {
+ return $appContainer->queryNoFallback($name);
+ } catch (QueryException $e) {
+ // Didn't find the service or the respective app container
+ // In this case the service won't be part of the core container,
+ // so we can throw directly
+ throw $e;
+ }
}
} elseif (str_starts_with($name, 'OC\\Settings\\') && substr_count($name, '\\') >= 3) {
$segments = explode('\\', $name);
diff --git a/lib/private/Session/CryptoWrapper.php b/lib/private/Session/CryptoWrapper.php
index 380c699d32d..40c2ba6adf3 100644
--- a/lib/private/Session/CryptoWrapper.php
+++ b/lib/private/Session/CryptoWrapper.php
@@ -59,7 +59,7 @@ class CryptoWrapper {
[
'expires' => 0,
'path' => $webRoot,
- 'domain' => '',
+ 'domain' => \OCP\Server::get(\OCP\IConfig::class)->getSystemValueString('cookie_domain'),
'secure' => $secureCookie,
'httponly' => true,
'samesite' => 'Lax',
diff --git a/lib/private/Settings/DeclarativeManager.php b/lib/private/Settings/DeclarativeManager.php
index dea0c678f20..534b4b19984 100644
--- a/lib/private/Settings/DeclarativeManager.php
+++ b/lib/private/Settings/DeclarativeManager.php
@@ -15,6 +15,7 @@ use OCP\IAppConfig;
use OCP\IConfig;
use OCP\IGroupManager;
use OCP\IUser;
+use OCP\Security\ICrypto;
use OCP\Server;
use OCP\Settings\DeclarativeSettingsTypes;
use OCP\Settings\Events\DeclarativeSettingsGetValueEvent;
@@ -49,6 +50,7 @@ class DeclarativeManager implements IDeclarativeManager {
private IConfig $config,
private IAppConfig $appConfig,
private LoggerInterface $logger,
+ private ICrypto $crypto,
) {
}
@@ -266,7 +268,7 @@ class DeclarativeManager implements IDeclarativeManager {
$this->eventDispatcher->dispatchTyped(new DeclarativeSettingsSetValueEvent($user, $app, $formId, $fieldId, $value));
break;
case DeclarativeSettingsTypes::STORAGE_TYPE_INTERNAL:
- $this->saveInternalValue($user, $app, $fieldId, $value);
+ $this->saveInternalValue($user, $app, $formId, $fieldId, $value);
break;
default:
throw new Exception('Unknown storage type "' . $storageType . '"');
@@ -290,18 +292,52 @@ class DeclarativeManager implements IDeclarativeManager {
private function getInternalValue(IUser $user, string $app, string $formId, string $fieldId): mixed {
$sectionType = $this->getSectionType($app, $fieldId);
$defaultValue = $this->getDefaultValue($app, $formId, $fieldId);
+
+ $field = $this->getSchemaField($app, $formId, $fieldId);
+ $isSensitive = $field !== null && isset($field['sensitive']) && $field['sensitive'] === true;
+
switch ($sectionType) {
case DeclarativeSettingsTypes::SECTION_TYPE_ADMIN:
- return $this->config->getAppValue($app, $fieldId, $defaultValue);
+ $value = $this->config->getAppValue($app, $fieldId, $defaultValue);
+ break;
case DeclarativeSettingsTypes::SECTION_TYPE_PERSONAL:
- return $this->config->getUserValue($user->getUID(), $app, $fieldId, $defaultValue);
+ $value = $this->config->getUserValue($user->getUID(), $app, $fieldId, $defaultValue);
+ break;
default:
throw new Exception('Unknown section type "' . $sectionType . '"');
}
+ if ($isSensitive && $value !== '') {
+ try {
+ $value = $this->crypto->decrypt($value);
+ } catch (Exception $e) {
+ $this->logger->warning('Failed to decrypt sensitive value for field {field} in app {app}: {message}', [
+ 'field' => $fieldId,
+ 'app' => $app,
+ 'message' => $e->getMessage(),
+ ]);
+ $value = $defaultValue;
+ }
+ }
+ return $value;
}
- private function saveInternalValue(IUser $user, string $app, string $fieldId, mixed $value): void {
+ private function saveInternalValue(IUser $user, string $app, string $formId, string $fieldId, mixed $value): void {
$sectionType = $this->getSectionType($app, $fieldId);
+
+ $field = $this->getSchemaField($app, $formId, $fieldId);
+ if ($field !== null && isset($field['sensitive']) && $field['sensitive'] === true && $value !== '' && $value !== 'dummySecret') {
+ try {
+ $value = $this->crypto->encrypt($value);
+ } catch (Exception $e) {
+ $this->logger->warning('Failed to decrypt sensitive value for field {field} in app {app}: {message}', [
+ 'field' => $fieldId,
+ 'app' => $app,
+ 'message' => $e->getMessage()]
+ );
+ throw new Exception('Failed to encrypt sensitive value');
+ }
+ }
+
switch ($sectionType) {
case DeclarativeSettingsTypes::SECTION_TYPE_ADMIN:
$this->appConfig->setValueString($app, $fieldId, $value);
@@ -314,6 +350,27 @@ class DeclarativeManager implements IDeclarativeManager {
}
}
+ private function getSchemaField(string $app, string $formId, string $fieldId): ?array {
+ $form = $this->getForm($app, $formId);
+ if ($form !== null) {
+ foreach ($form->getSchema()['fields'] as $field) {
+ if ($field['id'] === $fieldId) {
+ return $field;
+ }
+ }
+ }
+ foreach ($this->appSchemas[$app] ?? [] as $schema) {
+ if ($schema['id'] === $formId) {
+ foreach ($schema['fields'] as $field) {
+ if ($field['id'] === $fieldId) {
+ return $field;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
private function getDefaultValue(string $app, string $formId, string $fieldId): mixed {
foreach ($this->appSchemas[$app] as $schema) {
if ($schema['id'] === $formId) {
@@ -391,6 +448,12 @@ class DeclarativeManager implements IDeclarativeManager {
]);
return false;
}
+ if (isset($field['sensitive']) && $field['sensitive'] === true && !in_array($field['type'], [DeclarativeSettingsTypes::TEXT, DeclarativeSettingsTypes::PASSWORD])) {
+ $this->logger->warning('Declarative settings: sensitive field type is supported only for TEXT and PASSWORD types ({app}, {form_id}, {field_id})', [
+ 'app' => $appId, 'form_id' => $formId, 'field_id' => $fieldId,
+ ]);
+ return false;
+ }
if (!$this->validateField($appId, $formId, $field)) {
return false;
}
diff --git a/lib/private/Setup.php b/lib/private/Setup.php
index 6d3021aff71..c8b5060076a 100644
--- a/lib/private/Setup.php
+++ b/lib/private/Setup.php
@@ -14,6 +14,7 @@ use Exception;
use InvalidArgumentException;
use OC\Authentication\Token\PublicKeyTokenProvider;
use OC\Authentication\Token\TokenCleanupJob;
+use OC\Core\BackgroundJobs\GenerateMetadataJob;
use OC\Log\Rotate;
use OC\Preview\BackgroundCleanupJob;
use OC\TextProcessing\RemoveOldTasksBackgroundJob;
@@ -303,11 +304,15 @@ class Setup {
$error = [];
$dbType = $options['dbtype'];
- if (empty($options['adminlogin'])) {
- $error[] = $l->t('Set an admin Login.');
- }
- if (empty($options['adminpass'])) {
- $error[] = $l->t('Set an admin password.');
+ $disableAdminUser = (bool)($options['admindisable'] ?? false);
+
+ if (!$disableAdminUser) {
+ if (empty($options['adminlogin'])) {
+ $error[] = $l->t('Set an admin Login.');
+ }
+ if (empty($options['adminpass'])) {
+ $error[] = $l->t('Set an admin password.');
+ }
}
if (empty($options['directory'])) {
$options['directory'] = \OC::$SERVERROOT . '/data';
@@ -317,8 +322,6 @@ class Setup {
$dbType = 'sqlite';
}
- $username = htmlspecialchars_decode($options['adminlogin']);
- $password = htmlspecialchars_decode($options['adminpass']);
$dataDir = htmlspecialchars_decode($options['directory']);
$class = self::$dbSetupClasses[$dbType];
@@ -374,7 +377,7 @@ class Setup {
$this->outputDebug($output, 'Configuring database');
$dbSetup->initialize($options);
try {
- $dbSetup->setupDatabase($username);
+ $dbSetup->setupDatabase();
} catch (\OC\DatabaseSetupException $e) {
$error[] = [
'error' => $e->getMessage(),
@@ -404,19 +407,22 @@ class Setup {
return $error;
}
- $this->outputDebug($output, 'Create admin account');
-
- // create the admin account and group
$user = null;
- try {
- $user = Server::get(IUserManager::class)->createUser($username, $password);
- if (!$user) {
- $error[] = "Account <$username> could not be created.";
+ if (!$disableAdminUser) {
+ $username = htmlspecialchars_decode($options['adminlogin']);
+ $password = htmlspecialchars_decode($options['adminpass']);
+ $this->outputDebug($output, 'Create admin account');
+
+ try {
+ $user = Server::get(IUserManager::class)->createUser($username, $password);
+ if (!$user) {
+ $error[] = "Account <$username> could not be created.";
+ return $error;
+ }
+ } catch (Exception $exception) {
+ $error[] = $exception->getMessage();
return $error;
}
- } catch (Exception $exception) {
- $error[] = $exception->getMessage();
- return $error;
}
$config = Server::get(IConfig::class);
@@ -431,7 +437,7 @@ class Setup {
}
$group = Server::get(IGroupManager::class)->createGroup('admin');
- if ($group instanceof IGroup) {
+ if ($user !== null && $group instanceof IGroup) {
$group->addUser($user);
}
@@ -463,26 +469,28 @@ class Setup {
$bootstrapCoordinator = Server::get(\OC\AppFramework\Bootstrap\Coordinator::class);
$bootstrapCoordinator->runInitialRegistration();
- // Create a session token for the newly created user
- // The token provider requires a working db, so it's not injected on setup
- /** @var \OC\User\Session $userSession */
- $userSession = Server::get(IUserSession::class);
- $provider = Server::get(PublicKeyTokenProvider::class);
- $userSession->setTokenProvider($provider);
- $userSession->login($username, $password);
- $user = $userSession->getUser();
- if (!$user) {
- $error[] = 'No account found in session.';
- return $error;
- }
- $userSession->createSessionToken($request, $user->getUID(), $username, $password);
+ if (!$disableAdminUser) {
+ // Create a session token for the newly created user
+ // The token provider requires a working db, so it's not injected on setup
+ /** @var \OC\User\Session $userSession */
+ $userSession = Server::get(IUserSession::class);
+ $provider = Server::get(PublicKeyTokenProvider::class);
+ $userSession->setTokenProvider($provider);
+ $userSession->login($username, $password);
+ $user = $userSession->getUser();
+ if (!$user) {
+ $error[] = 'No account found in session.';
+ return $error;
+ }
+ $userSession->createSessionToken($request, $user->getUID(), $username, $password);
- $session = $userSession->getSession();
- $session->set('last-password-confirm', Server::get(ITimeFactory::class)->getTime());
+ $session = $userSession->getSession();
+ $session->set('last-password-confirm', Server::get(ITimeFactory::class)->getTime());
- // Set email for admin
- if (!empty($options['adminemail'])) {
- $user->setSystemEMailAddress($options['adminemail']);
+ // Set email for admin
+ if (!empty($options['adminemail'])) {
+ $user->setSystemEMailAddress($options['adminemail']);
+ }
}
return $error;
@@ -495,6 +503,7 @@ class Setup {
$jobList->add(BackgroundCleanupJob::class);
$jobList->add(RemoveOldTasksBackgroundJob::class);
$jobList->add(CleanupDeletedUsers::class);
+ $jobList->add(GenerateMetadataJob::class);
}
/**
diff --git a/lib/private/Setup/AbstractDatabase.php b/lib/private/Setup/AbstractDatabase.php
index dbbb587206b..ec4ce040090 100644
--- a/lib/private/Setup/AbstractDatabase.php
+++ b/lib/private/Setup/AbstractDatabase.php
@@ -127,10 +127,7 @@ abstract class AbstractDatabase {
return $connection;
}
- /**
- * @param string $username
- */
- abstract public function setupDatabase($username);
+ abstract public function setupDatabase();
public function runMigrations(?IOutput $output = null) {
if (!is_dir(\OC::$SERVERROOT . '/core/Migrations')) {
diff --git a/lib/private/Setup/MySQL.php b/lib/private/Setup/MySQL.php
index 6dd9855d851..1e2dda4c609 100644
--- a/lib/private/Setup/MySQL.php
+++ b/lib/private/Setup/MySQL.php
@@ -16,7 +16,7 @@ use OCP\Security\ISecureRandom;
class MySQL extends AbstractDatabase {
public $dbprettyname = 'MySQL/MariaDB';
- public function setupDatabase($username) {
+ public function setupDatabase() {
//check if the database user has admin right
$connection = $this->connect(['dbname' => null]);
@@ -28,7 +28,7 @@ class MySQL extends AbstractDatabase {
}
if ($this->tryCreateDbUser) {
- $this->createSpecificUser($username, new ConnectionAdapter($connection));
+ $this->createSpecificUser('oc_admin', new ConnectionAdapter($connection));
}
$this->config->setValues([
diff --git a/lib/private/Setup/OCI.php b/lib/private/Setup/OCI.php
index 47e5e5436a5..61c7f968787 100644
--- a/lib/private/Setup/OCI.php
+++ b/lib/private/Setup/OCI.php
@@ -40,7 +40,7 @@ class OCI extends AbstractDatabase {
return $errors;
}
- public function setupDatabase($username) {
+ public function setupDatabase() {
try {
$this->connect();
} catch (\Exception $e) {
diff --git a/lib/private/Setup/PostgreSQL.php b/lib/private/Setup/PostgreSQL.php
index b1cf031e876..9a686db2e54 100644
--- a/lib/private/Setup/PostgreSQL.php
+++ b/lib/private/Setup/PostgreSQL.php
@@ -16,10 +16,9 @@ class PostgreSQL extends AbstractDatabase {
public $dbprettyname = 'PostgreSQL';
/**
- * @param string $username
* @throws \OC\DatabaseSetupException
*/
- public function setupDatabase($username) {
+ public function setupDatabase() {
try {
$connection = $this->connect([
'dbname' => 'postgres'
@@ -46,7 +45,7 @@ class PostgreSQL extends AbstractDatabase {
//use the admin login data for the new database user
//add prefix to the postgresql user name to prevent collisions
- $this->dbUser = 'oc_' . strtolower($username);
+ $this->dbUser = 'oc_admin';
//create a new password so we don't need to store the admin config in the config file
$this->dbPassword = \OC::$server->get(ISecureRandom::class)->generate(30, ISecureRandom::CHAR_ALPHANUMERIC);
diff --git a/lib/private/Setup/Sqlite.php b/lib/private/Setup/Sqlite.php
index 1b90ebd5a5e..b34b1e32ede 100644
--- a/lib/private/Setup/Sqlite.php
+++ b/lib/private/Setup/Sqlite.php
@@ -45,7 +45,7 @@ class Sqlite extends AbstractDatabase {
}
}
- public function setupDatabase($username) {
+ public function setupDatabase() {
$datadir = $this->config->getValue(
'datadirectory',
\OC::$SERVERROOT . '/data'
diff --git a/lib/private/Share20/DefaultShareProvider.php b/lib/private/Share20/DefaultShareProvider.php
index a257bc4f7b5..e1eebe1e450 100644
--- a/lib/private/Share20/DefaultShareProvider.php
+++ b/lib/private/Share20/DefaultShareProvider.php
@@ -5,6 +5,7 @@
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
* SPDX-License-Identifier: AGPL-3.0-only
*/
+
namespace OC\Share20;
use OC\Files\Cache\Cache;
@@ -31,6 +32,7 @@ use OCP\Share\IAttributes;
use OCP\Share\IManager;
use OCP\Share\IShare;
use OCP\Share\IShareProviderSupportsAccept;
+use OCP\Share\IShareProviderSupportsAllSharesInFolder;
use OCP\Share\IShareProviderWithNotification;
use Psr\Log\LoggerInterface;
use function str_starts_with;
@@ -40,7 +42,7 @@ use function str_starts_with;
*
* @package OC\Share20
*/
-class DefaultShareProvider implements IShareProviderWithNotification, IShareProviderSupportsAccept {
+class DefaultShareProvider implements IShareProviderWithNotification, IShareProviderSupportsAccept, IShareProviderSupportsAllSharesInFolder {
// Special share type for user modified group shares
public const SHARE_TYPE_USERGROUP = 2;
@@ -603,6 +605,17 @@ class DefaultShareProvider implements IShareProviderWithNotification, IShareProv
throw new \Exception('non-shallow getSharesInFolder is no longer supported');
}
+ return $this->getSharesInFolderInternal($userId, $node, $reshares);
+ }
+
+ public function getAllSharesInFolder(Folder $node): array {
+ return $this->getSharesInFolderInternal(null, $node, null);
+ }
+
+ /**
+ * @return array<int, list<IShare>>
+ */
+ private function getSharesInFolderInternal(?string $userId, Folder $node, ?bool $reshares): array {
$qb = $this->dbConn->getQueryBuilder();
$qb->select('s.*',
'f.fileid', 'f.path', 'f.permissions AS f_permissions', 'f.storage', 'f.path_hash',
@@ -613,18 +626,20 @@ class DefaultShareProvider implements IShareProviderWithNotification, IShareProv
$qb->andWhere($qb->expr()->in('share_type', $qb->createNamedParameter([IShare::TYPE_USER, IShare::TYPE_GROUP, IShare::TYPE_LINK], IQueryBuilder::PARAM_INT_ARRAY)));
- /**
- * Reshares for this user are shares where they are the owner.
- */
- if ($reshares === false) {
- $qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
- } else {
- $qb->andWhere(
- $qb->expr()->orX(
- $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
- $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
- )
- );
+ if ($userId !== null) {
+ /**
+ * Reshares for this user are shares where they are the owner.
+ */
+ if ($reshares !== true) {
+ $qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
+ } else {
+ $qb->andWhere(
+ $qb->expr()->orX(
+ $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
+ $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
+ )
+ );
+ }
}
// todo? maybe get these from the oc_mounts table
@@ -656,7 +671,6 @@ class DefaultShareProvider implements IShareProviderWithNotification, IShareProv
foreach ($chunks as $chunk) {
$qb->setParameter('chunk', $chunk, IQueryBuilder::PARAM_INT_ARRAY);
- $a = $qb->getSQL();
$cursor = $qb->executeQuery();
while ($data = $cursor->fetch()) {
$shares[$data['fileid']][] = $this->createShare($data);
diff --git a/lib/private/Share20/Manager.php b/lib/private/Share20/Manager.php
index 3b247475afa..2104c07593a 100644
--- a/lib/private/Share20/Manager.php
+++ b/lib/private/Share20/Manager.php
@@ -51,6 +51,7 @@ use OCP\Share\IProviderFactory;
use OCP\Share\IShare;
use OCP\Share\IShareProvider;
use OCP\Share\IShareProviderSupportsAccept;
+use OCP\Share\IShareProviderSupportsAllSharesInFolder;
use OCP\Share\IShareProviderWithNotification;
use Psr\Log\LoggerInterface;
@@ -1213,11 +1214,13 @@ class Manager implements IManager {
$shares = [];
foreach ($providers as $provider) {
if ($isOwnerless) {
- foreach ($node->getDirectoryListing() as $childNode) {
- $data = $provider->getSharesByPath($childNode);
- $fid = $childNode->getId();
- $shares[$fid] ??= [];
- $shares[$fid] = array_merge($shares[$fid], $data);
+ // If the provider does not implement the additional interface,
+ // we lack a performant way of querying all shares and therefore ignore the provider.
+ if ($provider instanceof IShareProviderSupportsAllSharesInFolder) {
+ foreach ($provider->getAllSharesInFolder($node) as $fid => $data) {
+ $shares[$fid] ??= [];
+ $shares[$fid] = array_merge($shares[$fid], $data);
+ }
}
} else {
foreach ($provider->getSharesInFolder($userId, $node, $reshares) as $fid => $data) {
diff --git a/lib/private/Share20/ProviderFactory.php b/lib/private/Share20/ProviderFactory.php
index 7335c863df0..eba3f4f26f1 100644
--- a/lib/private/Share20/ProviderFactory.php
+++ b/lib/private/Share20/ProviderFactory.php
@@ -1,32 +1,21 @@
<?php
+declare(strict_types=1);
+
/**
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
* SPDX-License-Identifier: AGPL-3.0-only
*/
+
namespace OC\Share20;
use OC\Share20\Exception\ProviderException;
-use OCA\FederatedFileSharing\AddressHandler;
use OCA\FederatedFileSharing\FederatedShareProvider;
-use OCA\FederatedFileSharing\Notifications;
-use OCA\FederatedFileSharing\TokenHandler;
-use OCA\ShareByMail\Settings\SettingsManager;
use OCA\ShareByMail\ShareByMailProvider;
use OCA\Talk\Share\RoomShareProvider;
-use OCP\AppFramework\Utility\ITimeFactory;
-use OCP\Defaults;
-use OCP\EventDispatcher\IEventDispatcher;
-use OCP\Federation\ICloudFederationFactory;
-use OCP\Files\IRootFolder;
-use OCP\Http\Client\IClientService;
-use OCP\IServerContainer;
-use OCP\L10N\IFactory;
-use OCP\Mail\IMailer;
-use OCP\Security\IHasher;
-use OCP\Security\ISecureRandom;
-use OCP\Share\IManager;
+use OCP\App\IAppManager;
+use OCP\Server;
use OCP\Share\IProviderFactory;
use OCP\Share\IShare;
use OCP\Share\IShareProvider;
@@ -38,30 +27,22 @@ use Psr\Log\LoggerInterface;
* @package OC\Share20
*/
class ProviderFactory implements IProviderFactory {
- /** @var DefaultShareProvider */
- private $defaultProvider = null;
- /** @var FederatedShareProvider */
- private $federatedProvider = null;
- /** @var ShareByMailProvider */
- private $shareByMailProvider;
- /** @var \OCA\Circles\ShareByCircleProvider */
- private $shareByCircleProvider = null;
- /** @var bool */
- private $circlesAreNotAvailable = false;
- /** @var \OCA\Talk\Share\RoomShareProvider */
+ private ?DefaultShareProvider $defaultProvider = null;
+ private ?FederatedShareProvider $federatedProvider = null;
+ private ?ShareByMailProvider $shareByMailProvider = null;
+ /**
+ * @psalm-suppress UndefinedDocblockClass
+ * @var ?RoomShareProvider
+ */
private $roomShareProvider = null;
- private $registeredShareProviders = [];
+ private array $registeredShareProviders = [];
- private $shareProviders = [];
+ private array $shareProviders = [];
- /**
- * IProviderFactory constructor.
- *
- * @param IServerContainer $serverContainer
- */
public function __construct(
- private IServerContainer $serverContainer,
+ protected IAppManager $appManager,
+ protected LoggerInterface $logger,
) {
}
@@ -71,81 +52,24 @@ class ProviderFactory implements IProviderFactory {
/**
* Create the default share provider.
- *
- * @return DefaultShareProvider
*/
- protected function defaultShareProvider() {
- if ($this->defaultProvider === null) {
- $this->defaultProvider = new DefaultShareProvider(
- $this->serverContainer->getDatabaseConnection(),
- $this->serverContainer->getUserManager(),
- $this->serverContainer->getGroupManager(),
- $this->serverContainer->get(IRootFolder::class),
- $this->serverContainer->get(IMailer::class),
- $this->serverContainer->get(Defaults::class),
- $this->serverContainer->get(IFactory::class),
- $this->serverContainer->getURLGenerator(),
- $this->serverContainer->get(ITimeFactory::class),
- $this->serverContainer->get(LoggerInterface::class),
- $this->serverContainer->get(IManager::class),
- );
- }
-
- return $this->defaultProvider;
+ protected function defaultShareProvider(): DefaultShareProvider {
+ return Server::get(DefaultShareProvider::class);
}
/**
* Create the federated share provider
- *
- * @return FederatedShareProvider
*/
- protected function federatedShareProvider() {
+ protected function federatedShareProvider(): ?FederatedShareProvider {
if ($this->federatedProvider === null) {
/*
* Check if the app is enabled
*/
- $appManager = $this->serverContainer->getAppManager();
- if (!$appManager->isEnabledForUser('federatedfilesharing')) {
+ if (!$this->appManager->isEnabledForUser('federatedfilesharing')) {
return null;
}
- /*
- * TODO: add factory to federated sharing app
- */
- $l = $this->serverContainer->getL10N('federatedfilesharing');
- $addressHandler = new AddressHandler(
- $this->serverContainer->getURLGenerator(),
- $l,
- $this->serverContainer->getCloudIdManager()
- );
- $notifications = new Notifications(
- $addressHandler,
- $this->serverContainer->get(IClientService::class),
- $this->serverContainer->get(\OCP\OCS\IDiscoveryService::class),
- $this->serverContainer->getJobList(),
- \OC::$server->getCloudFederationProviderManager(),
- \OC::$server->get(ICloudFederationFactory::class),
- $this->serverContainer->get(IEventDispatcher::class),
- $this->serverContainer->get(LoggerInterface::class),
- );
- $tokenHandler = new TokenHandler(
- $this->serverContainer->get(ISecureRandom::class)
- );
-
- $this->federatedProvider = new FederatedShareProvider(
- $this->serverContainer->getDatabaseConnection(),
- $addressHandler,
- $notifications,
- $tokenHandler,
- $l,
- $this->serverContainer->get(IRootFolder::class),
- $this->serverContainer->getConfig(),
- $this->serverContainer->getUserManager(),
- $this->serverContainer->getCloudIdManager(),
- $this->serverContainer->getGlobalScaleConfig(),
- $this->serverContainer->getCloudFederationProviderManager(),
- $this->serverContainer->get(LoggerInterface::class),
- );
+ $this->federatedProvider = Server::get(FederatedShareProvider::class);
}
return $this->federatedProvider;
@@ -153,90 +77,34 @@ class ProviderFactory implements IProviderFactory {
/**
* Create the federated share provider
- *
- * @return ShareByMailProvider
*/
- protected function getShareByMailProvider() {
+ protected function getShareByMailProvider(): ?ShareByMailProvider {
if ($this->shareByMailProvider === null) {
/*
* Check if the app is enabled
*/
- $appManager = $this->serverContainer->getAppManager();
- if (!$appManager->isEnabledForUser('sharebymail')) {
+ if (!$this->appManager->isEnabledForUser('sharebymail')) {
return null;
}
- $settingsManager = new SettingsManager($this->serverContainer->getConfig());
-
- $this->shareByMailProvider = new ShareByMailProvider(
- $this->serverContainer->getConfig(),
- $this->serverContainer->getDatabaseConnection(),
- $this->serverContainer->get(ISecureRandom::class),
- $this->serverContainer->getUserManager(),
- $this->serverContainer->get(IRootFolder::class),
- $this->serverContainer->getL10N('sharebymail'),
- $this->serverContainer->get(LoggerInterface::class),
- $this->serverContainer->get(IMailer::class),
- $this->serverContainer->getURLGenerator(),
- $this->serverContainer->getActivityManager(),
- $settingsManager,
- $this->serverContainer->get(Defaults::class),
- $this->serverContainer->get(IHasher::class),
- $this->serverContainer->get(IEventDispatcher::class),
- $this->serverContainer->get(IManager::class)
- );
+ $this->shareByMailProvider = Server::get(ShareByMailProvider::class);
}
return $this->shareByMailProvider;
}
-
- /**
- * Create the circle share provider
- *
- * @return FederatedShareProvider
- *
- * @suppress PhanUndeclaredClassMethod
- */
- protected function getShareByCircleProvider() {
- if ($this->circlesAreNotAvailable) {
- return null;
- }
-
- if (!$this->serverContainer->getAppManager()->isEnabledForUser('circles') ||
- !class_exists('\OCA\Circles\ShareByCircleProvider')
- ) {
- $this->circlesAreNotAvailable = true;
- return null;
- }
-
- if ($this->shareByCircleProvider === null) {
- $this->shareByCircleProvider = new \OCA\Circles\ShareByCircleProvider(
- $this->serverContainer->getDatabaseConnection(),
- $this->serverContainer->get(ISecureRandom::class),
- $this->serverContainer->getUserManager(),
- $this->serverContainer->get(IRootFolder::class),
- $this->serverContainer->getL10N('circles'),
- $this->serverContainer->get(LoggerInterface::class),
- $this->serverContainer->getURLGenerator()
- );
- }
-
- return $this->shareByCircleProvider;
- }
-
/**
* Create the room share provider
*
- * @return RoomShareProvider
+ * @psalm-suppress UndefinedDocblockClass
+ * @return ?RoomShareProvider
*/
protected function getRoomShareProvider() {
if ($this->roomShareProvider === null) {
/*
* Check if the app is enabled
*/
- $appManager = $this->serverContainer->getAppManager();
- if (!$appManager->isEnabledForUser('spreed')) {
+ if (!$this->appManager->isEnabledForUser('spreed')) {
return null;
}
@@ -244,9 +112,9 @@ class ProviderFactory implements IProviderFactory {
/**
* @psalm-suppress UndefinedClass
*/
- $this->roomShareProvider = $this->serverContainer->get(RoomShareProvider::class);
+ $this->roomShareProvider = Server::get(RoomShareProvider::class);
} catch (\Throwable $e) {
- $this->serverContainer->get(LoggerInterface::class)->error(
+ $this->logger->error(
$e->getMessage(),
['exception' => $e]
);
@@ -272,8 +140,6 @@ class ProviderFactory implements IProviderFactory {
$provider = $this->federatedShareProvider();
} elseif ($id === 'ocMailShare') {
$provider = $this->getShareByMailProvider();
- } elseif ($id === 'ocCircleShare') {
- $provider = $this->getShareByCircleProvider();
} elseif ($id === 'ocRoomShare') {
$provider = $this->getRoomShareProvider();
}
@@ -281,10 +147,10 @@ class ProviderFactory implements IProviderFactory {
foreach ($this->registeredShareProviders as $shareProvider) {
try {
/** @var IShareProvider $instance */
- $instance = $this->serverContainer->get($shareProvider);
+ $instance = Server::get($shareProvider);
$this->shareProviders[$instance->identifier()] = $instance;
} catch (\Throwable $e) {
- $this->serverContainer->get(LoggerInterface::class)->error(
+ $this->logger->error(
$e->getMessage(),
['exception' => $e]
);
@@ -318,7 +184,7 @@ class ProviderFactory implements IProviderFactory {
} elseif ($shareType === IShare::TYPE_EMAIL) {
$provider = $this->getShareByMailProvider();
} elseif ($shareType === IShare::TYPE_CIRCLE) {
- $provider = $this->getShareByCircleProvider();
+ $provider = $this->getProvider('ocCircleShare');
} elseif ($shareType === IShare::TYPE_ROOM) {
$provider = $this->getRoomShareProvider();
} elseif ($shareType === IShare::TYPE_DECK) {
@@ -341,10 +207,6 @@ class ProviderFactory implements IProviderFactory {
if ($shareByMail !== null) {
$shares[] = $shareByMail;
}
- $shareByCircle = $this->getShareByCircleProvider();
- if ($shareByCircle !== null) {
- $shares[] = $shareByCircle;
- }
$roomShare = $this->getRoomShareProvider();
if ($roomShare !== null) {
$shares[] = $roomShare;
@@ -353,9 +215,9 @@ class ProviderFactory implements IProviderFactory {
foreach ($this->registeredShareProviders as $shareProvider) {
try {
/** @var IShareProvider $instance */
- $instance = $this->serverContainer->get($shareProvider);
+ $instance = Server::get($shareProvider);
} catch (\Throwable $e) {
- $this->serverContainer->get(LoggerInterface::class)->error(
+ $this->logger->error(
$e->getMessage(),
['exception' => $e]
);
diff --git a/lib/private/Support/CrashReport/Registry.php b/lib/private/Support/CrashReport/Registry.php
index 93969a81265..77dd8163174 100644
--- a/lib/private/Support/CrashReport/Registry.php
+++ b/lib/private/Support/CrashReport/Registry.php
@@ -110,6 +110,7 @@ class Registry implements IRegistry {
\OC::$server->get(LoggerInterface::class)->critical('Could not load lazy crash reporter: ' . $e->getMessage(), [
'exception' => $e,
]);
+ return;
}
/**
* Try to register the loaded reporter. Theoretically it could be of a wrong
diff --git a/lib/private/TaskProcessing/Manager.php b/lib/private/TaskProcessing/Manager.php
index a701c23d56f..9992310dbbb 100644
--- a/lib/private/TaskProcessing/Manager.php
+++ b/lib/private/TaskProcessing/Manager.php
@@ -584,6 +584,7 @@ class Manager implements IManager {
\OCP\TaskProcessing\TaskTypes\TextToTextChatWithTools::ID => \OCP\Server::get(\OCP\TaskProcessing\TaskTypes\TextToTextChatWithTools::class),
\OCP\TaskProcessing\TaskTypes\ContextAgentInteraction::ID => \OCP\Server::get(\OCP\TaskProcessing\TaskTypes\ContextAgentInteraction::class),
\OCP\TaskProcessing\TaskTypes\TextToTextProofread::ID => \OCP\Server::get(\OCP\TaskProcessing\TaskTypes\TextToTextProofread::class),
+ \OCP\TaskProcessing\TaskTypes\TextToSpeech::ID => \OCP\Server::get(\OCP\TaskProcessing\TaskTypes\TextToSpeech::class),
];
foreach ($context->getTaskProcessingTaskTypes() as $providerServiceRegistration) {
diff --git a/lib/private/TaskProcessing/RemoveOldTasksBackgroundJob.php b/lib/private/TaskProcessing/RemoveOldTasksBackgroundJob.php
index c6f26e3aa8b..42d073a024d 100644
--- a/lib/private/TaskProcessing/RemoveOldTasksBackgroundJob.php
+++ b/lib/private/TaskProcessing/RemoveOldTasksBackgroundJob.php
@@ -16,7 +16,7 @@ use OCP\Files\SimpleFS\ISimpleFolder;
use Psr\Log\LoggerInterface;
class RemoveOldTasksBackgroundJob extends TimedJob {
- public const MAX_TASK_AGE_SECONDS = 60 * 60 * 24 * 7 * 4; // 4 weeks
+ public const MAX_TASK_AGE_SECONDS = 60 * 60 * 24 * 30 * 4; // 4 months
private \OCP\Files\IAppData $appData;
public function __construct(
diff --git a/lib/private/TempManager.php b/lib/private/TempManager.php
index b7dccad3f95..4c0ffcf43d7 100644
--- a/lib/private/TempManager.php
+++ b/lib/private/TempManager.php
@@ -8,6 +8,7 @@
namespace OC;
use bantu\IniGetWrapper\IniGetWrapper;
+use OCP\Files;
use OCP\IConfig;
use OCP\ITempManager;
use OCP\Security\ISecureRandom;
@@ -99,7 +100,7 @@ class TempManager implements ITempManager {
foreach ($files as $file) {
if (file_exists($file)) {
try {
- \OC_Helper::rmdirr($file);
+ Files::rmdirr($file);
} catch (\UnexpectedValueException $ex) {
$this->log->warning(
'Error deleting temporary file/folder: {file} - Reason: {error}',
diff --git a/lib/private/Template/JSResourceLocator.php b/lib/private/Template/JSResourceLocator.php
index aad999f939a..a6d2d13a2ad 100644
--- a/lib/private/Template/JSResourceLocator.php
+++ b/lib/private/Template/JSResourceLocator.php
@@ -69,7 +69,7 @@ class JSResourceLocator extends ResourceLocator {
|| $this->appendScriptIfExist($this->serverroot, "dist/$app-$scriptName")
|| $this->appendScriptIfExist($appRoot, $script, $appWebRoot)
|| $this->cacheAndAppendCombineJsonIfExist($this->serverroot, $script . '.json')
- || $this->cacheAndAppendCombineJsonIfExist($appRoot, $script . '.json', $appWebRoot)
+ || $this->cacheAndAppendCombineJsonIfExist($appRoot, $script . '.json', $app)
|| $this->appendScriptIfExist($this->serverroot, $theme_dir . 'core/' . $script)
|| $this->appendScriptIfExist($this->serverroot, 'core/' . $script)
|| (strpos($scriptName, '/') === -1 && ($this->appendScriptIfExist($this->serverroot, $theme_dir . "dist/core-$scriptName")
diff --git a/lib/private/TemplateLayout.php b/lib/private/TemplateLayout.php
index caffbfceefa..cfc387d2164 100644
--- a/lib/private/TemplateLayout.php
+++ b/lib/private/TemplateLayout.php
@@ -201,7 +201,7 @@ class TemplateLayout {
if ($this->config->getSystemValueBool('installed', false)) {
if (empty(self::$versionHash)) {
- $v = $this->appManager->getAppInstalledVersions();
+ $v = $this->appManager->getAppInstalledVersions(true);
$v['core'] = implode('.', $this->serverVersion->getVersion());
self::$versionHash = substr(md5(implode(',', $v)), 0, 8);
}
diff --git a/lib/private/URLGenerator.php b/lib/private/URLGenerator.php
index ad12fae5144..1a2978b84d7 100644
--- a/lib/private/URLGenerator.php
+++ b/lib/private/URLGenerator.php
@@ -189,14 +189,14 @@ class URLGenerator implements IURLGenerator {
$basename = substr(basename($file), 0, -4);
try {
- $appPath = $this->getAppManager()->getAppPath($appName);
- } catch (AppPathNotFoundException $e) {
if ($appName === 'core' || $appName === '') {
$appName = 'core';
$appPath = false;
} else {
- throw new RuntimeException('image not found: image: ' . $file . ' webroot: ' . \OC::$WEBROOT . ' serverroot: ' . \OC::$SERVERROOT);
+ $appPath = $this->getAppManager()->getAppPath($appName);
}
+ } catch (AppPathNotFoundException $e) {
+ throw new RuntimeException('image not found: image: ' . $file . ' webroot: ' . \OC::$WEBROOT . ' serverroot: ' . \OC::$SERVERROOT);
}
// Check if the app is in the app folder
@@ -304,6 +304,11 @@ class URLGenerator implements IURLGenerator {
if ($href === '') {
throw new \InvalidArgumentException('Default navigation entry is missing href: ' . $entryId);
}
+
+ if (str_starts_with($href, $this->getBaseUrl())) {
+ return $href;
+ }
+
if (str_starts_with($href, '/index.php/') && ($this->config->getSystemValueBool('htaccess.IgnoreFrontController', false) || getenv('front_controller_active') === 'true')) {
$href = substr($href, 10);
}
diff --git a/lib/private/Updater/VersionCheck.php b/lib/private/Updater/VersionCheck.php
index 53bfc0d5d5f..be410b06c3e 100644
--- a/lib/private/Updater/VersionCheck.php
+++ b/lib/private/Updater/VersionCheck.php
@@ -105,17 +105,20 @@ class VersionCheck {
}
/**
- * @codeCoverageIgnore
- * @param string $url
- * @return resource|string
* @throws \Exception
*/
- protected function getUrlContent($url) {
- $client = $this->clientService->newClient();
- $response = $client->get($url, [
+ protected function getUrlContent(string $url): string {
+ $response = $this->clientService->newClient()->get($url, [
'timeout' => 5,
]);
- return $response->getBody();
+
+ $content = $response->getBody();
+
+ // IResponse.getBody responds with null|resource if returning a stream response was requested.
+ // As that's not the case here, we can just ignore the psalm warning by adding an assertion.
+ assert(is_string($content));
+
+ return $content;
}
private function computeCategory(): int {
diff --git a/lib/private/User/LazyUser.php b/lib/private/User/LazyUser.php
index 715265f6a39..501169019d4 100644
--- a/lib/private/User/LazyUser.php
+++ b/lib/private/User/LazyUser.php
@@ -160,6 +160,10 @@ class LazyUser implements IUser {
return $this->getUser()->getQuota();
}
+ public function getQuotaBytes(): int|float {
+ return $this->getUser()->getQuotaBytes();
+ }
+
public function setQuota($quota) {
$this->getUser()->setQuota($quota);
}
diff --git a/lib/private/User/Manager.php b/lib/private/User/Manager.php
index ca5d90f8c00..229f3138e6d 100644
--- a/lib/private/User/Manager.php
+++ b/lib/private/User/Manager.php
@@ -724,7 +724,8 @@ class Manager extends PublicEmitter implements IUserManager {
// User ID is too long
if (strlen($uid) > IUser::MAX_USERID_LENGTH) {
- throw new \InvalidArgumentException($l->t('Login is too long'));
+ // TRANSLATORS User ID is too long
+ throw new \InvalidArgumentException($l->t('Username is too long'));
}
if (!$this->verifyUid($uid, $checkDataDirectory)) {
diff --git a/lib/private/User/Session.php b/lib/private/User/Session.php
index 27570822ef2..a638cd24557 100644
--- a/lib/private/User/Session.php
+++ b/lib/private/User/Session.php
@@ -967,6 +967,7 @@ class Session implements IUserSession, Emitter {
if ($webRoot === '') {
$webRoot = '/';
}
+ $domain = $this->config->getSystemValueString('cookie_domain');
$maxAge = $this->config->getSystemValueInt('remember_login_cookie_lifetime', 60 * 60 * 24 * 15);
\OC\Http\CookieHelper::setCookie(
@@ -974,7 +975,7 @@ class Session implements IUserSession, Emitter {
$username,
$maxAge,
$webRoot,
- '',
+ $domain,
$secureCookie,
true,
\OC\Http\CookieHelper::SAMESITE_LAX
@@ -984,7 +985,7 @@ class Session implements IUserSession, Emitter {
$token,
$maxAge,
$webRoot,
- '',
+ $domain,
$secureCookie,
true,
\OC\Http\CookieHelper::SAMESITE_LAX
@@ -995,7 +996,7 @@ class Session implements IUserSession, Emitter {
$this->session->getId(),
$maxAge,
$webRoot,
- '',
+ $domain,
$secureCookie,
true,
\OC\Http\CookieHelper::SAMESITE_LAX
@@ -1011,18 +1012,19 @@ class Session implements IUserSession, Emitter {
public function unsetMagicInCookie() {
//TODO: DI for cookies and IRequest
$secureCookie = OC::$server->getRequest()->getServerProtocol() === 'https';
+ $domain = $this->config->getSystemValueString('cookie_domain');
unset($_COOKIE['nc_username']); //TODO: DI
unset($_COOKIE['nc_token']);
unset($_COOKIE['nc_session_id']);
- setcookie('nc_username', '', $this->timeFactory->getTime() - 3600, OC::$WEBROOT, '', $secureCookie, true);
- setcookie('nc_token', '', $this->timeFactory->getTime() - 3600, OC::$WEBROOT, '', $secureCookie, true);
- setcookie('nc_session_id', '', $this->timeFactory->getTime() - 3600, OC::$WEBROOT, '', $secureCookie, true);
+ setcookie('nc_username', '', $this->timeFactory->getTime() - 3600, OC::$WEBROOT, $domain, $secureCookie, true);
+ setcookie('nc_token', '', $this->timeFactory->getTime() - 3600, OC::$WEBROOT, $domain, $secureCookie, true);
+ setcookie('nc_session_id', '', $this->timeFactory->getTime() - 3600, OC::$WEBROOT, $domain, $secureCookie, true);
// old cookies might be stored under /webroot/ instead of /webroot
// and Firefox doesn't like it!
- setcookie('nc_username', '', $this->timeFactory->getTime() - 3600, OC::$WEBROOT . '/', '', $secureCookie, true);
- setcookie('nc_token', '', $this->timeFactory->getTime() - 3600, OC::$WEBROOT . '/', '', $secureCookie, true);
- setcookie('nc_session_id', '', $this->timeFactory->getTime() - 3600, OC::$WEBROOT . '/', '', $secureCookie, true);
+ setcookie('nc_username', '', $this->timeFactory->getTime() - 3600, OC::$WEBROOT . '/', $domain, $secureCookie, true);
+ setcookie('nc_token', '', $this->timeFactory->getTime() - 3600, OC::$WEBROOT . '/', $domain, $secureCookie, true);
+ setcookie('nc_session_id', '', $this->timeFactory->getTime() - 3600, OC::$WEBROOT . '/', $domain, $secureCookie, true);
}
/**
diff --git a/lib/private/User/User.php b/lib/private/User/User.php
index f04977314e2..88ed0d44387 100644
--- a/lib/private/User/User.php
+++ b/lib/private/User/User.php
@@ -11,7 +11,6 @@ use InvalidArgumentException;
use OC\Accounts\AccountManager;
use OC\Avatar\AvatarManager;
use OC\Hooks\Emitter;
-use OC_Helper;
use OCP\Accounts\IAccountManager;
use OCP\Comments\ICommentsManager;
use OCP\EventDispatcher\IEventDispatcher;
@@ -559,6 +558,19 @@ class User implements IUser {
return $quota;
}
+ public function getQuotaBytes(): int|float {
+ $quota = $this->getQuota();
+ if ($quota === 'none') {
+ return \OCP\Files\FileInfo::SPACE_UNLIMITED;
+ }
+
+ $bytes = \OCP\Util::computerFileSize($quota);
+ if ($bytes === false) {
+ return \OCP\Files\FileInfo::SPACE_UNKNOWN;
+ }
+ return $bytes;
+ }
+
/**
* set the users' quota
*
@@ -570,11 +582,11 @@ class User implements IUser {
public function setQuota($quota) {
$oldQuota = $this->config->getUserValue($this->uid, 'files', 'quota', '');
if ($quota !== 'none' and $quota !== 'default') {
- $bytesQuota = OC_Helper::computerFileSize($quota);
+ $bytesQuota = \OCP\Util::computerFileSize($quota);
if ($bytesQuota === false) {
throw new InvalidArgumentException('Failed to set quota to invalid value ' . $quota);
}
- $quota = OC_Helper::humanFileSize($bytesQuota);
+ $quota = \OCP\Util::humanFileSize($bytesQuota);
}
if ($quota !== $oldQuota) {
$this->config->setUserValue($this->uid, 'files', 'quota', $quota);
diff --git a/lib/private/legacy/OC_App.php b/lib/private/legacy/OC_App.php
index ecceafa65b3..24982ab9e80 100644
--- a/lib/private/legacy/OC_App.php
+++ b/lib/private/legacy/OC_App.php
@@ -9,6 +9,7 @@ declare(strict_types=1);
use OC\App\DependencyAnalyzer;
use OC\App\Platform;
use OC\AppFramework\Bootstrap\Coordinator;
+use OC\Config\ConfigManager;
use OC\DB\MigrationService;
use OC\Installer;
use OC\Repair;
@@ -211,7 +212,7 @@ class OC_App {
array $groups = []) {
// Check if app is already downloaded
/** @var Installer $installer */
- $installer = \OCP\Server::get(Installer::class);
+ $installer = Server::get(Installer::class);
$isDownloaded = $installer->isDownloaded($appId);
if (!$isDownloaded) {
@@ -246,7 +247,7 @@ class OC_App {
}
}
- \OCP\Server::get(LoggerInterface::class)->error('No application directories are marked as writable.', ['app' => 'core']);
+ Server::get(LoggerInterface::class)->error('No application directories are marked as writable.', ['app' => 'core']);
return null;
}
@@ -310,12 +311,14 @@ class OC_App {
* @param string $appId
* @param bool $refreshAppPath should be set to true only during install/upgrade
* @return string|false
- * @deprecated 11.0.0 use \OCP\Server::get(IAppManager)->getAppPath()
+ * @deprecated 11.0.0 use Server::get(IAppManager)->getAppPath()
*/
public static function getAppPath(string $appId, bool $refreshAppPath = false) {
$appId = self::cleanAppId($appId);
if ($appId === '') {
return false;
+ } elseif ($appId === 'core') {
+ return __DIR__ . '/../../../core';
}
if (($dir = self::findAppInDirectories($appId, $refreshAppPath)) != false) {
@@ -347,7 +350,7 @@ class OC_App {
*/
public static function getAppVersionByPath(string $path): string {
$infoFile = $path . '/appinfo/info.xml';
- $appData = \OCP\Server::get(IAppManager::class)->getAppInfoByPath($infoFile);
+ $appData = Server::get(IAppManager::class)->getAppInfoByPath($infoFile);
return $appData['version'] ?? '';
}
@@ -389,7 +392,7 @@ class OC_App {
* @deprecated 20.0.0 Please register your alternative login option using the registerAlternativeLogin() on the RegistrationContext in your Application class implementing the OCP\Authentication\IAlternativeLogin interface
*/
public static function registerLogIn(array $entry) {
- \OCP\Server::get(LoggerInterface::class)->debug('OC_App::registerLogIn() is deprecated, please register your alternative login option using the registerAlternativeLogin() on the RegistrationContext in your Application class implementing the OCP\Authentication\IAlternativeLogin interface');
+ Server::get(LoggerInterface::class)->debug('OC_App::registerLogIn() is deprecated, please register your alternative login option using the registerAlternativeLogin() on the RegistrationContext in your Application class implementing the OCP\Authentication\IAlternativeLogin interface');
self::$altLogin[] = $entry;
}
@@ -398,11 +401,11 @@ class OC_App {
*/
public static function getAlternativeLogIns(): array {
/** @var Coordinator $bootstrapCoordinator */
- $bootstrapCoordinator = \OCP\Server::get(Coordinator::class);
+ $bootstrapCoordinator = Server::get(Coordinator::class);
foreach ($bootstrapCoordinator->getRegistrationContext()->getAlternativeLogins() as $registration) {
if (!in_array(IAlternativeLogin::class, class_implements($registration->getService()), true)) {
- \OCP\Server::get(LoggerInterface::class)->error('Alternative login option {option} does not implement {interface} and is therefore ignored.', [
+ Server::get(LoggerInterface::class)->error('Alternative login option {option} does not implement {interface} and is therefore ignored.', [
'option' => $registration->getService(),
'interface' => IAlternativeLogin::class,
'app' => $registration->getAppId(),
@@ -412,9 +415,9 @@ class OC_App {
try {
/** @var IAlternativeLogin $provider */
- $provider = \OCP\Server::get($registration->getService());
+ $provider = Server::get($registration->getService());
} catch (ContainerExceptionInterface $e) {
- \OCP\Server::get(LoggerInterface::class)->error('Alternative login option {option} can not be initialized.',
+ Server::get(LoggerInterface::class)->error('Alternative login option {option} can not be initialized.',
[
'exception' => $e,
'option' => $registration->getService(),
@@ -431,7 +434,7 @@ class OC_App {
'class' => $provider->getClass(),
];
} catch (Throwable $e) {
- \OCP\Server::get(LoggerInterface::class)->error('Alternative login option {option} had an error while loading.',
+ Server::get(LoggerInterface::class)->error('Alternative login option {option} had an error while loading.',
[
'exception' => $e,
'option' => $registration->getService(),
@@ -450,7 +453,7 @@ class OC_App {
* @deprecated 31.0.0 Use IAppManager::getAllAppsInAppsFolders instead
*/
public static function getAllApps(): array {
- return \OCP\Server::get(IAppManager::class)->getAllAppsInAppsFolders();
+ return Server::get(IAppManager::class)->getAllAppsInAppsFolders();
}
/**
@@ -459,7 +462,7 @@ class OC_App {
* @deprecated 32.0.0 Use \OCP\Support\Subscription\IRegistry::delegateGetSupportedApps instead
*/
public function getSupportedApps(): array {
- $subscriptionRegistry = \OCP\Server::get(\OCP\Support\Subscription\IRegistry::class);
+ $subscriptionRegistry = Server::get(\OCP\Support\Subscription\IRegistry::class);
$supportedApps = $subscriptionRegistry->delegateGetSupportedApps();
return $supportedApps;
}
@@ -484,12 +487,12 @@ class OC_App {
if (!in_array($app, $blacklist)) {
$info = $appManager->getAppInfo($app, false, $langCode);
if (!is_array($info)) {
- \OCP\Server::get(LoggerInterface::class)->error('Could not read app info file for app "' . $app . '"', ['app' => 'core']);
+ Server::get(LoggerInterface::class)->error('Could not read app info file for app "' . $app . '"', ['app' => 'core']);
continue;
}
if (!isset($info['name'])) {
- \OCP\Server::get(LoggerInterface::class)->error('App id "' . $app . '" has no name in appinfo', ['app' => 'core']);
+ Server::get(LoggerInterface::class)->error('App id "' . $app . '" has no name in appinfo', ['app' => 'core']);
continue;
}
@@ -556,7 +559,7 @@ class OC_App {
public static function shouldUpgrade(string $app): bool {
$versions = self::getAppVersions();
- $currentVersion = \OCP\Server::get(\OCP\App\IAppManager::class)->getAppVersion($app);
+ $currentVersion = Server::get(\OCP\App\IAppManager::class)->getAppVersion($app);
if ($currentVersion && isset($versions[$app])) {
$installedVersion = $versions[$app];
if (!version_compare($currentVersion, $installedVersion, '=')) {
@@ -645,7 +648,7 @@ class OC_App {
* @deprecated 32.0.0 Use IAppManager::getAppInstalledVersions or IAppConfig::getAppInstalledVersions instead
*/
public static function getAppVersions(): array {
- return \OCP\Server::get(IAppConfig::class)->getAppInstalledVersions();
+ return Server::get(IAppConfig::class)->getAppInstalledVersions();
}
/**
@@ -663,13 +666,13 @@ class OC_App {
}
if (is_file($appPath . '/appinfo/database.xml')) {
- \OCP\Server::get(LoggerInterface::class)->error('The appinfo/database.xml file is not longer supported. Used in ' . $appId);
+ Server::get(LoggerInterface::class)->error('The appinfo/database.xml file is not longer supported. Used in ' . $appId);
return false;
}
\OC::$server->getAppManager()->clearAppsCache();
$l = \OC::$server->getL10N('core');
- $appData = \OCP\Server::get(\OCP\App\IAppManager::class)->getAppInfo($appId, false, $l->getLanguageCode());
+ $appData = Server::get(\OCP\App\IAppManager::class)->getAppInfo($appId, false, $l->getLanguageCode());
$ignoreMaxApps = \OC::$server->getConfig()->getSystemValue('app_install_overwrite', []);
$ignoreMax = in_array($appId, $ignoreMaxApps, true);
@@ -709,9 +712,13 @@ class OC_App {
self::setAppTypes($appId);
- $version = \OCP\Server::get(\OCP\App\IAppManager::class)->getAppVersion($appId);
+ $version = Server::get(\OCP\App\IAppManager::class)->getAppVersion($appId);
\OC::$server->getConfig()->setAppValue($appId, 'installed_version', $version);
+ // migrate eventual new config keys in the process
+ /** @psalm-suppress InternalMethod */
+ Server::get(ConfigManager::class)->migrateConfigLexiconKeys($appId);
+
\OC::$server->get(IEventDispatcher::class)->dispatchTyped(new AppUpdateEvent($appId));
\OC::$server->get(IEventDispatcher::class)->dispatch(ManagerEvent::EVENT_APP_UPDATE, new ManagerEvent(
ManagerEvent::EVENT_APP_UPDATE, $appId
@@ -768,28 +775,6 @@ class OC_App {
}
}
- /**
- * @param string $appId
- * @return \OC\Files\View|false
- */
- public static function getStorage(string $appId) {
- if (\OC::$server->getAppManager()->isEnabledForUser($appId)) { //sanity check
- if (\OC::$server->getUserSession()->isLoggedIn()) {
- $view = new \OC\Files\View('/' . OC_User::getUser());
- if (!$view->file_exists($appId)) {
- $view->mkdir($appId);
- }
- return new \OC\Files\View('/' . OC_User::getUser() . '/' . $appId);
- } else {
- \OCP\Server::get(LoggerInterface::class)->error('Can\'t get app storage, app ' . $appId . ', user not logged in', ['app' => 'core']);
- return false;
- }
- } else {
- \OCP\Server::get(LoggerInterface::class)->error('Can\'t get app storage, app ' . $appId . ' not enabled', ['app' => 'core']);
- return false;
- }
- }
-
protected static function findBestL10NOption(array $options, string $lang): string {
// only a single option
if (isset($options['@value'])) {
diff --git a/lib/private/legacy/OC_Helper.php b/lib/private/legacy/OC_Helper.php
index a89cbe1bb3a..4388f775623 100644
--- a/lib/private/legacy/OC_Helper.php
+++ b/lib/private/legacy/OC_Helper.php
@@ -12,6 +12,7 @@ use OCP\Files\Mount\IMountPoint;
use OCP\IBinaryFinder;
use OCP\ICacheFactory;
use OCP\IUser;
+use OCP\Server;
use OCP\Util;
use Psr\Log\LoggerInterface;
@@ -36,85 +37,11 @@ class OC_Helper {
private static ?bool $quotaIncludeExternalStorage = null;
/**
- * Make a human file size
- * @param int|float $bytes file size in bytes
- * @return string a human readable file size
- *
- * Makes 2048 to 2 kB.
- */
- public static function humanFileSize(int|float $bytes): string {
- if ($bytes < 0) {
- return '?';
- }
- if ($bytes < 1024) {
- return "$bytes B";
- }
- $bytes = round($bytes / 1024, 0);
- if ($bytes < 1024) {
- return "$bytes KB";
- }
- $bytes = round($bytes / 1024, 1);
- if ($bytes < 1024) {
- return "$bytes MB";
- }
- $bytes = round($bytes / 1024, 1);
- if ($bytes < 1024) {
- return "$bytes GB";
- }
- $bytes = round($bytes / 1024, 1);
- if ($bytes < 1024) {
- return "$bytes TB";
- }
-
- $bytes = round($bytes / 1024, 1);
- return "$bytes PB";
- }
-
- /**
- * Make a computer file size
- * @param string $str file size in human readable format
- * @return false|int|float a file size in bytes
- *
- * Makes 2kB to 2048.
- *
- * Inspired by: https://www.php.net/manual/en/function.filesize.php#92418
- */
- public static function computerFileSize(string $str): false|int|float {
- $str = strtolower($str);
- if (is_numeric($str)) {
- return Util::numericToNumber($str);
- }
-
- $bytes_array = [
- 'b' => 1,
- 'k' => 1024,
- 'kb' => 1024,
- 'mb' => 1024 * 1024,
- 'm' => 1024 * 1024,
- 'gb' => 1024 * 1024 * 1024,
- 'g' => 1024 * 1024 * 1024,
- 'tb' => 1024 * 1024 * 1024 * 1024,
- 't' => 1024 * 1024 * 1024 * 1024,
- 'pb' => 1024 * 1024 * 1024 * 1024 * 1024,
- 'p' => 1024 * 1024 * 1024 * 1024 * 1024,
- ];
-
- $bytes = (float)$str;
-
- if (preg_match('#([kmgtp]?b?)$#si', $str, $matches) && isset($bytes_array[$matches[1]])) {
- $bytes *= $bytes_array[$matches[1]];
- } else {
- return false;
- }
-
- return Util::numericToNumber(round($bytes));
- }
-
- /**
* Recursive copying of folders
* @param string $src source folder
* @param string $dest target folder
* @return void
+ * @deprecated 32.0.0 - use \OCP\Files\Folder::copy
*/
public static function copyr($src, $dest) {
if (!file_exists($src)) {
@@ -140,44 +67,6 @@ class OC_Helper {
}
/**
- * Recursive deletion of folders
- * @param string $dir path to the folder
- * @param bool $deleteSelf if set to false only the content of the folder will be deleted
- * @return bool
- */
- public static function rmdirr($dir, $deleteSelf = true) {
- if (is_dir($dir)) {
- $files = new RecursiveIteratorIterator(
- new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
- RecursiveIteratorIterator::CHILD_FIRST
- );
-
- foreach ($files as $fileInfo) {
- /** @var SplFileInfo $fileInfo */
- if ($fileInfo->isLink()) {
- unlink($fileInfo->getPathname());
- } elseif ($fileInfo->isDir()) {
- rmdir($fileInfo->getRealPath());
- } else {
- unlink($fileInfo->getRealPath());
- }
- }
- if ($deleteSelf) {
- rmdir($dir);
- }
- } elseif (file_exists($dir)) {
- if ($deleteSelf) {
- unlink($dir);
- }
- }
- if (!$deleteSelf) {
- return true;
- }
-
- return !file_exists($dir);
- }
-
- /**
* @deprecated 18.0.0
* @return \OC\Files\Type\TemplateManager
*/
@@ -196,6 +85,7 @@ class OC_Helper {
* @internal param string $program name
* @internal param string $optional search path, defaults to $PATH
* @return bool true if executable program found in path
+ * @deprecated 32.0.0 use the \OCP\IBinaryFinder
*/
public static function canExecute($name, $path = false) {
// path defaults to PATH from environment if not set
@@ -206,7 +96,7 @@ class OC_Helper {
$exts = [''];
$check_fn = 'is_executable';
// Default check will be done with $path directories :
- $dirs = explode(PATH_SEPARATOR, $path);
+ $dirs = explode(PATH_SEPARATOR, (string)$path);
// WARNING : We have to check if open_basedir is enabled :
$obd = OC::$server->get(IniGetWrapper::class)->getString('open_basedir');
if ($obd != 'none') {
@@ -233,31 +123,10 @@ class OC_Helper {
* @param resource $source
* @param resource $target
* @return array the number of bytes copied and result
+ * @deprecated 5.0.0 - Use \OCP\Files::streamCopy
*/
public static function streamCopy($source, $target) {
- if (!$source or !$target) {
- return [0, false];
- }
- $bufSize = 8192;
- $result = true;
- $count = 0;
- while (!feof($source)) {
- $buf = fread($source, $bufSize);
- $bytesWritten = fwrite($target, $buf);
- if ($bytesWritten !== false) {
- $count += $bytesWritten;
- }
- // note: strlen is expensive so only use it when necessary,
- // on the last block
- if ($bytesWritten === false
- || ($bytesWritten < $bufSize && $bytesWritten < strlen($buf))
- ) {
- // write error, could be disk full ?
- $result = false;
- break;
- }
- }
- return [$count, $result];
+ return \OCP\Files::streamCopy($source, $target, true);
}
/**
@@ -320,115 +189,20 @@ class OC_Helper {
}
/**
- * Returns an array with all keys from input lowercased or uppercased. Numbered indices are left as is.
- *
- * @param array $input The array to work on
- * @param int $case Either MB_CASE_UPPER or MB_CASE_LOWER (default)
- * @param string $encoding The encoding parameter is the character encoding. Defaults to UTF-8
- * @return array
- *
- * Returns an array with all keys from input lowercased or uppercased. Numbered indices are left as is.
- * based on https://www.php.net/manual/en/function.array-change-key-case.php#107715
- *
- */
- public static function mb_array_change_key_case($input, $case = MB_CASE_LOWER, $encoding = 'UTF-8') {
- $case = ($case != MB_CASE_UPPER) ? MB_CASE_LOWER : MB_CASE_UPPER;
- $ret = [];
- foreach ($input as $k => $v) {
- $ret[mb_convert_case($k, $case, $encoding)] = $v;
- }
- return $ret;
- }
-
- /**
- * performs a search in a nested array
- * @param array $haystack the array to be searched
- * @param string $needle the search string
- * @param mixed $index optional, only search this key name
- * @return mixed the key of the matching field, otherwise false
- *
- * performs a search in a nested array
- *
- * taken from https://www.php.net/manual/en/function.array-search.php#97645
- */
- public static function recursiveArraySearch($haystack, $needle, $index = null) {
- $aIt = new RecursiveArrayIterator($haystack);
- $it = new RecursiveIteratorIterator($aIt);
-
- while ($it->valid()) {
- if (((isset($index) and ($it->key() == $index)) or !isset($index)) and ($it->current() == $needle)) {
- return $aIt->key();
- }
-
- $it->next();
- }
-
- return false;
- }
-
- /**
- * calculates the maximum upload size respecting system settings, free space and user quota
- *
- * @param string $dir the current folder where the user currently operates
- * @param int|float $freeSpace the number of bytes free on the storage holding $dir, if not set this will be received from the storage directly
- * @return int|float number of bytes representing
- */
- public static function maxUploadFilesize($dir, $freeSpace = null) {
- if (is_null($freeSpace) || $freeSpace < 0) {
- $freeSpace = self::freeSpace($dir);
- }
- return min($freeSpace, self::uploadLimit());
- }
-
- /**
- * Calculate free space left within user quota
- *
- * @param string $dir the current folder where the user currently operates
- * @return int|float number of bytes representing
- */
- public static function freeSpace($dir) {
- $freeSpace = \OC\Files\Filesystem::free_space($dir);
- if ($freeSpace < \OCP\Files\FileInfo::SPACE_UNLIMITED) {
- $freeSpace = max($freeSpace, 0);
- return $freeSpace;
- } else {
- return (INF > 0)? INF: PHP_INT_MAX; // work around https://bugs.php.net/bug.php?id=69188
- }
- }
-
- /**
- * Calculate PHP upload limit
- *
- * @return int|float PHP upload file size limit
- */
- public static function uploadLimit() {
- $ini = \OC::$server->get(IniGetWrapper::class);
- $upload_max_filesize = Util::computerFileSize($ini->get('upload_max_filesize')) ?: 0;
- $post_max_size = Util::computerFileSize($ini->get('post_max_size')) ?: 0;
- if ($upload_max_filesize === 0 && $post_max_size === 0) {
- return INF;
- } elseif ($upload_max_filesize === 0 || $post_max_size === 0) {
- return max($upload_max_filesize, $post_max_size); //only the non 0 value counts
- } else {
- return min($upload_max_filesize, $post_max_size);
- }
- }
-
- /**
* Checks if a function is available
*
* @deprecated 25.0.0 use \OCP\Util::isFunctionEnabled instead
*/
public static function is_function_enabled(string $function_name): bool {
- return \OCP\Util::isFunctionEnabled($function_name);
+ return Util::isFunctionEnabled($function_name);
}
/**
* Try to find a program
- * @deprecated 25.0.0 Use \OC\BinaryFinder directly
+ * @deprecated 25.0.0 Use \OCP\IBinaryFinder directly
*/
public static function findBinaryPath(string $program): ?string {
- $result = \OCP\Server::get(IBinaryFinder::class)->findBinaryPath($program);
+ $result = Server::get(IBinaryFinder::class)->findBinaryPath($program);
return $result !== false ? $result : null;
}
@@ -448,7 +222,7 @@ class OC_Helper {
*/
public static function getStorageInfo($path, $rootInfo = null, $includeMountPoints = true, $useCache = true) {
if (!self::$cacheFactory) {
- self::$cacheFactory = \OC::$server->get(ICacheFactory::class);
+ self::$cacheFactory = Server::get(ICacheFactory::class);
}
$memcache = self::$cacheFactory->createLocal('storage_info');
@@ -498,7 +272,7 @@ class OC_Helper {
} else {
$user = \OC::$server->getUserSession()->getUser();
}
- $quota = OC_Util::getUserQuota($user);
+ $quota = $user?->getQuotaBytes() ?? \OCP\Files\FileInfo::SPACE_UNKNOWN;
if ($quota !== \OCP\Files\FileInfo::SPACE_UNLIMITED) {
// always get free space / total space from root + mount points
return self::getGlobalStorageInfo($quota, $user, $mount);
@@ -641,6 +415,7 @@ class OC_Helper {
/**
* Returns whether the config file is set manually to read-only
* @return bool
+ * @deprecated 32.0.0 use the `config_is_read_only` system config directly
*/
public static function isReadOnlyConfigEnabled() {
return \OC::$server->getConfig()->getSystemValueBool('config_is_read_only', false);
diff --git a/lib/private/legacy/OC_Response.php b/lib/private/legacy/OC_Response.php
index 86274f5fcb7..c45852b4b1d 100644
--- a/lib/private/legacy/OC_Response.php
+++ b/lib/private/legacy/OC_Response.php
@@ -78,7 +78,6 @@ class OC_Response {
header('X-Frame-Options: SAMEORIGIN'); // Disallow iFraming from other domains
header('X-Permitted-Cross-Domain-Policies: none'); // https://www.adobe.com/devnet/adobe-media-server/articles/cross-domain-xml-for-streaming.html
header('X-Robots-Tag: noindex, nofollow'); // https://developers.google.com/webmasters/control-crawl-index/docs/robots_meta_tag
- header('X-XSS-Protection: 1; mode=block'); // Enforce browser based XSS filters
}
}
}
diff --git a/lib/private/legacy/OC_Util.php b/lib/private/legacy/OC_Util.php
index 580fec7b5b3..41ac787aa80 100644
--- a/lib/private/legacy/OC_Util.php
+++ b/lib/private/legacy/OC_Util.php
@@ -98,6 +98,7 @@ class OC_Util {
*
* @param IUser|null $user
* @return int|\OCP\Files\FileInfo::SPACE_UNLIMITED|false|float Quota bytes
+ * @deprecated 9.0.0 - Use \OCP\IUser::getQuota or \OCP\IUser::getQuotaBytes
*/
public static function getUserQuota(?IUser $user) {
if (is_null($user)) {
@@ -107,7 +108,7 @@ class OC_Util {
if ($userQuota === 'none') {
return \OCP\Files\FileInfo::SPACE_UNLIMITED;
}
- return OC_Helper::computerFileSize($userQuota);
+ return \OCP\Util::computerFileSize($userQuota);
}
/**
@@ -186,14 +187,13 @@ class OC_Util {
$child = $target->newFolder($file);
self::copyr($source . '/' . $file, $child);
} else {
- $child = $target->newFile($file);
$sourceStream = fopen($source . '/' . $file, 'r');
if ($sourceStream === false) {
$logger->error(sprintf('Could not fopen "%s"', $source . '/' . $file), ['app' => 'core']);
closedir($dir);
return;
}
- $child->putContent($sourceStream);
+ $target->newFile($file, $sourceStream);
}
}
}
@@ -331,7 +331,7 @@ class OC_Util {
}
// Check if config folder is writable.
- if (!OC_Helper::isReadOnlyConfigEnabled()) {
+ if (!(bool)$config->getValue('config_is_read_only', false)) {
if (!is_writable(OC::$configDir) or !is_readable(OC::$configDir)) {
$errors[] = [
'error' => $l->t('Cannot write into "config" directory.'),
diff --git a/lib/public/Accounts/IAccountManager.php b/lib/public/Accounts/IAccountManager.php
index a15651eb5e6..92fc0002674 100644
--- a/lib/public/Accounts/IAccountManager.php
+++ b/lib/public/Accounts/IAccountManager.php
@@ -48,30 +48,6 @@ interface IAccountManager {
public const SCOPE_PUBLISHED = 'v2-published';
/**
- * Contact details only visible locally
- *
- * @since 15.0.0
- * @deprecated 21.0.1
- */
- public const VISIBILITY_PRIVATE = 'private';
-
- /**
- * Contact details visible on trusted federated servers.
- *
- * @since 15.0.0
- * @deprecated 21.0.1
- */
- public const VISIBILITY_CONTACTS_ONLY = 'contacts';
-
- /**
- * Contact details visible on trusted federated servers and in the public lookup server.
- *
- * @since 15.0.0
- * @deprecated 21.0.1
- */
- public const VISIBILITY_PUBLIC = 'public';
-
- /**
* The list of allowed scopes
*
* @since 25.0.0
@@ -81,9 +57,6 @@ interface IAccountManager {
self::SCOPE_LOCAL,
self::SCOPE_FEDERATED,
self::SCOPE_PUBLISHED,
- self::VISIBILITY_PRIVATE,
- self::VISIBILITY_CONTACTS_ONLY,
- self::VISIBILITY_PUBLIC,
];
/**
@@ -98,6 +71,7 @@ interface IAccountManager {
/**
* @since 27.0.0
+ * @deprecated 27.0.0 only added for backwards compatibility with provisioning_api UsersController::getCurrentUser
*/
public const PROPERTY_DISPLAYNAME_LEGACY = 'display-name';
diff --git a/lib/public/App/Events/AppUpdateEvent.php b/lib/public/App/Events/AppUpdateEvent.php
index 344e7def080..2cf59ff7949 100644
--- a/lib/public/App/Events/AppUpdateEvent.php
+++ b/lib/public/App/Events/AppUpdateEvent.php
@@ -16,15 +16,13 @@ use OCP\EventDispatcher\Event;
* @since 27.0.0
*/
class AppUpdateEvent extends Event {
- private string $appId;
-
/**
* @since 27.0.0
*/
- public function __construct(string $appId) {
+ public function __construct(
+ private readonly string $appId,
+ ) {
parent::__construct();
-
- $this->appId = $appId;
}
/**
diff --git a/lib/public/App/IAppManager.php b/lib/public/App/IAppManager.php
index 67ef2d796be..20019ce1ffd 100644
--- a/lib/public/App/IAppManager.php
+++ b/lib/public/App/IAppManager.php
@@ -57,7 +57,7 @@ interface IAppManager {
* @return array<string, string>
* @since 32.0.0
*/
- public function getAppInstalledVersions(): array;
+ public function getAppInstalledVersions(bool $onlyEnabled = false): array;
/**
* Returns the app icon or null if none is found
@@ -184,7 +184,7 @@ interface IAppManager {
* List all apps enabled for a user
*
* @param \OCP\IUser $user
- * @return string[]
+ * @return list<string>
* @since 8.1.0
*/
public function getEnabledAppsForUser(IUser $user);
diff --git a/lib/public/AppFramework/ApiController.php b/lib/public/AppFramework/ApiController.php
index dae80456e26..729582c8505 100644
--- a/lib/public/AppFramework/ApiController.php
+++ b/lib/public/AppFramework/ApiController.php
@@ -58,9 +58,8 @@ abstract class ApiController extends Controller {
#[PublicPage]
#[NoAdminRequired]
public function preflightedCors() {
- if (isset($this->request->server['HTTP_ORIGIN'])) {
- $origin = $this->request->server['HTTP_ORIGIN'];
- } else {
+ $origin = $this->request->getHeader('origin');
+ if ($origin === '') {
$origin = '*';
}
diff --git a/lib/public/AppFramework/App.php b/lib/public/AppFramework/App.php
index 06404baea70..2cf976ce90a 100644
--- a/lib/public/AppFramework/App.php
+++ b/lib/public/AppFramework/App.php
@@ -9,10 +9,10 @@ declare(strict_types=1);
*/
namespace OCP\AppFramework;
-use OC\AppFramework\Routing\RouteConfig;
-use OC\Route\Router;
+use OC\AppFramework\Utility\SimpleContainer;
use OC\ServerContainer;
-use OCP\Route\IRouter;
+use OCP\IConfig;
+use OCP\Server;
use Psr\Log\LoggerInterface;
/**
@@ -47,7 +47,7 @@ class App {
* @since 6.0.0
*/
public function __construct(string $appName, array $urlParams = []) {
- $runIsSetupDirectly = \OC::$server->getConfig()->getSystemValueBool('debug')
+ $runIsSetupDirectly = Server::get(IConfig::class)->getSystemValueBool('debug')
&& !ini_get('zend.exception_ignore_args');
if ($runIsSetupDirectly) {
@@ -70,11 +70,18 @@ class App {
$step['args'][1] === $classNameParts[1]) {
$setUpViaQuery = true;
break;
+ } elseif (isset($step['class'], $step['function'], $step['args'][0]) &&
+ $step['class'] === SimpleContainer::class &&
+ preg_match('/{closure:OC\\\\AppFramework\\\\Utility\\\\SimpleContainer::buildClass\\(\\):\\d+}/', $step['function']) &&
+ $step['args'][0] === $this) {
+ /* We are setup through a lazy ghost, fine */
+ $setUpViaQuery = true;
+ break;
}
}
if (!$setUpViaQuery && $applicationClassName !== \OCP\AppFramework\App::class) {
- \OCP\Server::get(LoggerInterface::class)->error($e->getMessage(), [
+ Server::get(LoggerInterface::class)->error($e->getMessage(), [
'app' => $appName,
'exception' => $e,
]);
@@ -97,35 +104,6 @@ class App {
}
/**
- * This function is to be called to create single routes and restful routes based on the given $routes array.
- *
- * Example code in routes.php of tasks app (it will register two restful resources):
- * $routes = array(
- * 'resources' => array(
- * 'lists' => array('url' => '/tasklists'),
- * 'tasks' => array('url' => '/tasklists/{listId}/tasks')
- * )
- * );
- *
- * $a = new TasksApp();
- * $a->registerRoutes($this, $routes);
- *
- * @param \OCP\Route\IRouter $router
- * @param array $routes
- * @since 6.0.0
- * @suppress PhanAccessMethodInternal
- * @deprecated 20.0.0 Just return an array from your routes.php
- */
- public function registerRoutes(IRouter $router, array $routes) {
- if (!($router instanceof Router)) {
- throw new \RuntimeException('Can only setup routes with real router');
- }
-
- $routeConfig = new RouteConfig($this->container, $router, $routes);
- $routeConfig->register();
- }
-
- /**
* This function is called by the routing component to fire up the frameworks dispatch mechanism.
*
* Example code in routes.php of the task app:
diff --git a/lib/public/AppFramework/Http/Attribute/RequestHeader.php b/lib/public/AppFramework/Http/Attribute/RequestHeader.php
new file mode 100644
index 00000000000..1d0fbbfa0c3
--- /dev/null
+++ b/lib/public/AppFramework/Http/Attribute/RequestHeader.php
@@ -0,0 +1,34 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace OCP\AppFramework\Http\Attribute;
+
+use Attribute;
+
+/**
+ * This attribute allows documenting request headers and is primarily intended for OpenAPI documentation.
+ * It should be added whenever you use a request header in a controller method, in order to properly describe the header and its functionality.
+ * There are no checks that ensure the header is set, so you will still need to do this yourself in the controller method.
+ *
+ * @since 32.0.0
+ */
+#[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
+class RequestHeader {
+ /**
+ * @param lowercase-string $name The name of the request header
+ * @param non-empty-string $description The description of the request header
+ * @param bool $indirect Allow indirect usage of the header for example in a middleware. Enabling this turns off the check which ensures that the header must be referenced in the controller method.
+ */
+ public function __construct(
+ protected string $name,
+ protected string $description,
+ protected bool $indirect = false,
+ ) {
+ }
+}
diff --git a/lib/public/AppFramework/Http/RedirectToDefaultAppResponse.php b/lib/public/AppFramework/Http/RedirectToDefaultAppResponse.php
index 1681b39ce50..0a0c04f671d 100644
--- a/lib/public/AppFramework/Http/RedirectToDefaultAppResponse.php
+++ b/lib/public/AppFramework/Http/RedirectToDefaultAppResponse.php
@@ -30,8 +30,7 @@ class RedirectToDefaultAppResponse extends RedirectResponse {
* @deprecated 23.0.0 Use RedirectResponse() with IURLGenerator::linkToDefaultPageUrl() instead
*/
public function __construct(int $status = Http::STATUS_SEE_OTHER, array $headers = []) {
- /** @var IURLGenerator $urlGenerator */
- $urlGenerator = \OC::$server->get(IURLGenerator::class);
+ $urlGenerator = \OCP\Server::get(IURLGenerator::class);
parent::__construct($urlGenerator->linkToDefaultPageUrl(), $status, $headers);
}
}
diff --git a/lib/public/AppFramework/Http/Response.php b/lib/public/AppFramework/Http/Response.php
index 6fc3d4b98ea..bdebb12c00d 100644
--- a/lib/public/AppFramework/Http/Response.php
+++ b/lib/public/AppFramework/Http/Response.php
@@ -93,11 +93,10 @@ class Response {
// Set expires header
$expires = new \DateTime();
- /** @var ITimeFactory $time */
$time = \OCP\Server::get(ITimeFactory::class);
$expires->setTimestamp($time->getTime());
$expires->add(new \DateInterval('PT' . $cacheSeconds . 'S'));
- $this->addHeader('Expires', $expires->format(\DateTimeInterface::RFC2822));
+ $this->addHeader('Expires', $expires->format(\DateTimeInterface::RFC7231));
} else {
$this->addHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
unset($this->headers['Expires']);
@@ -184,10 +183,10 @@ class Response {
if ($this->status === Http::STATUS_NOT_MODIFIED
&& stripos($name, 'x-') === 0) {
/** @var IConfig $config */
- $config = \OC::$server->get(IConfig::class);
+ $config = \OCP\Server::get(IConfig::class);
if ($config->getSystemValueBool('debug', false)) {
- \OC::$server->get(LoggerInterface::class)->error('Setting custom header on a 304 is not supported (Header: {header})', [
+ \OCP\Server::get(LoggerInterface::class)->error('Setting custom header on a 304 is not supported (Header: {header})', [
'header' => $name,
]);
}
@@ -229,7 +228,7 @@ class Response {
/**
* @psalm-suppress UndefinedClass
*/
- $request = \OC::$server->get(IRequest::class);
+ $request = \OCP\Server::get(IRequest::class);
$mergeWith = [
'X-Request-Id' => $request->getId(),
'Cache-Control' => 'no-cache, no-store, must-revalidate',
@@ -239,7 +238,7 @@ class Response {
];
if ($this->lastModified) {
- $mergeWith['Last-Modified'] = $this->lastModified->format(\DateTimeInterface::RFC2822);
+ $mergeWith['Last-Modified'] = $this->lastModified->format(\DateTimeInterface::RFC7231);
}
if ($this->ETag) {
diff --git a/lib/public/AppFramework/Http/Template/PublicTemplateResponse.php b/lib/public/AppFramework/Http/Template/PublicTemplateResponse.php
index ef5d2f67f7e..a620f44e677 100644
--- a/lib/public/AppFramework/Http/Template/PublicTemplateResponse.php
+++ b/lib/public/AppFramework/Http/Template/PublicTemplateResponse.php
@@ -44,6 +44,7 @@ class PublicTemplateResponse extends TemplateResponse {
) {
parent::__construct($appName, $templateName, $params, 'public', $status, $headers);
\OCP\Util::addScript('core', 'public-page-menu');
+ \OCP\Util::addScript('core', 'public-page-user-menu');
$state = \OCP\Server::get(IInitialStateService::class);
$state->provideLazyInitialState('core', 'public-page-menu', function () {
diff --git a/lib/public/Calendar/CalendarExportOptions.php b/lib/public/Calendar/CalendarExportOptions.php
new file mode 100644
index 00000000000..bf21dd85ae4
--- /dev/null
+++ b/lib/public/Calendar/CalendarExportOptions.php
@@ -0,0 +1,68 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Calendar;
+
+/**
+ * Calendar Export Options
+ *
+ * @since 32.0.0
+ */
+final class CalendarExportOptions {
+
+ /** @var 'ical'|'jcal'|'xcal' */
+ private string $format = 'ical';
+ private ?string $rangeStart = null;
+ private ?int $rangeCount = null;
+
+ /**
+ * Gets the export format
+ *
+ * @return 'ical'|'jcal'|'xcal' (defaults to ical)
+ */
+ public function getFormat(): string {
+ return $this->format;
+ }
+
+ /**
+ * Sets the export format
+ *
+ * @param 'ical'|'jcal'|'xcal' $format
+ */
+ public function setFormat(string $format): void {
+ $this->format = $format;
+ }
+
+ /**
+ * Gets the start of the range to export
+ */
+ public function getRangeStart(): ?string {
+ return $this->rangeStart;
+ }
+
+ /**
+ * Sets the start of the range to export
+ */
+ public function setRangeStart(?string $rangeStart): void {
+ $this->rangeStart = $rangeStart;
+ }
+
+ /**
+ * Gets the number of objects to export
+ */
+ public function getRangeCount(): ?int {
+ return $this->rangeCount;
+ }
+
+ /**
+ * Sets the number of objects to export
+ */
+ public function setRangeCount(?int $rangeCount): void {
+ $this->rangeCount = $rangeCount;
+ }
+}
diff --git a/lib/public/Calendar/ICalendar.php b/lib/public/Calendar/ICalendar.php
index 2dfc1ca632f..50152d1240b 100644
--- a/lib/public/Calendar/ICalendar.php
+++ b/lib/public/Calendar/ICalendar.php
@@ -8,10 +8,18 @@ declare(strict_types=1);
*/
namespace OCP\Calendar;
+use DateTimeInterface;
+
/**
* Interface ICalendar
*
* @since 13.0.0
+ *
+ * @psalm-type CalendarSearchOptions = array{
+ * timerange?: array{start?: DateTimeInterface, end?: DateTimeInterface},
+ * uid?: string,
+ * types?: string[],
+ * }
*/
interface ICalendar {
/**
@@ -41,13 +49,63 @@ interface ICalendar {
public function getDisplayColor(): ?string;
/**
- * @param string $pattern which should match within the $searchProperties
- * @param array $searchProperties defines the properties within the query pattern should match
- * @param array $options - optional parameters:
- * ['timerange' => ['start' => new DateTime(...), 'end' => new DateTime(...)]]
- * @param int|null $limit - limit number of search results
- * @param int|null $offset - offset for paging of search results
- * @return array an array of events/journals/todos which are arrays of key-value-pairs. the events are sorted by start date (closest first, furthest last)
+ * Search the current calendar for matching events.
+ *
+ * This method searches for events in the calendar that match a given pattern within specified properties.
+ * The search is case-insensitive. It supports optional parameters such as a time range, limit, and offset.
+ * The results are sorted by start date, with the closest events appearing first.
+ *
+ * @param string $pattern A string to search for within the events. The search is done case-insensitive.
+ * @param array $searchProperties Defines the properties within which the pattern should match.
+ * @param array $options Optional parameters for the search:
+ * - 'timerange' element that can have 'start' (DateTimeInterface), 'end' (DateTimeInterface), or both.
+ * - 'uid' element to look for events with a given uid.
+ * - 'types' element to only return events for a given type (e.g. VEVENT or VTODO)
+ * @psalm-param CalendarSearchOptions $options
+ * @param int|null $limit Limit the number of search results.
+ * @param int|null $offset For paging of search results.
+ * @return array An array of events/journals/todos which are arrays of key-value-pairs. The events are sorted by start date (closest first, furthest last).
+ *
+ * Implementation Details:
+ *
+ * An event can consist of many sub-events, typically the case for events with recurrence rules. On a database level,
+ * there's only one event stored (with a matching first occurrence and last occurrence timestamp). Expanding an event
+ * into sub-events is done on the backend level. Using limit, offset, and timerange comes with some drawbacks.
+ * When asking the database for events, the result is ordered by the primary key to guarantee a stable order.
+ * After expanding the events into sub-events, they are sorted by the date (closest to furthest).
+ *
+ * Usage Examples:
+ *
+ * 1) Find 7 events within the next two weeks:
+ *
+ * $dateTime = (new DateTimeImmutable())->setTimestamp($this->timeFactory->getTime());
+ * $inTwoWeeks = $dateTime->add(new DateInterval('P14D'));
+ *
+ * $calendar->search(
+ * '',
+ * [],
+ * ['timerange' => ['start' => $dateTime, 'end' => $inTwoWeeks]],
+ * 7
+ * );
+ *
+ * Note: When combining timerange and limit, it's possible that the expected outcome is not in the order you would expect.
+ *
+ * Example: Create 7 events for tomorrow, starting from 11:00, 30 minutes each. Then create an 8th event for tomorrow at 10:00.
+ * The above code will list the event at 11:00 first, missing the event at 10:00. The reason is the ordering by the primary key
+ * and expanding on the backend level. This is a technical limitation. The easiest workaround is to fetch more events
+ * than you actually need, with the downside of needing more resources.
+ *
+ * Related:
+ * - https://github.com/nextcloud/server/pull/45222
+ * - https://github.com/nextcloud/server/issues/53002
+ *
+ * 2) Find all events where the location property contains the string 'Berlin':
+ *
+ * $calendar->search(
+ * 'Berlin',
+ * ['LOCATION']
+ * );
+ *
* @since 13.0.0
*/
public function search(string $pattern, array $searchProperties = [], array $options = [], ?int $limit = null, ?int $offset = null): array;
diff --git a/lib/public/Calendar/ICalendarExport.php b/lib/public/Calendar/ICalendarExport.php
new file mode 100644
index 00000000000..61b286e1668
--- /dev/null
+++ b/lib/public/Calendar/ICalendarExport.php
@@ -0,0 +1,31 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Calendar;
+
+use Generator;
+
+/**
+ * ICalendar Interface Extension to export data
+ *
+ * @since 32.0.0
+ */
+interface ICalendarExport {
+
+ /**
+ * Export objects
+ *
+ * @since 32.0.0
+ *
+ * @param CalendarExportOptions|null $options
+ *
+ * @return Generator<\Sabre\VObject\Component\VCalendar>
+ */
+ public function export(?CalendarExportOptions $options): Generator;
+
+}
diff --git a/lib/public/Calendar/ICalendarIsEnabled.php b/lib/public/Calendar/ICalendarIsEnabled.php
new file mode 100644
index 00000000000..868159d208f
--- /dev/null
+++ b/lib/public/Calendar/ICalendarIsEnabled.php
@@ -0,0 +1,24 @@
+<?php
+
+declare(strict_types=1);
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Calendar;
+
+/**
+ * ICalendar Interface Extension
+ *
+ * @since 32.0.0
+ */
+interface ICalendarIsEnabled {
+
+ /**
+ * Indicates whether the calendar is enabled
+ *
+ * @since 32.0.0
+ */
+ public function isEnabled(): bool;
+
+}
diff --git a/lib/public/Color.php b/lib/public/Color.php
index c8ba3a1ff15..5523dbd94cb 100644
--- a/lib/public/Color.php
+++ b/lib/public/Color.php
@@ -125,7 +125,7 @@ class Color {
* Calculate steps between two Colors
* @param int $steps start color
* @param Color[] $ends end color
- * @return array{0: int, 1: int, 2: int} [r,g,b] steps for each color to go from $steps to $ends
+ * @return array{0: float, 1: float, 2: float} [r,g,b] steps for each color to go from $steps to $ends
* @since 25.0.0
*/
private static function stepCalc(int $steps, array $ends): array {
diff --git a/lib/public/Constants.php b/lib/public/Constants.php
index 62772d195b2..8d38ade7baf 100644
--- a/lib/public/Constants.php
+++ b/lib/public/Constants.php
@@ -18,20 +18,20 @@ namespace OCP;
*/
class Constants {
/**
- * CRUDS permissions.
* @since 8.0.0
*/
- public const PERMISSION_CREATE = 4;
+ public const PERMISSION_READ = 1;
/**
* @since 8.0.0
*/
- public const PERMISSION_READ = 1;
+ public const PERMISSION_UPDATE = 2;
/**
+ * CRUDS permissions.
* @since 8.0.0
*/
- public const PERMISSION_UPDATE = 2;
+ public const PERMISSION_CREATE = 4;
/**
* @since 8.0.0
diff --git a/lib/public/Defaults.php b/lib/public/Defaults.php
index 9242a230024..6de22caa41e 100644
--- a/lib/public/Defaults.php
+++ b/lib/public/Defaults.php
@@ -29,7 +29,7 @@ class Defaults {
*/
public function __construct(?\OC_Defaults $defaults = null) {
if ($defaults === null) {
- $defaults = \OC::$server->get('ThemingDefaults');
+ $defaults = \OCP\Server::get('ThemingDefaults');
}
$this->defaults = $defaults;
}
diff --git a/lib/public/Diagnostics/IQueryLogger.php b/lib/public/Diagnostics/IQueryLogger.php
index 1973168803d..07c999023da 100644
--- a/lib/public/Diagnostics/IQueryLogger.php
+++ b/lib/public/Diagnostics/IQueryLogger.php
@@ -31,7 +31,7 @@ interface IQueryLogger extends SQLLogger {
* Mark the end of the current active query. Ending query should store \OCP\Diagnostics\IQuery to
* be returned with getQueries() method.
*
- * @return mixed
+ * @return void
* @since 8.0.0
*/
public function stopQuery();
diff --git a/lib/public/Encryption/Exceptions/InvalidHeaderException.php b/lib/public/Encryption/Exceptions/InvalidHeaderException.php
new file mode 100644
index 00000000000..f7213577fb6
--- /dev/null
+++ b/lib/public/Encryption/Exceptions/InvalidHeaderException.php
@@ -0,0 +1,17 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+namespace OCP\Encryption\Exceptions;
+
+use OCP\HintException;
+
+/**
+ * Class InvalidHeaderException
+ *
+ * @since 32.0.0
+ */
+class InvalidHeaderException extends HintException {
+}
diff --git a/lib/public/EventDispatcher/GenericEvent.php b/lib/public/EventDispatcher/GenericEvent.php
index fb0a7677672..7e646c4d6a7 100644
--- a/lib/public/EventDispatcher/GenericEvent.php
+++ b/lib/public/EventDispatcher/GenericEvent.php
@@ -18,10 +18,12 @@ use function array_key_exists;
/**
* Class GenericEvent
*
- * convenience reimplementation of \Symfony\Component\GenericEvent against
+ * convenience re-implementation of \Symfony\Component\GenericEvent against
* \OCP\EventDispatcher\Event
*
* @since 18.0.0
+ * @template-implements ArrayAccess<array-key, mixed>
+ * @template-implements IteratorAggregate<array-key, mixed>
* @deprecated 22.0.0 use \OCP\EventDispatcher\Event
*/
class GenericEvent extends Event implements ArrayAccess, IteratorAggregate {
diff --git a/lib/public/Files.php b/lib/public/Files.php
index 62c41c4ada1..3df3152b0ef 100644
--- a/lib/public/Files.php
+++ b/lib/public/Files.php
@@ -9,6 +9,8 @@
namespace OCP;
+use OCP\Files\IMimeTypeDetector;
+
/**
* This class provides access to the internal filesystem abstraction layer. Use
* this class exclusively if you want to access files
@@ -18,12 +20,44 @@ namespace OCP;
class Files {
/**
* Recursive deletion of folders
+ *
+ * @param string $dir path to the folder
+ * @param bool $deleteSelf if set to false only the content of the folder will be deleted
* @return bool
* @since 5.0.0
+ * @since 32.0.0 added the $deleteSelf parameter
* @deprecated 14.0.0
*/
- public static function rmdirr($dir) {
- return \OC_Helper::rmdirr($dir);
+ public static function rmdirr($dir, bool $deleteSelf = true) {
+ if (is_dir($dir)) {
+ $files = new \RecursiveIteratorIterator(
+ new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS),
+ \RecursiveIteratorIterator::CHILD_FIRST
+ );
+
+ foreach ($files as $fileInfo) {
+ /** @var \SplFileInfo $fileInfo */
+ if ($fileInfo->isLink()) {
+ unlink($fileInfo->getPathname());
+ } elseif ($fileInfo->isDir()) {
+ rmdir($fileInfo->getRealPath());
+ } else {
+ unlink($fileInfo->getRealPath());
+ }
+ }
+ if ($deleteSelf) {
+ rmdir($dir);
+ }
+ } elseif (file_exists($dir)) {
+ if ($deleteSelf) {
+ unlink($dir);
+ }
+ }
+ if (!$deleteSelf) {
+ return true;
+ }
+
+ return !file_exists($dir);
}
/**
@@ -35,7 +69,7 @@ class Files {
* @deprecated 14.0.0
*/
public static function getMimeType($path) {
- return \OC::$server->getMimeTypeDetector()->detect($path);
+ return Server::get(IMimeTypeDetector::class)->detect($path);
}
/**
@@ -51,15 +85,45 @@ class Files {
/**
* Copy the contents of one stream to another
+ *
+ * @template T of null|true
* @param resource $source
* @param resource $target
- * @return int the number of bytes copied
+ * @param T $includeResult
+ * @return int|array
+ * @psalm-return (T is true ? array{0: int, 1: bool} : int)
* @since 5.0.0
+ * @since 32.0.0 added $includeResult parameter
* @deprecated 14.0.0
*/
- public static function streamCopy($source, $target) {
- [$count, ] = \OC_Helper::streamCopy($source, $target);
- return $count;
+ public static function streamCopy($source, $target, ?bool $includeResult = null) {
+ if (!$source or !$target) {
+ return $includeResult ? [0, false] : 0;
+ }
+
+ $bufSize = 8192;
+ $count = 0;
+ $result = true;
+ while (!feof($source)) {
+ $buf = fread($source, $bufSize);
+ if ($buf === false) {
+ $result = false;
+ break;
+ }
+
+ $bytesWritten = fwrite($target, $buf);
+ if ($bytesWritten !== false) {
+ $count += $bytesWritten;
+ }
+
+ if ($bytesWritten === false
+ || ($bytesWritten < $bufSize && $bytesWritten < strlen($buf))
+ ) {
+ $result = false;
+ break;
+ }
+ }
+ return $includeResult ? [$count, $result] : $count;
}
/**
@@ -73,16 +137,4 @@ class Files {
public static function buildNotExistingFileName($path, $filename) {
return \OC_Helper::buildNotExistingFileName($path, $filename);
}
-
- /**
- * Gets the Storage for an app - creates the needed folder if they are not
- * existent
- * @param string $app
- * @return \OC\Files\View
- * @since 5.0.0
- * @deprecated 14.0.0 use IAppData instead
- */
- public static function getStorage($app) {
- return \OC_App::getStorage($app);
- }
}
diff --git a/lib/public/Files/Config/Event/UserMountAddedEvent.php b/lib/public/Files/Config/Event/UserMountAddedEvent.php
new file mode 100644
index 00000000000..f2846f2ff2b
--- /dev/null
+++ b/lib/public/Files/Config/Event/UserMountAddedEvent.php
@@ -0,0 +1,27 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace OCP\Files\Config\Event;
+
+use OCP\EventDispatcher\Event;
+use OCP\Files\Config\ICachedMountInfo;
+use OCP\Files\Mount\IMountPoint;
+
+/**
+ * Event emitted when a user mount was added.
+ *
+ * @since 32.0.0
+ */
+class UserMountAddedEvent extends Event {
+ public function __construct(
+ public readonly IMountPoint|ICachedMountInfo $mountPoint,
+ ) {
+ parent::__construct();
+ }
+}
diff --git a/lib/public/Files/Config/Event/UserMountRemovedEvent.php b/lib/public/Files/Config/Event/UserMountRemovedEvent.php
new file mode 100644
index 00000000000..bdf264c9c4b
--- /dev/null
+++ b/lib/public/Files/Config/Event/UserMountRemovedEvent.php
@@ -0,0 +1,27 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace OCP\Files\Config\Event;
+
+use OCP\EventDispatcher\Event;
+use OCP\Files\Config\ICachedMountInfo;
+use OCP\Files\Mount\IMountPoint;
+
+/**
+ * Event emitted when a user mount was removed.
+ *
+ * @since 32.0.0
+ */
+class UserMountRemovedEvent extends Event {
+ public function __construct(
+ public readonly IMountPoint|ICachedMountInfo $mountPoint,
+ ) {
+ parent::__construct();
+ }
+}
diff --git a/lib/public/Files/Config/Event/UserMountUpdatedEvent.php b/lib/public/Files/Config/Event/UserMountUpdatedEvent.php
new file mode 100644
index 00000000000..36d9cd55562
--- /dev/null
+++ b/lib/public/Files/Config/Event/UserMountUpdatedEvent.php
@@ -0,0 +1,28 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace OCP\Files\Config\Event;
+
+use OCP\EventDispatcher\Event;
+use OCP\Files\Config\ICachedMountInfo;
+use OCP\Files\Mount\IMountPoint;
+
+/**
+ * Event emitted when a user mount was moved.
+ *
+ * @since 32.0.0
+ */
+class UserMountUpdatedEvent extends Event {
+ public function __construct(
+ public readonly IMountPoint|ICachedMountInfo $oldMountPoint,
+ public readonly IMountPoint|ICachedMountInfo $newMountPoint,
+ ) {
+ parent::__construct();
+ }
+}
diff --git a/lib/public/Files/Folder.php b/lib/public/Files/Folder.php
index 3128a17c10c..a35d2d78bc9 100644
--- a/lib/public/Files/Folder.php
+++ b/lib/public/Files/Folder.php
@@ -199,4 +199,15 @@ interface Folder extends Node {
* @since 9.1.0
*/
public function getRecent($limit, $offset = 0);
+
+ /**
+ * Verify if the given path is valid and allowed from this folder.
+ *
+ * @param string $path the path from this folder
+ * @param string $fileName
+ * @param bool $readonly Check only if the path is allowed for read-only access
+ * @throws InvalidPathException
+ * @since 32.0.0
+ */
+ public function verifyPath($fileName, $readonly = false): void;
}
diff --git a/lib/public/Files/IFilenameValidator.php b/lib/public/Files/IFilenameValidator.php
index 2bd3bb945dc..9b7fa1e2e2e 100644
--- a/lib/public/Files/IFilenameValidator.php
+++ b/lib/public/Files/IFilenameValidator.php
@@ -36,4 +36,17 @@ interface IFilenameValidator {
* @since 30.0.0
*/
public function validateFilename(string $filename): void;
+
+ /**
+ * Sanitize a give filename to comply with admin setup naming constrains.
+ *
+ * If no sanitizing is needed the same name is returned.
+ *
+ * @param string $name The filename to sanitize
+ * @param null|string $charReplacement Character to use for replacing forbidden ones - by default underscore, dash or space is used if allowed.
+ * @throws \InvalidArgumentException if no character replacement was given (and the default could not be applied) or the replacement is not valid.
+ * @since 32.0.0
+ */
+ public function sanitizeFilename(string $name, ?string $charReplacement = null): string;
+
}
diff --git a/lib/public/Files/IMimeTypeDetector.php b/lib/public/Files/IMimeTypeDetector.php
index 1bc9c514610..1e87cf932ce 100644
--- a/lib/public/Files/IMimeTypeDetector.php
+++ b/lib/public/Files/IMimeTypeDetector.php
@@ -87,4 +87,12 @@ interface IMimeTypeDetector {
* @since 32.0.0
*/
public function getAllMappings(): array;
+
+ /**
+ * Get all human readable mime names
+ *
+ * @return array<string,string>
+ * @since 32.0.0
+ */
+ public function getAllNamings(): array;
}
diff --git a/lib/public/Files/ObjectStore/IObjectStoreMetaData.php b/lib/public/Files/ObjectStore/IObjectStoreMetaData.php
index 8359e83f573..9683873be36 100644
--- a/lib/public/Files/ObjectStore/IObjectStoreMetaData.php
+++ b/lib/public/Files/ObjectStore/IObjectStoreMetaData.php
@@ -9,7 +9,7 @@ namespace OCP\Files\ObjectStore;
/**
* Interface IObjectStoreMetaData
*
- * @psalm-type ObjectMetaData = array{mtime?: \DateTime, etag?: string, size?: int, mimetype?: string, filename?: string}
+ * @psalm-type ObjectMetaData = array{mtime?: \DateTime, etag?: string, size?: int, mimetype?: string, filename?: string, original-path?: string, original-storage?: string}
*
* @since 32.0.0
*/
@@ -35,4 +35,13 @@ interface IObjectStoreMetaData {
* @since 32.0.0
*/
public function listObjects(string $prefix = ''): \Iterator;
+
+ /**
+ * @param string $urn the unified resource name used to identify the object
+ * @param resource $stream stream with the data to write
+ * @param ObjectMetaData $metaData the metadata to set for the object
+ * @throws \Exception when something goes wrong, message will be logged
+ * @since 32.0.0
+ */
+ public function writeObjectWithMetaData(string $urn, $stream, array $metaData): void;
}
diff --git a/lib/public/Files/SimpleFS/ISimpleFile.php b/lib/public/Files/SimpleFS/ISimpleFile.php
index 2682c22580d..10cdc0a919d 100644
--- a/lib/public/Files/SimpleFS/ISimpleFile.php
+++ b/lib/public/Files/SimpleFS/ISimpleFile.php
@@ -5,8 +5,10 @@
*/
namespace OCP\Files\SimpleFS;
+use OCP\Files\GenericFileException;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
+use OCP\Lock\LockedException;
/**
* This interface allows to manage simple files.
@@ -49,8 +51,10 @@ interface ISimpleFile {
/**
* Get the content
*
- * @throws NotPermittedException
+ * @throws GenericFileException
+ * @throws LockedException
* @throws NotFoundException
+ * @throws NotPermittedException
* @since 11.0.0
*/
public function getContent(): string;
@@ -59,8 +63,10 @@ interface ISimpleFile {
* Overwrite the file
*
* @param string|resource $data
- * @throws NotPermittedException
+ * @throws GenericFileException
+ * @throws LockedException
* @throws NotFoundException
+ * @throws NotPermittedException
* @since 11.0.0
*/
public function putContent($data): void;
diff --git a/lib/public/Files/Template/BeforeGetTemplatesEvent.php b/lib/public/Files/Template/BeforeGetTemplatesEvent.php
index 006163c5f7f..9fb7453a50c 100644
--- a/lib/public/Files/Template/BeforeGetTemplatesEvent.php
+++ b/lib/public/Files/Template/BeforeGetTemplatesEvent.php
@@ -17,16 +17,19 @@ use OCP\EventDispatcher\Event;
class BeforeGetTemplatesEvent extends Event {
/** @var array<Template> */
private array $templates;
+ /** @var bool */
+ private bool $withFields;
/**
* @param array<Template> $templates
*
* @since 30.0.0
*/
- public function __construct(array $templates) {
+ public function __construct(array $templates, bool $withFields = false) {
parent::__construct();
$this->templates = $templates;
+ $this->withFields = $withFields;
}
/**
@@ -37,4 +40,13 @@ class BeforeGetTemplatesEvent extends Event {
public function getTemplates(): array {
return $this->templates;
}
+
+ /**
+ * @return bool
+ *
+ * @since 32.0.0
+ */
+ public function shouldGetFields(): bool {
+ return $this->withFields;
+ }
}
diff --git a/lib/public/Files/Template/ITemplateManager.php b/lib/public/Files/Template/ITemplateManager.php
index 9a81aa51ceb..df81bc5604e 100644
--- a/lib/public/Files/Template/ITemplateManager.php
+++ b/lib/public/Files/Template/ITemplateManager.php
@@ -39,6 +39,15 @@ interface ITemplateManager {
public function listTemplates(): array;
/**
+ * Get the fields for a given template
+ *
+ * @param int $fileId
+ * @return array
+ * @since 32.0.0
+ */
+ public function listTemplateFields(int $fileId): array;
+
+ /**
* @return bool
* @since 21.0.0
*/
diff --git a/lib/public/Files_FullTextSearch/Model/AFilesDocument.php b/lib/public/Files_FullTextSearch/Model/AFilesDocument.php
index ba5f504fccf..297d6bc6ffc 100644
--- a/lib/public/Files_FullTextSearch/Model/AFilesDocument.php
+++ b/lib/public/Files_FullTextSearch/Model/AFilesDocument.php
@@ -16,7 +16,7 @@ use OCP\FullTextSearch\Model\IIndexDocument;
* This is mostly used by 3rd party apps that want to complete the IIndexDocument
* with more information about a file before its index:
*
- * \OC::$server->getEventDispatcher()->addListener(
+ * \OCP\Server::get(IEventDispatcher::class)->addListener(
* '\OCA\Files_FullTextSearch::onFileIndexing',
* function(GenericEvent $e) {
* //@var \OCP\Files\Node $file
diff --git a/lib/public/Http/Client/IResponse.php b/lib/public/Http/Client/IResponse.php
index deec2cf97b1..53032ef2a37 100644
--- a/lib/public/Http/Client/IResponse.php
+++ b/lib/public/Http/Client/IResponse.php
@@ -15,8 +15,9 @@ namespace OCP\Http\Client;
*/
interface IResponse {
/**
- * @return string|resource
+ * @return null|resource|string
* @since 8.1.0
+ * @sicne 8.2.0 with stream enabled, the function returns null or a resource
*/
public function getBody();
diff --git a/lib/public/IAppConfig.php b/lib/public/IAppConfig.php
index f4210793476..fcc528fe11f 100644
--- a/lib/public/IAppConfig.php
+++ b/lib/public/IAppConfig.php
@@ -514,5 +514,5 @@ interface IAppConfig {
* @return array<string, string>
* @since 32.0.0
*/
- public function getAppInstalledVersions(): array;
+ public function getAppInstalledVersions(bool $onlyEnabled = false): array;
}
diff --git a/lib/public/IPreview.php b/lib/public/IPreview.php
index 6ab4af1b7ca..3c9eadd4577 100644
--- a/lib/public/IPreview.php
+++ b/lib/public/IPreview.php
@@ -71,12 +71,14 @@ interface IPreview {
* @param bool $crop
* @param string $mode
* @param string $mimeType To force a given mimetype for the file (files_versions needs this)
+ * @param bool $cacheResult Whether or not to cache the preview on the filesystem. Default to true. Can be useful to set to false to limit the amount of stored previews.
* @return ISimpleFile
* @throws NotFoundException
* @throws \InvalidArgumentException if the preview would be invalid (in case the original image is invalid)
* @since 11.0.0 - \InvalidArgumentException was added in 12.0.0
+ * @since 32.0.0 - getPreview($cacheResult) added the $cacheResult argument to the signature
*/
- public function getPreview(File $file, $width = -1, $height = -1, $crop = false, $mode = IPreview::MODE_FILL, $mimeType = null);
+ public function getPreview(File $file, $width = -1, $height = -1, $crop = false, $mode = IPreview::MODE_FILL, $mimeType = null, bool $cacheResult = true);
/**
* Returns true if the passed mime type is supported
@@ -90,10 +92,12 @@ interface IPreview {
* Check if a preview can be generated for a file
*
* @param \OCP\Files\FileInfo $file
+ * @param string|null $mimeType To force a given mimetype for the file
* @return bool
* @since 8.0.0
+ * @since 32.0.0 - isAvailable($mimeType) added the $mimeType argument to the signature
*/
- public function isAvailable(\OCP\Files\FileInfo $file);
+ public function isAvailable(\OCP\Files\FileInfo $file, ?string $mimeType = null);
/**
* Generates previews of a file
diff --git a/lib/public/IServerContainer.php b/lib/public/IServerContainer.php
index 82da8779a66..6d5095c92da 100644
--- a/lib/public/IServerContainer.php
+++ b/lib/public/IServerContainer.php
@@ -8,10 +8,6 @@ declare(strict_types=1);
*/
namespace OCP;
-use OCP\Federation\ICloudFederationFactory;
-use OCP\Federation\ICloudFederationProviderManager;
-use OCP\Log\ILogFactory;
-use OCP\Security\IContentSecurityPolicyManager;
use Psr\Container\ContainerInterface;
/**
@@ -26,35 +22,6 @@ use Psr\Container\ContainerInterface;
* @since 6.0.0
*/
interface IServerContainer extends ContainerInterface, IContainer {
- /**
- * The calendar manager will act as a broker between consumers for calendar information and
- * providers which actual deliver the calendar information.
- *
- * @return \OCP\Calendar\IManager
- * @since 13.0.0
- * @deprecated 20.0.0 have it injected or fetch it through \Psr\Container\ContainerInterface::get
- */
- public function getCalendarManager();
-
- /**
- * The calendar resource backend manager will act as a broker between consumers
- * for calendar resource information an providers which actual deliver the room information.
- *
- * @return \OCP\Calendar\Resource\IBackend
- * @since 14.0.0
- * @deprecated 20.0.0 have it injected or fetch it through \Psr\Container\ContainerInterface::get
- */
- public function getCalendarResourceBackendManager();
-
- /**
- * The calendar room backend manager will act as a broker between consumers
- * for calendar room information an providers which actual deliver the room information.
- *
- * @return \OCP\Calendar\Room\IBackend
- * @since 14.0.0
- * @deprecated 20.0.0 have it injected or fetch it through \Psr\Container\ContainerInterface::get
- */
- public function getCalendarRoomBackendManager();
/**
* The contacts manager will act as a broker between consumers for contacts information and
@@ -78,25 +45,6 @@ interface IServerContainer extends ContainerInterface, IContainer {
public function getRequest();
/**
- * Returns the preview manager which can create preview images for a given file
- *
- * @return \OCP\IPreview
- * @since 6.0.0
- * @deprecated 20.0.0 have it injected or fetch it through \Psr\Container\ContainerInterface::get
- */
- public function getPreviewManager();
-
- /**
- * Returns the tag manager which can get and set tags for different object types
- *
- * @see \OCP\ITagManager::load()
- * @return \OCP\ITagManager
- * @since 6.0.0
- * @deprecated 20.0.0 have it injected or fetch it through \Psr\Container\ContainerInterface::get
- */
- public function getTagManager();
-
- /**
* Returns the root folder of ownCloud's data directory
*
* @return \OCP\Files\IRootFolder
@@ -144,15 +92,6 @@ interface IServerContainer extends ContainerInterface, IContainer {
public function getUserSession();
/**
- * Returns the navigation manager
- *
- * @return \OCP\INavigationManager
- * @since 6.0.0
- * @deprecated 20.0.0 have it injected or fetch it through \Psr\Container\ContainerInterface::get
- */
- public function getNavigationManager();
-
- /**
* Returns the config manager
*
* @return \OCP\IConfig
@@ -189,24 +128,6 @@ interface IServerContainer extends ContainerInterface, IContainer {
public function getSecureRandom();
/**
- * Returns a CredentialsManager instance
- *
- * @return \OCP\Security\ICredentialsManager
- * @since 9.0.0
- * @deprecated 20.0.0 have it injected or fetch it through \Psr\Container\ContainerInterface::get
- */
- public function getCredentialsManager();
-
- /**
- * Returns the app config manager
- *
- * @return \OCP\IAppConfig
- * @since 7.0.0
- * @deprecated 20.0.0 have it injected or fetch it through \Psr\Container\ContainerInterface::get
- */
- public function getAppConfig();
-
- /**
* @return \OCP\L10N\IFactory
* @since 8.2.0
* @deprecated 20.0.0 have it injected or fetch it through \Psr\Container\ContainerInterface::get
@@ -238,13 +159,6 @@ interface IServerContainer extends ContainerInterface, IContainer {
public function getEncryptionFilesHelper();
/**
- * @return \OCP\Encryption\Keys\IStorage
- * @since 8.1.0
- * @deprecated 20.0.0 have it injected or fetch it through \Psr\Container\ContainerInterface::get
- */
- public function getEncryptionKeyStorage();
-
- /**
* Returns the URL generator
*
* @return \OCP\IURLGenerator
@@ -299,15 +213,6 @@ interface IServerContainer extends ContainerInterface, IContainer {
public function getDatabaseConnection();
/**
- * Returns an avatar manager, used for avatar functionality
- *
- * @return \OCP\IAvatarManager
- * @since 6.0.0
- * @deprecated 20.0.0 have it injected or fetch it through \Psr\Container\ContainerInterface::get
- */
- public function getAvatarManager();
-
- /**
* Returns an job list for controlling background jobs
*
* @return \OCP\BackgroundJob\IJobList
@@ -317,24 +222,6 @@ interface IServerContainer extends ContainerInterface, IContainer {
public function getJobList();
/**
- * returns a log factory instance
- *
- * @return ILogFactory
- * @since 14.0.0
- * @deprecated 20.0.0 have it injected or fetch it through \Psr\Container\ContainerInterface::get
- */
- public function getLogFactory();
-
- /**
- * Returns a router for generating and matching urls
- *
- * @return \OCP\Route\IRouter
- * @since 7.0.0
- * @deprecated 20.0.0 have it injected or fetch it through \Psr\Container\ContainerInterface::get
- */
- public function getRouter();
-
- /**
* Get the certificate manager
*
* @return \OCP\ICertificateManager
@@ -344,35 +231,6 @@ interface IServerContainer extends ContainerInterface, IContainer {
public function getCertificateManager();
/**
- * Returns an instance of the HTTP client service
- *
- * @return \OCP\Http\Client\IClientService
- * @since 8.1.0
- * @deprecated 20.0.0 have it injected or fetch it through \Psr\Container\ContainerInterface::get
- */
- public function getHTTPClientService();
-
- /**
- * Get the active event logger
- *
- * @return \OCP\Diagnostics\IEventLogger
- * @since 8.0.0
- * @deprecated 20.0.0 have it injected or fetch it through \Psr\Container\ContainerInterface::get
- */
- public function getEventLogger();
-
- /**
- * Get the active query logger
- *
- * The returned logger only logs data when debug mode is enabled
- *
- * @return \OCP\Diagnostics\IQueryLogger
- * @since 8.0.0
- * @deprecated 20.0.0 have it injected or fetch it through \Psr\Container\ContainerInterface::get
- */
- public function getQueryLogger();
-
- /**
* Get the manager for temporary files and folders
*
* @return \OCP\ITempManager
@@ -400,28 +258,6 @@ interface IServerContainer extends ContainerInterface, IContainer {
public function getWebRoot();
/**
- * @return \OCP\Files\Config\IMountProviderCollection
- * @since 8.0.0
- * @deprecated 20.0.0 have it injected or fetch it through \Psr\Container\ContainerInterface::get
- */
- public function getMountProviderCollection();
-
- /**
- * Get the IniWrapper
- *
- * @return \bantu\IniGetWrapper\IniGetWrapper
- * @since 8.0.0
- * @deprecated 20.0.0 have it injected or fetch it through \Psr\Container\ContainerInterface::get
- */
- public function getIniWrapper();
- /**
- * @return \OCP\Command\IBus
- * @since 8.1.0
- * @deprecated 20.0.0 have it injected or fetch it through \Psr\Container\ContainerInterface::get
- */
- public function getCommandBus();
-
- /**
* Creates a new mailer
*
* @return \OCP\Mail\IMailer
@@ -440,13 +276,6 @@ interface IServerContainer extends ContainerInterface, IContainer {
public function getLockingProvider();
/**
- * @return \OCP\Files\Mount\IMountManager
- * @since 8.2.0
- * @deprecated 20.0.0 have it injected or fetch it through \Psr\Container\ContainerInterface::get
- */
- public function getMountManager();
-
- /**
* Get the MimeTypeDetector
*
* @return \OCP\Files\IMimeTypeDetector
@@ -474,108 +303,9 @@ interface IServerContainer extends ContainerInterface, IContainer {
public function getNotificationManager();
/**
- * @return \OCP\Comments\ICommentsManager
- * @since 9.0.0
- * @deprecated 20.0.0 have it injected or fetch it through \Psr\Container\ContainerInterface::get
- */
- public function getCommentsManager();
-
- /**
- * Returns the system-tag manager
- *
- * @return \OCP\SystemTag\ISystemTagManager
- *
- * @since 9.0.0
- * @deprecated 20.0.0 have it injected or fetch it through \Psr\Container\ContainerInterface::get
- */
- public function getSystemTagManager();
-
- /**
- * Returns the system-tag object mapper
- *
- * @return \OCP\SystemTag\ISystemTagObjectMapper
- *
- * @since 9.0.0
- * @deprecated 20.0.0 have it injected or fetch it through \Psr\Container\ContainerInterface::get
- */
- public function getSystemTagObjectMapper();
-
- /**
- * Returns the share manager
- *
- * @return \OCP\Share\IManager
- * @since 9.0.0
- * @deprecated 20.0.0 have it injected or fetch it through \Psr\Container\ContainerInterface::get
- */
- public function getShareManager();
-
- /**
- * @return IContentSecurityPolicyManager
- * @since 9.0.0
- * @deprecated 17.0.0 Use the AddContentSecurityPolicyEvent
- */
- public function getContentSecurityPolicyManager();
-
- /**
- * @return \OCP\IDateTimeZone
- * @since 8.0.0
- * @deprecated 20.0.0 have it injected or fetch it through \Psr\Container\ContainerInterface::get
- */
- public function getDateTimeZone();
-
- /**
- * @return \OCP\IDateTimeFormatter
- * @since 8.0.0
- * @deprecated 20.0.0 have it injected or fetch it through \Psr\Container\ContainerInterface::get
- */
- public function getDateTimeFormatter();
-
- /**
* @return \OCP\Federation\ICloudIdManager
* @since 12.0.0
* @deprecated 20.0.0 have it injected or fetch it through \Psr\Container\ContainerInterface::get
*/
public function getCloudIdManager();
-
- /**
- * @return \OCP\GlobalScale\IConfig
- * @since 14.0.0
- * @deprecated 20.0.0 have it injected or fetch it through \Psr\Container\ContainerInterface::get
- */
- public function getGlobalScaleConfig();
-
- /**
- * @return ICloudFederationFactory
- * @since 14.0.0
- * @deprecated 20.0.0 have it injected or fetch it through \Psr\Container\ContainerInterface::get
- */
- public function getCloudFederationFactory();
-
- /**
- * @return ICloudFederationProviderManager
- * @since 14.0.0
- * @deprecated 20.0.0 have it injected or fetch it through \Psr\Container\ContainerInterface::get
- */
- public function getCloudFederationProviderManager();
-
- /**
- * @return \OCP\Remote\Api\IApiFactory
- * @since 13.0.0
- * @deprecated 20.0.0 have it injected or fetch it through \Psr\Container\ContainerInterface::get
- */
- public function getRemoteApiFactory();
-
- /**
- * @return \OCP\Remote\IInstanceFactory
- * @since 13.0.0
- * @deprecated 20.0.0 have it injected or fetch it through \Psr\Container\ContainerInterface::get
- */
- public function getRemoteInstanceFactory();
-
- /**
- * @return \OCP\Files\Storage\IStorageFactory
- * @since 15.0.0
- * @deprecated 20.0.0 have it injected or fetch it through \Psr\Container\ContainerInterface::get
- */
- public function getStorageFactory();
}
diff --git a/lib/public/IUser.php b/lib/public/IUser.php
index 52f79083dc1..945e7e1602a 100644
--- a/lib/public/IUser.php
+++ b/lib/public/IUser.php
@@ -281,6 +281,15 @@ interface IUser {
public function getQuota();
/**
+ * Get the users' quota in machine readable form. If a specific quota is set
+ * for the user, then the quota is returned in bytes. Otherwise the default value is returned.
+ * If a default setting was not set, it is return as `\OCP\Files\FileInfo::SPACE_UNLIMITED`, i.e. quota is not limited.
+ *
+ * @since 32.0.0
+ */
+ public function getQuotaBytes(): int|float;
+
+ /**
* set the users' quota
*
* @param string $quota
diff --git a/lib/public/L10N/ILanguageIterator.php b/lib/public/L10N/ILanguageIterator.php
index cba0feefdcf..27f850d4235 100644
--- a/lib/public/L10N/ILanguageIterator.php
+++ b/lib/public/L10N/ILanguageIterator.php
@@ -21,7 +21,7 @@ namespace OCP\L10N;
* if settings are not present or truncating is not applicable, the iterator
* skips to the next valid item itself
*
- *
+ * @template-extends \Iterator<int, string>
* @since 14.0.0
*/
interface ILanguageIterator extends \Iterator {
@@ -36,22 +36,20 @@ interface ILanguageIterator extends \Iterator {
* Move forward to next element
*
* @since 14.0.0
- * @return void
*/
- #[\ReturnTypeWillChange]
- public function next();
+ public function next(): void;
/**
* Return the key of the current element
*
* @since 14.0.0
*/
- public function key():int;
+ public function key(): int;
/**
* Checks if current position is valid
*
* @since 14.0.0
*/
- public function valid():bool;
+ public function valid(): bool;
}
diff --git a/lib/public/Lock/LockedException.php b/lib/public/Lock/LockedException.php
index ce41d2d7242..799886a2dbb 100644
--- a/lib/public/Lock/LockedException.php
+++ b/lib/public/Lock/LockedException.php
@@ -24,6 +24,8 @@ class LockedException extends \Exception {
/** @var string|null */
private $existingLock;
+ private ?string $readablePath;
+
/**
* LockedException constructor.
*
@@ -34,6 +36,7 @@ class LockedException extends \Exception {
* @since 8.1.0
*/
public function __construct(string $path, ?\Exception $previous = null, ?string $existingLock = null, ?string $readablePath = null) {
+ $this->readablePath = $readablePath;
if ($readablePath) {
$message = "\"$path\"(\"$readablePath\") is locked";
} else {
@@ -62,4 +65,13 @@ class LockedException extends \Exception {
public function getExistingLock(): ?string {
return $this->existingLock;
}
+
+ /**
+ * @return ?string
+ * @since 32.0.0
+ */
+ public function getReadablePath(): ?string {
+ return $this->readablePath;
+ }
+
}
diff --git a/lib/public/Mail/IMailer.php b/lib/public/Mail/IMailer.php
index 18eaef541c0..277f7863184 100644
--- a/lib/public/Mail/IMailer.php
+++ b/lib/public/Mail/IMailer.php
@@ -14,7 +14,7 @@ namespace OCP\Mail;
*
* Example usage:
*
- * $mailer = \OC::$server->get(\OCP\Mail\IMailer::class);
+ * $mailer = \OCP\Server::get(\OCP\Mail\IMailer::class);
* $message = $mailer->createMessage();
* $message->setSubject('Your Subject');
* $message->setFrom(['cloud@domain.org' => 'Nextcloud Notifier']);
diff --git a/lib/public/OCM/ICapabilityAwareOCMProvider.php b/lib/public/OCM/ICapabilityAwareOCMProvider.php
new file mode 100644
index 00000000000..d3ad2e29932
--- /dev/null
+++ b/lib/public/OCM/ICapabilityAwareOCMProvider.php
@@ -0,0 +1,60 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\OCM;
+
+/**
+ * Version 1.1 and 1.2 extensions to the Open Cloud Mesh Discovery API
+ * @link https://github.com/cs3org/OCM-API/
+ * @since 32.0.0
+ */
+interface ICapabilityAwareOCMProvider extends IOCMProvider {
+ /**
+ * get the capabilities
+ *
+ * @return array
+ * @since 32.0.0
+ */
+ public function getCapabilities(): array;
+
+ /**
+ * get the provider name
+ *
+ * @return string
+ * @since 32.0.0
+ */
+ public function getProvider(): string;
+
+ /**
+ * returns the invite accept dialog
+ *
+ * @return string
+ * @since 32.0.0
+ */
+ public function getInviteAcceptDialog(): string;
+
+ /**
+ * set the capabilities
+ *
+ * @param array $capabilities
+ *
+ * @return $this
+ * @since 32.0.0
+ */
+ public function setCapabilities(array $capabilities): static;
+
+ /**
+ * set the invite accept dialog
+ *
+ * @param string $inviteAcceptDialog
+ *
+ * @return $this
+ * @since 32.0.0
+ */
+ public function setInviteAcceptDialog(string $inviteAcceptDialog): static;
+}
diff --git a/lib/public/OCM/IOCMProvider.php b/lib/public/OCM/IOCMProvider.php
index a267abc52d2..7141b0a9ab9 100644
--- a/lib/public/OCM/IOCMProvider.php
+++ b/lib/public/OCM/IOCMProvider.php
@@ -16,6 +16,7 @@ use OCP\OCM\Exceptions\OCMProviderException;
* Model based on the Open Cloud Mesh Discovery API
* @link https://github.com/cs3org/OCM-API/
* @since 28.0.0
+ * @deprecated 32.0.0 Please use {@see \OCP\OCM\ICapabilityAwareOCMProvider}
*/
interface IOCMProvider extends JsonSerializable {
/**
diff --git a/lib/public/Profiler/IProfile.php b/lib/public/Profiler/IProfile.php
index ddbad4b4388..89eb709d061 100644
--- a/lib/public/Profiler/IProfile.php
+++ b/lib/public/Profiler/IProfile.php
@@ -17,7 +17,7 @@ use OCP\DataCollector\IDataCollector;
*
* ```php
* <?php
- * $profiler = \OC::$server->get(IProfiler::class);
+ * $profiler = \OCP\Server::get(IProfiler::class);
* $profiles = $profiler->find('/settings/users', 10);
* ```
*
diff --git a/lib/public/Route/IRoute.php b/lib/public/Route/IRoute.php
index fffd4b9c1a1..7dba6225aff 100644
--- a/lib/public/Route/IRoute.php
+++ b/lib/public/Route/IRoute.php
@@ -34,8 +34,9 @@ interface IRoute {
* it is called directly
*
* @param string $file
- * @return void
+ * @return $this
* @since 7.0.0
+ * @deprecated 32.0.0 Use a proper controller instead
*/
public function actionInclude($file);
@@ -70,6 +71,7 @@ interface IRoute {
* This function is called with $class set to a callable or
* to the class with $function
* @since 7.0.0
+ * @deprecated 32.0.0 Use a proper controller instead
*/
public function action($class, $function = null);
diff --git a/lib/public/Security/IContentSecurityPolicyManager.php b/lib/public/Security/IContentSecurityPolicyManager.php
index 3df0da465b2..00cdcc2c454 100644
--- a/lib/public/Security/IContentSecurityPolicyManager.php
+++ b/lib/public/Security/IContentSecurityPolicyManager.php
@@ -24,7 +24,7 @@ interface IContentSecurityPolicyManager {
* Note that the adjustment is only applied to applications that use AppFramework
* controllers.
*
- * To use this from your `app.php` use `\OC::$server->getContentSecurityPolicyManager()->addDefaultPolicy($policy)`,
+ * To use this from your `app.php` use `\OCP\Server::get(IContentSecurityPolicyManager::class)->addDefaultPolicy($policy)`,
* $policy has to be of type `\OCP\AppFramework\Http\ContentSecurityPolicy`.
*
* WARNING: Using this API incorrectly may make the instance more insecure.
diff --git a/lib/public/Security/ICrypto.php b/lib/public/Security/ICrypto.php
index c2ba4cc9c97..78b0fc14d6d 100644
--- a/lib/public/Security/ICrypto.php
+++ b/lib/public/Security/ICrypto.php
@@ -13,8 +13,8 @@ namespace OCP\Security;
* it will use the secret defined in config.php as key. Additionally the message will be HMAC'd.
*
* Usage:
- * $encryptWithDefaultPassword = \OC::$server->getCrypto()->encrypt('EncryptedText');
- * $encryptWithCustomPassword = \OC::$server->getCrypto()->encrypt('EncryptedText', 'password');
+ * $encryptWithDefaultPassword = \OCP\Server::get(ICrypto::class)->encrypt('EncryptedText');
+ * $encryptWithCustomPassword = \OCP\Server::get(ICrypto::class)->encrypt('EncryptedText', 'password');
*
* @since 8.0.0
*/
diff --git a/lib/public/Security/IHasher.php b/lib/public/Security/IHasher.php
index d985ffe48ab..d0d6e4e9028 100644
--- a/lib/public/Security/IHasher.php
+++ b/lib/public/Security/IHasher.php
@@ -19,10 +19,10 @@ namespace OCP\Security;
*
* Usage:
* // Hashing a message
- * $hash = \OC::$server->get(\OCP\Security\IHasher::class)->hash('MessageToHash');
+ * $hash = \OCP\Server::get(\OCP\Security\IHasher::class)->hash('MessageToHash');
* // Verifying a message - $newHash will contain the newly calculated hash
* $newHash = null;
- * var_dump(\OC::$server->get(\OCP\Security\IHasher::class)->verify('a', '86f7e437faa5a7fce15d1ddcb9eaeaea377667b8', $newHash));
+ * var_dump(\OCP\Server::get(\OCP\Security\IHasher::class)->verify('a', '86f7e437faa5a7fce15d1ddcb9eaeaea377667b8', $newHash));
* var_dump($newHash);
*
* @since 8.0.0
diff --git a/lib/public/Security/ISecureRandom.php b/lib/public/Security/ISecureRandom.php
index aa191ca348f..0f4a79e08e0 100644
--- a/lib/public/Security/ISecureRandom.php
+++ b/lib/public/Security/ISecureRandom.php
@@ -14,7 +14,7 @@ namespace OCP\Security;
* use a fallback.
*
* Usage:
- * \OC::$server->get(ISecureRandom::class)->generate(10);
+ * \OCP\Server::get(ISecureRandom::class)->generate(10);
*
* @since 8.0.0
*/
diff --git a/lib/public/Settings/IDeclarativeSettingsForm.php b/lib/public/Settings/IDeclarativeSettingsForm.php
index d471cdf4a93..419905b7b23 100644
--- a/lib/public/Settings/IDeclarativeSettingsForm.php
+++ b/lib/public/Settings/IDeclarativeSettingsForm.php
@@ -27,6 +27,7 @@ namespace OCP\Settings;
* label?: string,
* default: mixed,
* options?: list<string|array{name: string, value: mixed}>,
+ * sensitive?: boolean,
* }
*
* @psalm-type DeclarativeSettingsFormFieldWithValue = DeclarativeSettingsFormField&array{
diff --git a/lib/public/Share/IProviderFactory.php b/lib/public/Share/IProviderFactory.php
index 34656af2d8c..9107274c8c1 100644
--- a/lib/public/Share/IProviderFactory.php
+++ b/lib/public/Share/IProviderFactory.php
@@ -39,7 +39,8 @@ interface IProviderFactory {
/**
* @since 21.0.0
- * @param string $shareProvier
+ * @since 32.0.0 Fix typo in parameter name
+ * @param string $shareProviderClass
*/
- public function registerProvider(string $shareProvier): void;
+ public function registerProvider(string $shareProviderClass): void;
}
diff --git a/lib/public/Share/IShareProviderSupportsAllSharesInFolder.php b/lib/public/Share/IShareProviderSupportsAllSharesInFolder.php
new file mode 100644
index 00000000000..e27da7682ce
--- /dev/null
+++ b/lib/public/Share/IShareProviderSupportsAllSharesInFolder.php
@@ -0,0 +1,24 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Share;
+
+use OCP\Files\Folder;
+
+/**
+ * Allows defining a IShareProvider with support for the getAllSharesInFolder method.
+ *
+ * @since 32.0.0
+ */
+interface IShareProviderSupportsAllSharesInFolder extends IShareProvider {
+ /**
+ * Get all shares in a folder.
+ *
+ * @return array<int, list<IShare>>
+ * @since 32.0.0
+ */
+ public function getAllSharesInFolder(Folder $node): array;
+}
diff --git a/lib/public/TaskProcessing/TaskTypes/TextToSpeech.php b/lib/public/TaskProcessing/TaskTypes/TextToSpeech.php
new file mode 100644
index 00000000000..ce35be32a6f
--- /dev/null
+++ b/lib/public/TaskProcessing/TaskTypes/TextToSpeech.php
@@ -0,0 +1,92 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace OCP\TaskProcessing\TaskTypes;
+
+use OCP\IL10N;
+use OCP\L10N\IFactory;
+use OCP\TaskProcessing\EShapeType;
+use OCP\TaskProcessing\ITaskType;
+use OCP\TaskProcessing\ShapeDescriptor;
+
+/**
+ * This is the task processing task type for speech generation
+ * @since 32.0.0
+ */
+class TextToSpeech implements ITaskType {
+ /**
+ * @since 32.0.0
+ */
+ public const ID = 'core:text2speech';
+
+ private IL10N $l;
+
+ /**
+ * @param IFactory $l10nFactory
+ * @since 32.0.0
+ */
+ public function __construct(
+ IFactory $l10nFactory,
+ ) {
+ $this->l = $l10nFactory->get('lib');
+ }
+
+
+ /**
+ * @inheritDoc
+ * @since 32.0.0
+ */
+ public function getName(): string {
+ return $this->l->t('Generate speech');
+ }
+
+ /**
+ * @inheritDoc
+ * @since 32.0.0
+ */
+ public function getDescription(): string {
+ return $this->l->t('Generate speech from a transcript');
+ }
+
+ /**
+ * @return string
+ * @since 32.0.0
+ */
+ public function getId(): string {
+ return self::ID;
+ }
+
+ /**
+ * @return ShapeDescriptor[]
+ * @since 32.0.0
+ */
+ public function getInputShape(): array {
+ return [
+ 'input' => new ShapeDescriptor(
+ $this->l->t('Prompt'),
+ $this->l->t('Write transcript that you want the assistant to generate speech from'),
+ EShapeType::Text
+ ),
+ ];
+ }
+
+ /**
+ * @return ShapeDescriptor[]
+ * @since 32.0.0
+ */
+ public function getOutputShape(): array {
+ return [
+ 'speech' => new ShapeDescriptor(
+ $this->l->t('Output speech'),
+ $this->l->t('The generated speech'),
+ EShapeType::Audio
+ ),
+ ];
+ }
+}
diff --git a/lib/public/Template.php b/lib/public/Template.php
index 3b31ee10a54..c29de52db4f 100644
--- a/lib/public/Template.php
+++ b/lib/public/Template.php
@@ -23,7 +23,7 @@ require_once __DIR__ . '/../private/Template/functions.php';
*/
class Template extends \OC_Template implements ITemplate {
/**
- * Make OC_Helper::imagePath available as a simple function
+ * Make \OCP\IURLGenerator::imagePath available as a simple function
*
* @see \OCP\IURLGenerator::imagePath
*
@@ -39,7 +39,7 @@ class Template extends \OC_Template implements ITemplate {
/**
- * Make OC_Helper::mimetypeIcon available as a simple function
+ * Make IMimeTypeDetector->mimeTypeIcon available as a simple function
*
* @param string $mimetype
* @return string to the image of this file type.
@@ -77,7 +77,7 @@ class Template extends \OC_Template implements ITemplate {
}
/**
- * Make OC_Helper::humanFileSize available as a simple function
+ * Make \OCP\Util::humanFileSize available as a simple function
* Example: 2048 to 2 kB.
*
* @param int $bytes in bytes
diff --git a/lib/public/Util.php b/lib/public/Util.php
index 14663abd62f..b3111c54fc7 100644
--- a/lib/public/Util.php
+++ b/lib/public/Util.php
@@ -51,7 +51,7 @@ class Util {
return $subscriptionRegistry->delegateHasExtendedSupport();
} catch (ContainerExceptionInterface $e) {
}
- return \OC::$server->getConfig()->getSystemValueBool('extendedSupport', false);
+ return \OCP\Server::get(IConfig::class)->getSystemValueBool('extendedSupport', false);
}
/**
@@ -60,7 +60,7 @@ class Util {
* @since 8.1.0
*/
public static function setChannel($channel) {
- \OC::$server->getConfig()->setSystemValue('updater.release.channel', $channel);
+ \OCP\Server::get(IConfig::class)->setSystemValue('updater.release.channel', $channel);
}
/**
@@ -182,7 +182,7 @@ class Util {
*/
public static function getScripts(): array {
// Sort scriptDeps into sortedScriptDeps
- $scriptSort = \OC::$server->get(AppScriptSort::class);
+ $scriptSort = \OCP\Server::get(AppScriptSort::class);
$sortedScripts = $scriptSort->sort(self::$scripts, self::$scriptDeps);
// Flatten array and remove duplicates
@@ -209,7 +209,7 @@ class Util {
*/
public static function addTranslations($application, $languageCode = null, $init = false) {
if (is_null($languageCode)) {
- $languageCode = \OC::$server->get(IFactory::class)->findLanguage($application);
+ $languageCode = \OCP\Server::get(IFactory::class)->findLanguage($application);
}
if (!empty($application)) {
$path = "$application/l10n/$languageCode";
@@ -247,7 +247,7 @@ class Util {
* @since 4.0.0 - parameter $args was added in 4.5.0
*/
public static function linkToAbsolute($app, $file, $args = []) {
- $urlGenerator = \OC::$server->getURLGenerator();
+ $urlGenerator = \OCP\Server::get(IURLGenerator::class);
return $urlGenerator->getAbsoluteURL(
$urlGenerator->linkTo($app, $file, $args)
);
@@ -260,7 +260,7 @@ class Util {
* @since 4.0.0
*/
public static function linkToRemote($service) {
- $urlGenerator = \OC::$server->getURLGenerator();
+ $urlGenerator = \OCP\Server::get(IURLGenerator::class);
$remoteBase = $urlGenerator->linkTo('', 'remote.php') . '/' . $service;
return $urlGenerator->getAbsoluteURL(
$remoteBase . (($service[strlen($service) - 1] != '/') ? '/' : '')
@@ -273,7 +273,7 @@ class Util {
* @since 5.0.0
*/
public static function getServerHostName() {
- $host_name = \OC::$server->getRequest()->getServerHost();
+ $host_name = \OCP\Server::get(IRequest::class)->getServerHost();
// strip away port number (if existing)
$colon_pos = strpos($host_name, ':');
if ($colon_pos != false) {
@@ -299,13 +299,13 @@ class Util {
* @since 5.0.0
*/
public static function getDefaultEmailAddress(string $user_part): string {
- $config = \OC::$server->getConfig();
+ $config = \OCP\Server::get(IConfig::class);
$user_part = $config->getSystemValueString('mail_from_address', $user_part);
$host_name = self::getServerHostName();
$host_name = $config->getSystemValueString('mail_domain', $host_name);
$defaultEmailAddress = $user_part . '@' . $host_name;
- $mailer = \OC::$server->get(IMailer::class);
+ $mailer = \OCP\Server::get(IMailer::class);
if ($mailer->validateMailAddress($defaultEmailAddress)) {
return $defaultEmailAddress;
}
@@ -332,19 +332,70 @@ class Util {
* @since 4.0.0
*/
public static function humanFileSize(int|float $bytes): string {
- return \OC_Helper::humanFileSize($bytes);
+ if ($bytes < 0) {
+ return '?';
+ }
+ if ($bytes < 1024) {
+ return "$bytes B";
+ }
+ $bytes = round($bytes / 1024, 0);
+ if ($bytes < 1024) {
+ return "$bytes KB";
+ }
+ $bytes = round($bytes / 1024, 1);
+ if ($bytes < 1024) {
+ return "$bytes MB";
+ }
+ $bytes = round($bytes / 1024, 1);
+ if ($bytes < 1024) {
+ return "$bytes GB";
+ }
+ $bytes = round($bytes / 1024, 1);
+ if ($bytes < 1024) {
+ return "$bytes TB";
+ }
+
+ $bytes = round($bytes / 1024, 1);
+ return "$bytes PB";
}
/**
* Make a computer file size (2 kB to 2048)
+ * Inspired by: https://www.php.net/manual/en/function.filesize.php#92418
+ *
* @param string $str file size in a fancy format
* @return false|int|float a file size in bytes
- *
- * Inspired by: https://www.php.net/manual/en/function.filesize.php#92418
* @since 4.0.0
*/
public static function computerFileSize(string $str): false|int|float {
- return \OC_Helper::computerFileSize($str);
+ $str = strtolower($str);
+ if (is_numeric($str)) {
+ return Util::numericToNumber($str);
+ }
+
+ $bytes_array = [
+ 'b' => 1,
+ 'k' => 1024,
+ 'kb' => 1024,
+ 'mb' => 1024 * 1024,
+ 'm' => 1024 * 1024,
+ 'gb' => 1024 * 1024 * 1024,
+ 'g' => 1024 * 1024 * 1024,
+ 'tb' => 1024 * 1024 * 1024 * 1024,
+ 't' => 1024 * 1024 * 1024 * 1024,
+ 'pb' => 1024 * 1024 * 1024 * 1024 * 1024,
+ 'p' => 1024 * 1024 * 1024 * 1024 * 1024,
+ ];
+
+ $bytes = (float)$str;
+
+ if (preg_match('#([kmgtp]?b?)$#si', $str, $matches) && isset($bytes_array[$matches[1]])) {
+ $bytes *= $bytes_array[$matches[1]];
+ } else {
+ return false;
+ }
+
+ return Util::numericToNumber(round($bytes));
}
/**
@@ -396,7 +447,7 @@ class Util {
*/
public static function callRegister() {
if (self::$token === '') {
- self::$token = \OC::$server->get(CsrfTokenManager::class)->getToken()->getEncryptedValue();
+ self::$token = \OCP\Server::get(CsrfTokenManager::class)->getToken()->getEncryptedValue();
}
return self::$token;
}
@@ -440,7 +491,12 @@ class Util {
* @since 4.5.0
*/
public static function mb_array_change_key_case($input, $case = MB_CASE_LOWER, $encoding = 'UTF-8') {
- return \OC_Helper::mb_array_change_key_case($input, $case, $encoding);
+ $case = ($case != MB_CASE_UPPER) ? MB_CASE_LOWER : MB_CASE_UPPER;
+ $ret = [];
+ foreach ($input as $k => $v) {
+ $ret[mb_convert_case($k, $case, $encoding)] = $v;
+ }
+ return $ret;
}
/**
@@ -454,7 +510,18 @@ class Util {
* @deprecated 15.0.0
*/
public static function recursiveArraySearch($haystack, $needle, $index = null) {
- return \OC_Helper::recursiveArraySearch($haystack, $needle, $index);
+ $aIt = new \RecursiveArrayIterator($haystack);
+ $it = new \RecursiveIteratorIterator($aIt);
+
+ while ($it->valid()) {
+ if (((isset($index) and ($it->key() == $index)) or !isset($index)) and ($it->current() == $needle)) {
+ return $aIt->key();
+ }
+
+ $it->next();
+ }
+
+ return false;
}
/**
@@ -466,7 +533,10 @@ class Util {
* @since 5.0.0
*/
public static function maxUploadFilesize(string $dir, int|float|null $free = null): int|float {
- return \OC_Helper::maxUploadFilesize($dir, $free);
+ if (is_null($free) || $free < 0) {
+ $free = self::freeSpace($dir);
+ }
+ return min($free, self::uploadLimit());
}
/**
@@ -476,7 +546,13 @@ class Util {
* @since 7.0.0
*/
public static function freeSpace(string $dir): int|float {
- return \OC_Helper::freeSpace($dir);
+ $freeSpace = \OC\Files\Filesystem::free_space($dir);
+ if ($freeSpace < \OCP\Files\FileInfo::SPACE_UNLIMITED) {
+ $freeSpace = max($freeSpace, 0);
+ return $freeSpace;
+ } else {
+ return (INF > 0)? INF: PHP_INT_MAX; // work around https://bugs.php.net/bug.php?id=69188
+ }
}
/**
@@ -486,7 +562,16 @@ class Util {
* @since 7.0.0
*/
public static function uploadLimit(): int|float {
- return \OC_Helper::uploadLimit();
+ $ini = Server::get(IniGetWrapper::class);
+ $upload_max_filesize = self::computerFileSize($ini->get('upload_max_filesize')) ?: 0;
+ $post_max_size = self::computerFileSize($ini->get('post_max_size')) ?: 0;
+ if ($upload_max_filesize === 0 && $post_max_size === 0) {
+ return INF;
+ } elseif ($upload_max_filesize === 0 || $post_max_size === 0) {
+ return max($upload_max_filesize, $post_max_size); //only the non 0 value counts
+ } else {
+ return min($upload_max_filesize, $post_max_size);
+ }
}
/**
@@ -531,7 +616,7 @@ class Util {
*/
public static function needUpgrade() {
if (!isset(self::$needUpgradeCache)) {
- self::$needUpgradeCache = \OC_Util::needUpgrade(\OC::$server->getSystemConfig());
+ self::$needUpgradeCache = \OC_Util::needUpgrade(\OCP\Server::get(\OC\SystemConfig::class));
}
return self::$needUpgradeCache;
}
diff --git a/lib/unstable/Config/Lexicon/ConfigLexiconEntry.php b/lib/unstable/Config/Lexicon/ConfigLexiconEntry.php
index d7d781d8e26..d0d9b4cbd23 100644
--- a/lib/unstable/Config/Lexicon/ConfigLexiconEntry.php
+++ b/lib/unstable/Config/Lexicon/ConfigLexiconEntry.php
@@ -17,6 +17,9 @@ use NCU\Config\ValueType;
* @experimental 31.0.0
*/
class ConfigLexiconEntry {
+ /** @experimental 32.0.0 */
+ public const RENAME_INVERT_BOOLEAN = 1;
+
private string $definition = '';
private ?string $default = null;
@@ -26,6 +29,7 @@ class ConfigLexiconEntry {
* @param string $definition optional description of config key available when using occ command
* @param bool $lazy set config value as lazy
* @param int $flags set flags
+ * @param string|null $rename previous config key to migrate config value from
* @param bool $deprecated set config key as deprecated
*
* @experimental 31.0.0
@@ -40,6 +44,8 @@ class ConfigLexiconEntry {
private readonly bool $lazy = false,
private readonly int $flags = 0,
private readonly bool $deprecated = false,
+ private readonly ?string $rename = null,
+ private readonly int $options = 0,
) {
/** @psalm-suppress UndefinedClass */
if (\OC::$CLI) { // only store definition if ran from CLI
@@ -199,6 +205,25 @@ class ConfigLexiconEntry {
}
/**
+ * should be called/used only during migration/upgrade.
+ * link to an old config key.
+ *
+ * @return string|null not NULL if value can be imported from a previous key
+ * @experimental 32.0.0
+ */
+ public function getRename(): ?string {
+ return $this->rename;
+ }
+
+ /**
+ * @experimental 32.0.0
+ * @return bool TRUE if $option was set during the creation of the entry.
+ */
+ public function hasOption(int $option): bool {
+ return (($option & $this->options) !== 0);
+ }
+
+ /**
* returns if config key is set as deprecated
*
* @return bool TRUE if config si deprecated