diff options
author | Jasper Weyne <jasperweyne@gmail.com> | 2022-08-11 09:54:08 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-11 09:54:08 +0300 |
commit | 44f6c931e7c9c74ea4f448d3cdfbaa89f3b7c379 (patch) | |
tree | 710a8c1bd1c20c685991de146aa9ef149ec1de7a /apps/dav | |
parent | 0633a1d9f5a7ef06d577ae6556d09db9e94f5684 (diff) | |
parent | a61331f4560468e6d433cf32e008b157b06e7ea9 (diff) |
Merge branch 'master' into patch-2
Diffstat (limited to 'apps/dav')
175 files changed, 5029 insertions, 2008 deletions
diff --git a/apps/dav/appinfo/info.xml b/apps/dav/appinfo/info.xml index 10f78d8332a..deb99b1c33b 100644 --- a/apps/dav/appinfo/info.xml +++ b/apps/dav/appinfo/info.xml @@ -5,7 +5,7 @@ <name>WebDAV</name> <summary>WebDAV endpoint</summary> <description>WebDAV endpoint</description> - <version>1.23.0</version> + <version>1.24.0</version> <licence>agpl</licence> <author>owncloud.org</author> <namespace>DAV</namespace> @@ -39,6 +39,7 @@ <step>OCA\DAV\Migration\RemoveOrphanEventsAndContacts</step> <step>OCA\DAV\Migration\RemoveClassifiedEventActivity</step> <step>OCA\DAV\Migration\RemoveDeletedUsersCalendarSubscriptions</step> + <step>OCA\DAV\Migration\RemoveObjectProperties</step> </post-migration> <live-migration> <step>OCA\DAV\Migration\ChunkCleanup</step> diff --git a/apps/dav/appinfo/v1/caldav.php b/apps/dav/appinfo/v1/caldav.php index 6a496a992e6..1f55266a21f 100644 --- a/apps/dav/appinfo/v1/caldav.php +++ b/apps/dav/appinfo/v1/caldav.php @@ -34,6 +34,7 @@ use OCA\DAV\Connector\Sabre\Auth; use OCA\DAV\Connector\Sabre\ExceptionLoggerPlugin; use OCA\DAV\Connector\Sabre\MaintenancePlugin; use OCA\DAV\Connector\Sabre\Principal; +use OCP\Accounts\IAccountManager; use Psr\Log\LoggerInterface; $authBackend = new Auth( @@ -47,6 +48,7 @@ $authBackend = new Auth( $principalBackend = new Principal( \OC::$server->getUserManager(), \OC::$server->getGroupManager(), + \OC::$server->get(IAccountManager::class), \OC::$server->getShareManager(), \OC::$server->getUserSession(), \OC::$server->getAppManager(), @@ -61,7 +63,6 @@ $userManager = \OC::$server->getUserManager(); $random = \OC::$server->getSecureRandom(); $logger = \OC::$server->get(LoggerInterface::class); $dispatcher = \OC::$server->get(\OCP\EventDispatcher\IEventDispatcher::class); -$legacyDispatcher = \OC::$server->getEventDispatcher(); $config = \OC::$server->get(\OCP\IConfig::class); $calDavBackend = new CalDavBackend( @@ -72,7 +73,6 @@ $calDavBackend = new CalDavBackend( $random, $logger, $dispatcher, - $legacyDispatcher, $config, true ); diff --git a/apps/dav/appinfo/v1/carddav.php b/apps/dav/appinfo/v1/carddav.php index a0306118781..293ae4293d4 100644 --- a/apps/dav/appinfo/v1/carddav.php +++ b/apps/dav/appinfo/v1/carddav.php @@ -8,6 +8,7 @@ * @author John Molakvoæ <skjnldsv@protonmail.com> * @author Lukas Reschke <lukas@statuscode.ch> * @author Morris Jobke <hey@morrisjobke.de> + * @author Thomas Citharel <nextcloud@tcit.fr> * @author Thomas Müller <thomas.mueller@tmit.eu> * * @license AGPL-3.0 @@ -35,6 +36,7 @@ use OCA\DAV\Connector\Sabre\Auth; use OCA\DAV\Connector\Sabre\ExceptionLoggerPlugin; use OCA\DAV\Connector\Sabre\MaintenancePlugin; use OCA\DAV\Connector\Sabre\Principal; +use OCP\Accounts\IAccountManager; use OCP\App\IAppManager; use Psr\Log\LoggerInterface; use Sabre\CardDAV\Plugin; @@ -50,6 +52,7 @@ $authBackend = new Auth( $principalBackend = new Principal( \OC::$server->getUserManager(), \OC::$server->getGroupManager(), + \OC::$server->get(IAccountManager::class), \OC::$server->getShareManager(), \OC::$server->getUserSession(), \OC::$server->getAppManager(), @@ -60,7 +63,7 @@ $principalBackend = new Principal( 'principals/' ); $db = \OC::$server->getDatabaseConnection(); -$cardDavBackend = new CardDavBackend($db, $principalBackend, \OC::$server->getUserManager(), \OC::$server->getGroupManager(), \OC::$server->get(\OCP\EventDispatcher\IEventDispatcher::class), \OC::$server->getEventDispatcher()); +$cardDavBackend = new CardDavBackend($db, $principalBackend, \OC::$server->getUserManager(), \OC::$server->getGroupManager(), \OC::$server->get(\OCP\EventDispatcher\IEventDispatcher::class)); $debugging = \OC::$server->getConfig()->getSystemValue('debug', false); diff --git a/apps/dav/appinfo/v1/publicwebdav.php b/apps/dav/appinfo/v1/publicwebdav.php index 389461f94b1..409fbbcf4a7 100644 --- a/apps/dav/appinfo/v1/publicwebdav.php +++ b/apps/dav/appinfo/v1/publicwebdav.php @@ -98,7 +98,7 @@ $server = $serverFactory->createServer($baseuri, $requestUri, $authPlugin, funct $fileInfo = $ownerView->getFileInfo($path); $linkCheckPlugin->setFileInfo($fileInfo); - // If not readble (files_drop) enable the filesdrop plugin + // If not readable (files_drop) enable the filesdrop plugin if (!$isReadable) { $filesDropPlugin->enable(); } diff --git a/apps/dav/composer/composer/InstalledVersions.php b/apps/dav/composer/composer/InstalledVersions.php index 41bc143c114..c6b54af7ba2 100644 --- a/apps/dav/composer/composer/InstalledVersions.php +++ b/apps/dav/composer/composer/InstalledVersions.php @@ -28,7 +28,7 @@ class InstalledVersions { /** * @var mixed[]|null - * @psalm-var array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}|array{}|null + * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null */ private static $installed; @@ -39,7 +39,7 @@ class InstalledVersions /** * @var array[] - * @psalm-var array<string, array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}> + * @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}> */ private static $installedByVendor = array(); @@ -243,7 +243,7 @@ class InstalledVersions /** * @return array - * @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string} + * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool} */ public static function getRootPackage() { @@ -257,7 +257,7 @@ class InstalledVersions * * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. * @return array[] - * @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>} + * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} */ public static function getRawData() { @@ -280,7 +280,7 @@ class InstalledVersions * Returns the raw data of all installed.php which are currently loaded for custom implementations * * @return array[] - * @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}> + * @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}> */ public static function getAllRawData() { @@ -303,7 +303,7 @@ class InstalledVersions * @param array[] $data A vendor/composer/installed.php data set * @return void * - * @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>} $data + * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data */ public static function reload($data) { @@ -313,7 +313,7 @@ class InstalledVersions /** * @return array[] - * @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}> + * @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}> */ private static function getInstalled() { diff --git a/apps/dav/composer/composer/autoload_classmap.php b/apps/dav/composer/composer/autoload_classmap.php index 0583b94a86c..d3290c4e792 100644 --- a/apps/dav/composer/composer/autoload_classmap.php +++ b/apps/dav/composer/composer/autoload_classmap.php @@ -22,6 +22,7 @@ return array( 'OCA\\DAV\\BackgroundJob\\RegisterRegenerateBirthdayCalendars' => $baseDir . '/../lib/BackgroundJob/RegisterRegenerateBirthdayCalendars.php', 'OCA\\DAV\\BackgroundJob\\UpdateCalendarResourcesRoomsBackgroundJob' => $baseDir . '/../lib/BackgroundJob/UpdateCalendarResourcesRoomsBackgroundJob.php', 'OCA\\DAV\\BackgroundJob\\UploadCleanup' => $baseDir . '/../lib/BackgroundJob/UploadCleanup.php', + 'OCA\\DAV\\BackgroundJob\\UserStatusAutomation' => $baseDir . '/../lib/BackgroundJob/UserStatusAutomation.php', 'OCA\\DAV\\BulkUpload\\BulkUploadPlugin' => $baseDir . '/../lib/BulkUpload/BulkUploadPlugin.php', 'OCA\\DAV\\BulkUpload\\MultipartRequestParser' => $baseDir . '/../lib/BulkUpload/MultipartRequestParser.php', 'OCA\\DAV\\CalDAV\\Activity\\Backend' => $baseDir . '/../lib/CalDAV/Activity/Backend.php', @@ -190,6 +191,7 @@ return array( 'OCA\\DAV\\DAV\\Sharing\\Xml\\Invite' => $baseDir . '/../lib/DAV/Sharing/Xml/Invite.php', 'OCA\\DAV\\DAV\\Sharing\\Xml\\ShareRequest' => $baseDir . '/../lib/DAV/Sharing/Xml/ShareRequest.php', 'OCA\\DAV\\DAV\\SystemPrincipalBackend' => $baseDir . '/../lib/DAV/SystemPrincipalBackend.php', + 'OCA\\DAV\\DAV\\ViewOnlyPlugin' => $baseDir . '/../lib/DAV/ViewOnlyPlugin.php', 'OCA\\DAV\\Db\\Direct' => $baseDir . '/../lib/Db/Direct.php', 'OCA\\DAV\\Db\\DirectMapper' => $baseDir . '/../lib/Db/DirectMapper.php', 'OCA\\DAV\\Direct\\DirectFile' => $baseDir . '/../lib/Direct/DirectFile.php', @@ -209,6 +211,7 @@ return array( 'OCA\\DAV\\Events\\CalendarMovedToTrashEvent' => $baseDir . '/../lib/Events/CalendarMovedToTrashEvent.php', 'OCA\\DAV\\Events\\CalendarObjectCreatedEvent' => $baseDir . '/../lib/Events/CalendarObjectCreatedEvent.php', 'OCA\\DAV\\Events\\CalendarObjectDeletedEvent' => $baseDir . '/../lib/Events/CalendarObjectDeletedEvent.php', + 'OCA\\DAV\\Events\\CalendarObjectMovedEvent' => $baseDir . '/../lib/Events/CalendarObjectMovedEvent.php', 'OCA\\DAV\\Events\\CalendarObjectMovedToTrashEvent' => $baseDir . '/../lib/Events/CalendarObjectMovedToTrashEvent.php', 'OCA\\DAV\\Events\\CalendarObjectRestoredEvent' => $baseDir . '/../lib/Events/CalendarObjectRestoredEvent.php', 'OCA\\DAV\\Events\\CalendarObjectUpdatedEvent' => $baseDir . '/../lib/Events/CalendarObjectUpdatedEvent.php', @@ -224,6 +227,7 @@ return array( 'OCA\\DAV\\Events\\SubscriptionCreatedEvent' => $baseDir . '/../lib/Events/SubscriptionCreatedEvent.php', 'OCA\\DAV\\Events\\SubscriptionDeletedEvent' => $baseDir . '/../lib/Events/SubscriptionDeletedEvent.php', 'OCA\\DAV\\Events\\SubscriptionUpdatedEvent' => $baseDir . '/../lib/Events/SubscriptionUpdatedEvent.php', + 'OCA\\DAV\\Exception\\ServerMaintenanceMode' => $baseDir . '/../lib/Exception/ServerMaintenanceMode.php', 'OCA\\DAV\\Exception\\UnsupportedLimitOnInitialSyncException' => $baseDir . '/../lib/Exception/UnsupportedLimitOnInitialSyncException.php', 'OCA\\DAV\\Files\\BrowserErrorPagePlugin' => $baseDir . '/../lib/Files/BrowserErrorPagePlugin.php', 'OCA\\DAV\\Files\\FileSearchBackend' => $baseDir . '/../lib/Files/FileSearchBackend.php', @@ -235,10 +239,17 @@ return array( 'OCA\\DAV\\HookManager' => $baseDir . '/../lib/HookManager.php', 'OCA\\DAV\\Listener\\ActivityUpdaterListener' => $baseDir . '/../lib/Listener/ActivityUpdaterListener.php', 'OCA\\DAV\\Listener\\AddressbookListener' => $baseDir . '/../lib/Listener/AddressbookListener.php', + 'OCA\\DAV\\Listener\\BirthdayListener' => $baseDir . '/../lib/Listener/BirthdayListener.php', 'OCA\\DAV\\Listener\\CalendarContactInteractionListener' => $baseDir . '/../lib/Listener/CalendarContactInteractionListener.php', 'OCA\\DAV\\Listener\\CalendarDeletionDefaultUpdaterListener' => $baseDir . '/../lib/Listener/CalendarDeletionDefaultUpdaterListener.php', 'OCA\\DAV\\Listener\\CalendarObjectReminderUpdaterListener' => $baseDir . '/../lib/Listener/CalendarObjectReminderUpdaterListener.php', + 'OCA\\DAV\\Listener\\CalendarPublicationListener' => $baseDir . '/../lib/Listener/CalendarPublicationListener.php', + 'OCA\\DAV\\Listener\\CalendarShareUpdateListener' => $baseDir . '/../lib/Listener/CalendarShareUpdateListener.php', 'OCA\\DAV\\Listener\\CardListener' => $baseDir . '/../lib/Listener/CardListener.php', + 'OCA\\DAV\\Listener\\ClearPhotoCacheListener' => $baseDir . '/../lib/Listener/ClearPhotoCacheListener.php', + 'OCA\\DAV\\Listener\\SubscriptionListener' => $baseDir . '/../lib/Listener/SubscriptionListener.php', + 'OCA\\DAV\\Listener\\TrustedServerRemovedListener' => $baseDir . '/../lib/Listener/TrustedServerRemovedListener.php', + 'OCA\\DAV\\Listener\\UserPreferenceListener' => $baseDir . '/../lib/Listener/UserPreferenceListener.php', 'OCA\\DAV\\Migration\\BuildCalendarSearchIndex' => $baseDir . '/../lib/Migration/BuildCalendarSearchIndex.php', 'OCA\\DAV\\Migration\\BuildCalendarSearchIndexBackgroundJob' => $baseDir . '/../lib/Migration/BuildCalendarSearchIndexBackgroundJob.php', 'OCA\\DAV\\Migration\\BuildSocialSearchIndex' => $baseDir . '/../lib/Migration/BuildSocialSearchIndex.php', @@ -251,6 +262,7 @@ return array( 'OCA\\DAV\\Migration\\RegisterBuildReminderIndexBackgroundJob' => $baseDir . '/../lib/Migration/RegisterBuildReminderIndexBackgroundJob.php', 'OCA\\DAV\\Migration\\RemoveClassifiedEventActivity' => $baseDir . '/../lib/Migration/RemoveClassifiedEventActivity.php', 'OCA\\DAV\\Migration\\RemoveDeletedUsersCalendarSubscriptions' => $baseDir . '/../lib/Migration/RemoveDeletedUsersCalendarSubscriptions.php', + 'OCA\\DAV\\Migration\\RemoveObjectProperties' => $baseDir . '/../lib/Migration/RemoveObjectProperties.php', 'OCA\\DAV\\Migration\\RemoveOrphanEventsAndContacts' => $baseDir . '/../lib/Migration/RemoveOrphanEventsAndContacts.php', 'OCA\\DAV\\Migration\\Version1004Date20170825134824' => $baseDir . '/../lib/Migration/Version1004Date20170825134824.php', 'OCA\\DAV\\Migration\\Version1004Date20170919104507' => $baseDir . '/../lib/Migration/Version1004Date20170919104507.php', @@ -272,6 +284,7 @@ return array( 'OCA\\DAV\\Migration\\Version1016Date20201109085907' => $baseDir . '/../lib/Migration/Version1016Date20201109085907.php', 'OCA\\DAV\\Migration\\Version1017Date20210216083742' => $baseDir . '/../lib/Migration/Version1017Date20210216083742.php', 'OCA\\DAV\\Migration\\Version1018Date20210312100735' => $baseDir . '/../lib/Migration/Version1018Date20210312100735.php', + 'OCA\\DAV\\Migration\\Version1024Date20211221144219' => $baseDir . '/../lib/Migration/Version1024Date20211221144219.php', 'OCA\\DAV\\Profiler\\ProfilerPlugin' => $baseDir . '/../lib/Profiler/ProfilerPlugin.php', 'OCA\\DAV\\Provisioning\\Apple\\AppleProvisioningNode' => $baseDir . '/../lib/Provisioning/Apple/AppleProvisioningNode.php', 'OCA\\DAV\\Provisioning\\Apple\\AppleProvisioningPlugin' => $baseDir . '/../lib/Provisioning/Apple/AppleProvisioningPlugin.php', diff --git a/apps/dav/composer/composer/autoload_static.php b/apps/dav/composer/composer/autoload_static.php index 301be38246a..4d425f70f3b 100644 --- a/apps/dav/composer/composer/autoload_static.php +++ b/apps/dav/composer/composer/autoload_static.php @@ -37,6 +37,7 @@ class ComposerStaticInitDAV 'OCA\\DAV\\BackgroundJob\\RegisterRegenerateBirthdayCalendars' => __DIR__ . '/..' . '/../lib/BackgroundJob/RegisterRegenerateBirthdayCalendars.php', 'OCA\\DAV\\BackgroundJob\\UpdateCalendarResourcesRoomsBackgroundJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/UpdateCalendarResourcesRoomsBackgroundJob.php', 'OCA\\DAV\\BackgroundJob\\UploadCleanup' => __DIR__ . '/..' . '/../lib/BackgroundJob/UploadCleanup.php', + 'OCA\\DAV\\BackgroundJob\\UserStatusAutomation' => __DIR__ . '/..' . '/../lib/BackgroundJob/UserStatusAutomation.php', 'OCA\\DAV\\BulkUpload\\BulkUploadPlugin' => __DIR__ . '/..' . '/../lib/BulkUpload/BulkUploadPlugin.php', 'OCA\\DAV\\BulkUpload\\MultipartRequestParser' => __DIR__ . '/..' . '/../lib/BulkUpload/MultipartRequestParser.php', 'OCA\\DAV\\CalDAV\\Activity\\Backend' => __DIR__ . '/..' . '/../lib/CalDAV/Activity/Backend.php', @@ -205,6 +206,7 @@ class ComposerStaticInitDAV 'OCA\\DAV\\DAV\\Sharing\\Xml\\Invite' => __DIR__ . '/..' . '/../lib/DAV/Sharing/Xml/Invite.php', 'OCA\\DAV\\DAV\\Sharing\\Xml\\ShareRequest' => __DIR__ . '/..' . '/../lib/DAV/Sharing/Xml/ShareRequest.php', 'OCA\\DAV\\DAV\\SystemPrincipalBackend' => __DIR__ . '/..' . '/../lib/DAV/SystemPrincipalBackend.php', + 'OCA\\DAV\\DAV\\ViewOnlyPlugin' => __DIR__ . '/..' . '/../lib/DAV/ViewOnlyPlugin.php', 'OCA\\DAV\\Db\\Direct' => __DIR__ . '/..' . '/../lib/Db/Direct.php', 'OCA\\DAV\\Db\\DirectMapper' => __DIR__ . '/..' . '/../lib/Db/DirectMapper.php', 'OCA\\DAV\\Direct\\DirectFile' => __DIR__ . '/..' . '/../lib/Direct/DirectFile.php', @@ -224,6 +226,7 @@ class ComposerStaticInitDAV 'OCA\\DAV\\Events\\CalendarMovedToTrashEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarMovedToTrashEvent.php', 'OCA\\DAV\\Events\\CalendarObjectCreatedEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarObjectCreatedEvent.php', 'OCA\\DAV\\Events\\CalendarObjectDeletedEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarObjectDeletedEvent.php', + 'OCA\\DAV\\Events\\CalendarObjectMovedEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarObjectMovedEvent.php', 'OCA\\DAV\\Events\\CalendarObjectMovedToTrashEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarObjectMovedToTrashEvent.php', 'OCA\\DAV\\Events\\CalendarObjectRestoredEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarObjectRestoredEvent.php', 'OCA\\DAV\\Events\\CalendarObjectUpdatedEvent' => __DIR__ . '/..' . '/../lib/Events/CalendarObjectUpdatedEvent.php', @@ -239,6 +242,7 @@ class ComposerStaticInitDAV 'OCA\\DAV\\Events\\SubscriptionCreatedEvent' => __DIR__ . '/..' . '/../lib/Events/SubscriptionCreatedEvent.php', 'OCA\\DAV\\Events\\SubscriptionDeletedEvent' => __DIR__ . '/..' . '/../lib/Events/SubscriptionDeletedEvent.php', 'OCA\\DAV\\Events\\SubscriptionUpdatedEvent' => __DIR__ . '/..' . '/../lib/Events/SubscriptionUpdatedEvent.php', + 'OCA\\DAV\\Exception\\ServerMaintenanceMode' => __DIR__ . '/..' . '/../lib/Exception/ServerMaintenanceMode.php', 'OCA\\DAV\\Exception\\UnsupportedLimitOnInitialSyncException' => __DIR__ . '/..' . '/../lib/Exception/UnsupportedLimitOnInitialSyncException.php', 'OCA\\DAV\\Files\\BrowserErrorPagePlugin' => __DIR__ . '/..' . '/../lib/Files/BrowserErrorPagePlugin.php', 'OCA\\DAV\\Files\\FileSearchBackend' => __DIR__ . '/..' . '/../lib/Files/FileSearchBackend.php', @@ -250,10 +254,17 @@ class ComposerStaticInitDAV 'OCA\\DAV\\HookManager' => __DIR__ . '/..' . '/../lib/HookManager.php', 'OCA\\DAV\\Listener\\ActivityUpdaterListener' => __DIR__ . '/..' . '/../lib/Listener/ActivityUpdaterListener.php', 'OCA\\DAV\\Listener\\AddressbookListener' => __DIR__ . '/..' . '/../lib/Listener/AddressbookListener.php', + 'OCA\\DAV\\Listener\\BirthdayListener' => __DIR__ . '/..' . '/../lib/Listener/BirthdayListener.php', 'OCA\\DAV\\Listener\\CalendarContactInteractionListener' => __DIR__ . '/..' . '/../lib/Listener/CalendarContactInteractionListener.php', 'OCA\\DAV\\Listener\\CalendarDeletionDefaultUpdaterListener' => __DIR__ . '/..' . '/../lib/Listener/CalendarDeletionDefaultUpdaterListener.php', 'OCA\\DAV\\Listener\\CalendarObjectReminderUpdaterListener' => __DIR__ . '/..' . '/../lib/Listener/CalendarObjectReminderUpdaterListener.php', + 'OCA\\DAV\\Listener\\CalendarPublicationListener' => __DIR__ . '/..' . '/../lib/Listener/CalendarPublicationListener.php', + 'OCA\\DAV\\Listener\\CalendarShareUpdateListener' => __DIR__ . '/..' . '/../lib/Listener/CalendarShareUpdateListener.php', 'OCA\\DAV\\Listener\\CardListener' => __DIR__ . '/..' . '/../lib/Listener/CardListener.php', + 'OCA\\DAV\\Listener\\ClearPhotoCacheListener' => __DIR__ . '/..' . '/../lib/Listener/ClearPhotoCacheListener.php', + 'OCA\\DAV\\Listener\\SubscriptionListener' => __DIR__ . '/..' . '/../lib/Listener/SubscriptionListener.php', + 'OCA\\DAV\\Listener\\TrustedServerRemovedListener' => __DIR__ . '/..' . '/../lib/Listener/TrustedServerRemovedListener.php', + 'OCA\\DAV\\Listener\\UserPreferenceListener' => __DIR__ . '/..' . '/../lib/Listener/UserPreferenceListener.php', 'OCA\\DAV\\Migration\\BuildCalendarSearchIndex' => __DIR__ . '/..' . '/../lib/Migration/BuildCalendarSearchIndex.php', 'OCA\\DAV\\Migration\\BuildCalendarSearchIndexBackgroundJob' => __DIR__ . '/..' . '/../lib/Migration/BuildCalendarSearchIndexBackgroundJob.php', 'OCA\\DAV\\Migration\\BuildSocialSearchIndex' => __DIR__ . '/..' . '/../lib/Migration/BuildSocialSearchIndex.php', @@ -266,6 +277,7 @@ class ComposerStaticInitDAV 'OCA\\DAV\\Migration\\RegisterBuildReminderIndexBackgroundJob' => __DIR__ . '/..' . '/../lib/Migration/RegisterBuildReminderIndexBackgroundJob.php', 'OCA\\DAV\\Migration\\RemoveClassifiedEventActivity' => __DIR__ . '/..' . '/../lib/Migration/RemoveClassifiedEventActivity.php', 'OCA\\DAV\\Migration\\RemoveDeletedUsersCalendarSubscriptions' => __DIR__ . '/..' . '/../lib/Migration/RemoveDeletedUsersCalendarSubscriptions.php', + 'OCA\\DAV\\Migration\\RemoveObjectProperties' => __DIR__ . '/..' . '/../lib/Migration/RemoveObjectProperties.php', 'OCA\\DAV\\Migration\\RemoveOrphanEventsAndContacts' => __DIR__ . '/..' . '/../lib/Migration/RemoveOrphanEventsAndContacts.php', 'OCA\\DAV\\Migration\\Version1004Date20170825134824' => __DIR__ . '/..' . '/../lib/Migration/Version1004Date20170825134824.php', 'OCA\\DAV\\Migration\\Version1004Date20170919104507' => __DIR__ . '/..' . '/../lib/Migration/Version1004Date20170919104507.php', @@ -287,6 +299,7 @@ class ComposerStaticInitDAV 'OCA\\DAV\\Migration\\Version1016Date20201109085907' => __DIR__ . '/..' . '/../lib/Migration/Version1016Date20201109085907.php', 'OCA\\DAV\\Migration\\Version1017Date20210216083742' => __DIR__ . '/..' . '/../lib/Migration/Version1017Date20210216083742.php', 'OCA\\DAV\\Migration\\Version1018Date20210312100735' => __DIR__ . '/..' . '/../lib/Migration/Version1018Date20210312100735.php', + 'OCA\\DAV\\Migration\\Version1024Date20211221144219' => __DIR__ . '/..' . '/../lib/Migration/Version1024Date20211221144219.php', 'OCA\\DAV\\Profiler\\ProfilerPlugin' => __DIR__ . '/..' . '/../lib/Profiler/ProfilerPlugin.php', 'OCA\\DAV\\Provisioning\\Apple\\AppleProvisioningNode' => __DIR__ . '/..' . '/../lib/Provisioning/Apple/AppleProvisioningNode.php', 'OCA\\DAV\\Provisioning\\Apple\\AppleProvisioningPlugin' => __DIR__ . '/..' . '/../lib/Provisioning/Apple/AppleProvisioningPlugin.php', diff --git a/apps/dav/l10n/bg.js b/apps/dav/l10n/bg.js index f4842a46d30..690115069c3 100644 --- a/apps/dav/l10n/bg.js +++ b/apps/dav/l10n/bg.js @@ -2,7 +2,7 @@ OC.L10N.register( "dav", { "Calendar" : "Календар", - "Todos" : "Задачи", + "To-dos" : "Задачи за изпълнение", "Personal" : "Личен", "{actor} created calendar {calendar}" : "{actor} направи календар {calendar}", "You created calendar {calendar}" : "Създадохте календара {calendar}", @@ -32,23 +32,27 @@ OC.L10N.register( "You deleted event {event} from calendar {calendar}" : "Изтрихте събитие {event} от календар {calendar}", "{actor} updated event {event} in calendar {calendar}" : "{actor} обнови събитие {event} в календар {calendar}", "You updated event {event} in calendar {calendar}" : "Обновихте събитие {event} в календар {calendar}", + "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{actor} премести събитие {event} от календар {sourceCalendar} в календар {targetCalendar}", + "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "Преместихте събитие {event} от календар {sourceCalendar} в календар {targetCalendar}", "{actor} restored event {event} of calendar {calendar}" : "{actor} възстанови събитие {event} от календар {calendar}", "You restored event {event} of calendar {calendar}" : "Вие възстановихте събитие {event} от календар {calendar}", "Busy" : "Зает", - "{actor} created todo {todo} in list {calendar}" : "{actor} създаде задача {todo} в списък {calendar}", - "You created todo {todo} in list {calendar}" : "Създадохте задача {todo} в списък {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} изтри задача {todo} от списък {calendar}", - "You deleted todo {todo} from list {calendar}" : "Изтрихте задача {todo} от списък {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} актуализира задача {todo} в списък {calendar}", - "You updated todo {todo} in list {calendar}" : "Променихте задача {todo} в списък {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} разреши задача {todo} в списък {calendar}", - "You solved todo {todo} in list {calendar}" : "Разрешихте задача {todo} в списък {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} възобнови задача {todo} в списък {calendar}", - "You reopened todo {todo} in list {calendar}" : "Възобновихте задача {todo} в списък {calendar}", + "{actor} created to-do {todo} in list {calendar}" : "{actor} създаде задача {todo} в списък {calendar}", + "You created to-do {todo} in list {calendar}" : "Създадохте задача {todo} в списък {calendar}", + "{actor} deleted to-do {todo} from list {calendar}" : "{actor} изтри задача {todo} от списък {calendar}", + "You deleted to-do {todo} from list {calendar}" : "Изтрихте задача {todo} от списък {calendar}", + "{actor} updated to-do {todo} in list {calendar}" : "{actor} актуализира задача {todo} в списък {calendar}", + "You updated to-do {todo} in list {calendar}" : "Актуализирахте задачи {todo} в списъка {calendar}", + "{actor} solved to-do {todo} in list {calendar}" : "{actor} разреши задача {todo} в списък {calendar}", + "You solved to-do {todo} in list {calendar}" : "Разрешихте задача {todo} в списък {calendar}", + "{actor} reopened to-do {todo} in list {calendar}" : "{actor} отвори отново задача {todo} в списък {calendar}", + "You reopened to-do {todo} in list {calendar}" : "Отворихте отново задача {todo} в списък {calendar}", + "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor} премести задача {todo} от списък {sourceCalendar} в списък {targetCalendar}", + "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "Преместихте задача {todo} от списък {sourceCalendar} в списък {targetCalendar}", "Calendar, contacts and tasks" : "Календар, контакти и задачи", "A <strong>calendar</strong> was modified" : "Промяна на <strong>календар</strong>", "A calendar <strong>event</strong> was modified" : "Промяна на календарно <strong>събитие</strong>", - "A calendar <strong>todo</strong> was modified" : "Промяна на календарна <strong>задача</strong>", + "A calendar <strong>to-do</strong> was modified" : "<strong>задача</strong>от календар беше променена", "Contact birthdays" : "Рождени дни на контакти", "Death of %s" : "Смърт на %s", "Calendar:" : "Календар:", @@ -155,7 +159,11 @@ OC.L10N.register( "Friday" : "Петък", "Saturday" : "Събота", "Sunday" : "Неделя", + "Automatically set user status to \"Do not disturb\" outside of availability to mute all notifications." : "Автоматично задаване на потребителският статус на „Не безпокойте“ извън достъпността, за заглушаване на всички известия.", "Save" : "Запазване", + "Failed to load availability" : "Неуспешно зареждане на наличност", + "Saved availability" : "Запазена наличност", + "Failed to save availability" : "Неуспешно записване на наличност", "Calendar server" : "Сървър на календар", "Send invitations to attendees" : "Изпращане на покани до участниците", "Automatically generate a birthday calendar" : "Автоматично генериране на календар с рождени дни.", @@ -174,6 +182,18 @@ OC.L10N.register( "Tentative" : "Несигурно", "Number of guests" : "Брой на гостите ", "Comment" : "Коментар", - "Your attendance was updated successfully." : "Вашето присъствие е актуализирано успешно." + "Your attendance was updated successfully." : "Вашето присъствие е актуализирано успешно.", + "Todos" : "Задачи", + "{actor} created todo {todo} in list {calendar}" : "{actor} създаде задача {todo} в списък {calendar}", + "You created todo {todo} in list {calendar}" : "Създадохте задача {todo} в списък {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} изтри задача {todo} от списък {calendar}", + "You deleted todo {todo} from list {calendar}" : "Изтрихте задача {todo} от списък {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} актуализира задача {todo} в списък {calendar}", + "You updated todo {todo} in list {calendar}" : "Променихте задача {todo} в списък {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} разреши задача {todo} в списък {calendar}", + "You solved todo {todo} in list {calendar}" : "Разрешихте задача {todo} в списък {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} възобнови задача {todo} в списък {calendar}", + "You reopened todo {todo} in list {calendar}" : "Възобновихте задача {todo} в списък {calendar}", + "A calendar <strong>todo</strong> was modified" : "Промяна на календарна <strong>задача</strong>" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/dav/l10n/bg.json b/apps/dav/l10n/bg.json index 3a6ffd3e5fe..85f51d6e36b 100644 --- a/apps/dav/l10n/bg.json +++ b/apps/dav/l10n/bg.json @@ -1,6 +1,6 @@ { "translations": { "Calendar" : "Календар", - "Todos" : "Задачи", + "To-dos" : "Задачи за изпълнение", "Personal" : "Личен", "{actor} created calendar {calendar}" : "{actor} направи календар {calendar}", "You created calendar {calendar}" : "Създадохте календара {calendar}", @@ -30,23 +30,27 @@ "You deleted event {event} from calendar {calendar}" : "Изтрихте събитие {event} от календар {calendar}", "{actor} updated event {event} in calendar {calendar}" : "{actor} обнови събитие {event} в календар {calendar}", "You updated event {event} in calendar {calendar}" : "Обновихте събитие {event} в календар {calendar}", + "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{actor} премести събитие {event} от календар {sourceCalendar} в календар {targetCalendar}", + "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "Преместихте събитие {event} от календар {sourceCalendar} в календар {targetCalendar}", "{actor} restored event {event} of calendar {calendar}" : "{actor} възстанови събитие {event} от календар {calendar}", "You restored event {event} of calendar {calendar}" : "Вие възстановихте събитие {event} от календар {calendar}", "Busy" : "Зает", - "{actor} created todo {todo} in list {calendar}" : "{actor} създаде задача {todo} в списък {calendar}", - "You created todo {todo} in list {calendar}" : "Създадохте задача {todo} в списък {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} изтри задача {todo} от списък {calendar}", - "You deleted todo {todo} from list {calendar}" : "Изтрихте задача {todo} от списък {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} актуализира задача {todo} в списък {calendar}", - "You updated todo {todo} in list {calendar}" : "Променихте задача {todo} в списък {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} разреши задача {todo} в списък {calendar}", - "You solved todo {todo} in list {calendar}" : "Разрешихте задача {todo} в списък {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} възобнови задача {todo} в списък {calendar}", - "You reopened todo {todo} in list {calendar}" : "Възобновихте задача {todo} в списък {calendar}", + "{actor} created to-do {todo} in list {calendar}" : "{actor} създаде задача {todo} в списък {calendar}", + "You created to-do {todo} in list {calendar}" : "Създадохте задача {todo} в списък {calendar}", + "{actor} deleted to-do {todo} from list {calendar}" : "{actor} изтри задача {todo} от списък {calendar}", + "You deleted to-do {todo} from list {calendar}" : "Изтрихте задача {todo} от списък {calendar}", + "{actor} updated to-do {todo} in list {calendar}" : "{actor} актуализира задача {todo} в списък {calendar}", + "You updated to-do {todo} in list {calendar}" : "Актуализирахте задачи {todo} в списъка {calendar}", + "{actor} solved to-do {todo} in list {calendar}" : "{actor} разреши задача {todo} в списък {calendar}", + "You solved to-do {todo} in list {calendar}" : "Разрешихте задача {todo} в списък {calendar}", + "{actor} reopened to-do {todo} in list {calendar}" : "{actor} отвори отново задача {todo} в списък {calendar}", + "You reopened to-do {todo} in list {calendar}" : "Отворихте отново задача {todo} в списък {calendar}", + "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor} премести задача {todo} от списък {sourceCalendar} в списък {targetCalendar}", + "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "Преместихте задача {todo} от списък {sourceCalendar} в списък {targetCalendar}", "Calendar, contacts and tasks" : "Календар, контакти и задачи", "A <strong>calendar</strong> was modified" : "Промяна на <strong>календар</strong>", "A calendar <strong>event</strong> was modified" : "Промяна на календарно <strong>събитие</strong>", - "A calendar <strong>todo</strong> was modified" : "Промяна на календарна <strong>задача</strong>", + "A calendar <strong>to-do</strong> was modified" : "<strong>задача</strong>от календар беше променена", "Contact birthdays" : "Рождени дни на контакти", "Death of %s" : "Смърт на %s", "Calendar:" : "Календар:", @@ -153,7 +157,11 @@ "Friday" : "Петък", "Saturday" : "Събота", "Sunday" : "Неделя", + "Automatically set user status to \"Do not disturb\" outside of availability to mute all notifications." : "Автоматично задаване на потребителският статус на „Не безпокойте“ извън достъпността, за заглушаване на всички известия.", "Save" : "Запазване", + "Failed to load availability" : "Неуспешно зареждане на наличност", + "Saved availability" : "Запазена наличност", + "Failed to save availability" : "Неуспешно записване на наличност", "Calendar server" : "Сървър на календар", "Send invitations to attendees" : "Изпращане на покани до участниците", "Automatically generate a birthday calendar" : "Автоматично генериране на календар с рождени дни.", @@ -172,6 +180,18 @@ "Tentative" : "Несигурно", "Number of guests" : "Брой на гостите ", "Comment" : "Коментар", - "Your attendance was updated successfully." : "Вашето присъствие е актуализирано успешно." + "Your attendance was updated successfully." : "Вашето присъствие е актуализирано успешно.", + "Todos" : "Задачи", + "{actor} created todo {todo} in list {calendar}" : "{actor} създаде задача {todo} в списък {calendar}", + "You created todo {todo} in list {calendar}" : "Създадохте задача {todo} в списък {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} изтри задача {todo} от списък {calendar}", + "You deleted todo {todo} from list {calendar}" : "Изтрихте задача {todo} от списък {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} актуализира задача {todo} в списък {calendar}", + "You updated todo {todo} in list {calendar}" : "Променихте задача {todo} в списък {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} разреши задача {todo} в списък {calendar}", + "You solved todo {todo} in list {calendar}" : "Разрешихте задача {todo} в списък {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} възобнови задача {todo} в списък {calendar}", + "You reopened todo {todo} in list {calendar}" : "Възобновихте задача {todo} в списък {calendar}", + "A calendar <strong>todo</strong> was modified" : "Промяна на календарна <strong>задача</strong>" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/dav/l10n/ca.js b/apps/dav/l10n/ca.js index 63d0d35c797..a1d37e37ba3 100644 --- a/apps/dav/l10n/ca.js +++ b/apps/dav/l10n/ca.js @@ -2,7 +2,6 @@ OC.L10N.register( "dav", { "Calendar" : "Calendari", - "Todos" : "Tasques", "Personal" : "Personal", "{actor} created calendar {calendar}" : "{actor} ha creat el calendari {calendar}", "You created calendar {calendar}" : "Heu creat el calendari {calendar}", @@ -31,19 +30,8 @@ OC.L10N.register( "{actor} updated event {event} in calendar {calendar}" : "{actor} esdeveniment actualitzat {esdeveniment} al calendari {calendar}", "You updated event {event} in calendar {calendar}" : "Heu actualitzat l'esdeveniment {event} al calendari {calendar}", "Busy" : "Ocupat", - "{actor} created todo {todo} in list {calendar}" : "{actor} ha creat la tasca {todo} a {calendar}", - "You created todo {todo} in list {calendar}" : "Heu creat la tasca {todo} a {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} ha suprimit la tasca {todo} de la llista {calendar}", - "You deleted todo {todo} from list {calendar}" : "Heu suprimit la tasca {todo} de la llista {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} ha actualitzat la tasca {todo} a {calendar}", - "You updated todo {todo} in list {calendar}" : "Heu actualitzat la tasca {todo} a {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} ha resolt la tasca {todo} a {calendar}", - "You solved todo {todo} in list {calendar}" : "Heu resolt la tasca {todo} a {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} ha tornat a obrir la tasca {todo} a {calendar}", - "You reopened todo {todo} in list {calendar}" : "Heu tornat a obrir la tasca {todo} a {calendar}", "A <strong>calendar</strong> was modified" : "El <strong>calendari</strong> has estat modificat", "A calendar <strong>event</strong> was modified" : "S'ha modificat un <strong> esdeveniment </strong> del calendari", - "A calendar <strong>todo</strong> was modified" : "S'ha modificat una <strong>tasca</strong> d'un calendari", "Contact birthdays" : "Aniversaris dels contactes", "Death of %s" : "Mort de %s", "Calendar:" : "Calendari:", @@ -90,6 +78,7 @@ OC.L10N.register( "WebDAV" : "WebDAV", "WebDAV endpoint" : "Punt final de WebDAV", "to" : "a", + "Delete slot" : "Suprimeix unitat temporal", "Monday" : "Dilluns", "Tuesday" : "Dimarts", "Wednesday" : "Dimecres", @@ -113,6 +102,18 @@ OC.L10N.register( "Are you accepting the invitation?" : "Accepteu la invitació?", "Tentative" : "Provisional", "Comment" : "Comentari", - "Your attendance was updated successfully." : "La vostra assistència ha estat actualitzada correctament." + "Your attendance was updated successfully." : "La vostra assistència ha estat actualitzada correctament.", + "Todos" : "Tasques", + "{actor} created todo {todo} in list {calendar}" : "{actor} ha creat la tasca {todo} a {calendar}", + "You created todo {todo} in list {calendar}" : "Heu creat la tasca {todo} a {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} ha suprimit la tasca {todo} de la llista {calendar}", + "You deleted todo {todo} from list {calendar}" : "Heu suprimit la tasca {todo} de la llista {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} ha actualitzat la tasca {todo} a {calendar}", + "You updated todo {todo} in list {calendar}" : "Heu actualitzat la tasca {todo} a {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} ha resolt la tasca {todo} a {calendar}", + "You solved todo {todo} in list {calendar}" : "Heu resolt la tasca {todo} a {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} ha tornat a obrir la tasca {todo} a {calendar}", + "You reopened todo {todo} in list {calendar}" : "Heu tornat a obrir la tasca {todo} a {calendar}", + "A calendar <strong>todo</strong> was modified" : "S'ha modificat una <strong>tasca</strong> d'un calendari" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/dav/l10n/ca.json b/apps/dav/l10n/ca.json index 0952b65181b..5d339d4de30 100644 --- a/apps/dav/l10n/ca.json +++ b/apps/dav/l10n/ca.json @@ -1,6 +1,5 @@ { "translations": { "Calendar" : "Calendari", - "Todos" : "Tasques", "Personal" : "Personal", "{actor} created calendar {calendar}" : "{actor} ha creat el calendari {calendar}", "You created calendar {calendar}" : "Heu creat el calendari {calendar}", @@ -29,19 +28,8 @@ "{actor} updated event {event} in calendar {calendar}" : "{actor} esdeveniment actualitzat {esdeveniment} al calendari {calendar}", "You updated event {event} in calendar {calendar}" : "Heu actualitzat l'esdeveniment {event} al calendari {calendar}", "Busy" : "Ocupat", - "{actor} created todo {todo} in list {calendar}" : "{actor} ha creat la tasca {todo} a {calendar}", - "You created todo {todo} in list {calendar}" : "Heu creat la tasca {todo} a {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} ha suprimit la tasca {todo} de la llista {calendar}", - "You deleted todo {todo} from list {calendar}" : "Heu suprimit la tasca {todo} de la llista {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} ha actualitzat la tasca {todo} a {calendar}", - "You updated todo {todo} in list {calendar}" : "Heu actualitzat la tasca {todo} a {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} ha resolt la tasca {todo} a {calendar}", - "You solved todo {todo} in list {calendar}" : "Heu resolt la tasca {todo} a {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} ha tornat a obrir la tasca {todo} a {calendar}", - "You reopened todo {todo} in list {calendar}" : "Heu tornat a obrir la tasca {todo} a {calendar}", "A <strong>calendar</strong> was modified" : "El <strong>calendari</strong> has estat modificat", "A calendar <strong>event</strong> was modified" : "S'ha modificat un <strong> esdeveniment </strong> del calendari", - "A calendar <strong>todo</strong> was modified" : "S'ha modificat una <strong>tasca</strong> d'un calendari", "Contact birthdays" : "Aniversaris dels contactes", "Death of %s" : "Mort de %s", "Calendar:" : "Calendari:", @@ -88,6 +76,7 @@ "WebDAV" : "WebDAV", "WebDAV endpoint" : "Punt final de WebDAV", "to" : "a", + "Delete slot" : "Suprimeix unitat temporal", "Monday" : "Dilluns", "Tuesday" : "Dimarts", "Wednesday" : "Dimecres", @@ -111,6 +100,18 @@ "Are you accepting the invitation?" : "Accepteu la invitació?", "Tentative" : "Provisional", "Comment" : "Comentari", - "Your attendance was updated successfully." : "La vostra assistència ha estat actualitzada correctament." + "Your attendance was updated successfully." : "La vostra assistència ha estat actualitzada correctament.", + "Todos" : "Tasques", + "{actor} created todo {todo} in list {calendar}" : "{actor} ha creat la tasca {todo} a {calendar}", + "You created todo {todo} in list {calendar}" : "Heu creat la tasca {todo} a {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} ha suprimit la tasca {todo} de la llista {calendar}", + "You deleted todo {todo} from list {calendar}" : "Heu suprimit la tasca {todo} de la llista {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} ha actualitzat la tasca {todo} a {calendar}", + "You updated todo {todo} in list {calendar}" : "Heu actualitzat la tasca {todo} a {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} ha resolt la tasca {todo} a {calendar}", + "You solved todo {todo} in list {calendar}" : "Heu resolt la tasca {todo} a {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} ha tornat a obrir la tasca {todo} a {calendar}", + "You reopened todo {todo} in list {calendar}" : "Heu tornat a obrir la tasca {todo} a {calendar}", + "A calendar <strong>todo</strong> was modified" : "S'ha modificat una <strong>tasca</strong> d'un calendari" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/dav/l10n/cs.js b/apps/dav/l10n/cs.js index 5dfc5bcd147..f15065305a6 100644 --- a/apps/dav/l10n/cs.js +++ b/apps/dav/l10n/cs.js @@ -2,7 +2,7 @@ OC.L10N.register( "dav", { "Calendar" : "Kalendář", - "Todos" : "Úkoly", + "To-dos" : "Zbývá udělat", "Personal" : "Osobní", "{actor} created calendar {calendar}" : "{actor} vytvořil(a) kalendář {calendar}", "You created calendar {calendar}" : "Vytvořili jste kalendář {calendar}", @@ -32,23 +32,27 @@ OC.L10N.register( "You deleted event {event} from calendar {calendar}" : "Smazali jste událost {event} z kalendáře {calendar}", "{actor} updated event {event} in calendar {calendar}" : "{actor} aktualizoval(a) událost {event} v kalendáři {calendar}", "You updated event {event} in calendar {calendar}" : "Aktualizovali jste událost {event} v kalendáři {calendar}", + "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{actor} přesunul(a) událost {event} z kalendáře {sourceCalendar} do kalendáře {targetCalendar}", + "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "Přesunuli jste událost {event} z kalendáře {sourceCalendar} do kalendáře {targetCalendar}", "{actor} restored event {event} of calendar {calendar}" : "{actor} obnovil(a) událost {event} kalendáře {calendar}", "You restored event {event} of calendar {calendar}" : "Obnovili jste událost {event} kalendáře {calendar}", "Busy" : "Zaneprázdněn(a)", - "{actor} created todo {todo} in list {calendar}" : "{actor} vytvořil(a) v seznamu {calendar} vytvořila úkol {todo}", - "You created todo {todo} in list {calendar}" : "V seznamu {calendar} jste vytvořili úkol {todo}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} smazal(a) úkol {todo} ze seznamu {calendar}", - "You deleted todo {todo} from list {calendar}" : "Ze seznamu {calendar} jste smazali úkol {todo}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} aktualizoval(a) úkol {todo} v seznamu {calendar}", - "You updated todo {todo} in list {calendar}" : "Aktualizovali jste úkol {todo} v seznamu {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} vyřešil(a) úkol {todo} v seznamu {calendar}", - "You solved todo {todo} in list {calendar}" : "Vyřešili jste úkol {todo} v seznamu {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} znovu otevřel(a) úkol {todo} v seznamu {calendar}", - "You reopened todo {todo} in list {calendar}" : "Znovu jste otevřeli úkol {todo} v seznamu {calendar}", + "{actor} created to-do {todo} in list {calendar}" : "{actor} vytvořil(a) úkol {todo} v seznamu {calendar}", + "You created to-do {todo} in list {calendar}" : "Vytvořili jste úkol {todo} v seznamu {calendar}", + "{actor} deleted to-do {todo} from list {calendar}" : "{actor} vymazal(a) úkol {todo} ze seznamu {calendar}", + "You deleted to-do {todo} from list {calendar}" : "Vymazali jste úkol {todo} ze seznamu {calendar}", + "{actor} updated to-do {todo} in list {calendar}" : "{actor} aktualizoval(a) úkol {todo} v seznamu {calendar}", + "You updated to-do {todo} in list {calendar}" : "Aktualizovali jste úkol {todo} v seznamu {calendar}", + "{actor} solved to-do {todo} in list {calendar}" : "{actor} vyřešil(a) úkol {todo} v seznamu {calendar}", + "You solved to-do {todo} in list {calendar}" : "Vyřešili jste úkol {todo} v seznamu {calendar}", + "{actor} reopened to-do {todo} in list {calendar}" : "{actor} znovu otevřel(a) úkol {todo} v seznamu {calendar}", + "You reopened to-do {todo} in list {calendar}" : "Znovuotevřeli jste úkol {todo} v seznamu {calendar}", + "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor} přesunul(a) úkol {todo} ze seznamu {sourceCalendar} do seznamu {targetCalendar}", + "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "Přesunuli jste úkol {todo} ze seznamu {sourceCalendar} do seznamu {targetCalendar}", "Calendar, contacts and tasks" : "Kalendář, kontakty a úkoly", "A <strong>calendar</strong> was modified" : "<strong>Kalendář</strong> byl změněn", "A calendar <strong>event</strong> was modified" : "<strong>Událost</strong> v kalendáři byla změněna", - "A calendar <strong>todo</strong> was modified" : "<strong>Úkol</strong> v kalendáři byl změněn", + "A calendar <strong>to-do</strong> was modified" : "Kalendář <strong>úkoly</strong> byl upraven", "Contact birthdays" : "Narozeniny kontaktů", "Death of %s" : "Datum úmrtí %s", "Calendar:" : "Kalendář:", @@ -155,6 +159,7 @@ OC.L10N.register( "Friday" : "pátek", "Saturday" : "sobota", "Sunday" : "neděle", + "Automatically set user status to \"Do not disturb\" outside of availability to mute all notifications." : "V době, kdy není k dispozici, automaticky nastavit stav uživatele jako „Nerušit“ a ztlumit tak veškerá upozornění pro něho.", "Save" : "Uložit", "Failed to load availability" : "Nepodařilo se načíst dostupnost", "Saved availability" : "Uložena dostupnost", @@ -177,6 +182,18 @@ OC.L10N.register( "Tentative" : "Nezávazně", "Number of guests" : "Počet hostů", "Comment" : "Komentář", - "Your attendance was updated successfully." : "Vaše účast byla úspěšně aktualizována." + "Your attendance was updated successfully." : "Vaše účast byla úspěšně aktualizována.", + "Todos" : "Úkoly", + "{actor} created todo {todo} in list {calendar}" : "{actor} vytvořil(a) v seznamu {calendar} vytvořila úkol {todo}", + "You created todo {todo} in list {calendar}" : "V seznamu {calendar} jste vytvořili úkol {todo}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} smazal(a) úkol {todo} ze seznamu {calendar}", + "You deleted todo {todo} from list {calendar}" : "Ze seznamu {calendar} jste smazali úkol {todo}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} aktualizoval(a) úkol {todo} v seznamu {calendar}", + "You updated todo {todo} in list {calendar}" : "Aktualizovali jste úkol {todo} v seznamu {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} vyřešil(a) úkol {todo} v seznamu {calendar}", + "You solved todo {todo} in list {calendar}" : "Vyřešili jste úkol {todo} v seznamu {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} znovu otevřel(a) úkol {todo} v seznamu {calendar}", + "You reopened todo {todo} in list {calendar}" : "Znovu jste otevřeli úkol {todo} v seznamu {calendar}", + "A calendar <strong>todo</strong> was modified" : "<strong>Úkol</strong> v kalendáři byl změněn" }, "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/apps/dav/l10n/cs.json b/apps/dav/l10n/cs.json index 12df93f770d..91635a5353f 100644 --- a/apps/dav/l10n/cs.json +++ b/apps/dav/l10n/cs.json @@ -1,6 +1,6 @@ { "translations": { "Calendar" : "Kalendář", - "Todos" : "Úkoly", + "To-dos" : "Zbývá udělat", "Personal" : "Osobní", "{actor} created calendar {calendar}" : "{actor} vytvořil(a) kalendář {calendar}", "You created calendar {calendar}" : "Vytvořili jste kalendář {calendar}", @@ -30,23 +30,27 @@ "You deleted event {event} from calendar {calendar}" : "Smazali jste událost {event} z kalendáře {calendar}", "{actor} updated event {event} in calendar {calendar}" : "{actor} aktualizoval(a) událost {event} v kalendáři {calendar}", "You updated event {event} in calendar {calendar}" : "Aktualizovali jste událost {event} v kalendáři {calendar}", + "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{actor} přesunul(a) událost {event} z kalendáře {sourceCalendar} do kalendáře {targetCalendar}", + "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "Přesunuli jste událost {event} z kalendáře {sourceCalendar} do kalendáře {targetCalendar}", "{actor} restored event {event} of calendar {calendar}" : "{actor} obnovil(a) událost {event} kalendáře {calendar}", "You restored event {event} of calendar {calendar}" : "Obnovili jste událost {event} kalendáře {calendar}", "Busy" : "Zaneprázdněn(a)", - "{actor} created todo {todo} in list {calendar}" : "{actor} vytvořil(a) v seznamu {calendar} vytvořila úkol {todo}", - "You created todo {todo} in list {calendar}" : "V seznamu {calendar} jste vytvořili úkol {todo}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} smazal(a) úkol {todo} ze seznamu {calendar}", - "You deleted todo {todo} from list {calendar}" : "Ze seznamu {calendar} jste smazali úkol {todo}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} aktualizoval(a) úkol {todo} v seznamu {calendar}", - "You updated todo {todo} in list {calendar}" : "Aktualizovali jste úkol {todo} v seznamu {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} vyřešil(a) úkol {todo} v seznamu {calendar}", - "You solved todo {todo} in list {calendar}" : "Vyřešili jste úkol {todo} v seznamu {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} znovu otevřel(a) úkol {todo} v seznamu {calendar}", - "You reopened todo {todo} in list {calendar}" : "Znovu jste otevřeli úkol {todo} v seznamu {calendar}", + "{actor} created to-do {todo} in list {calendar}" : "{actor} vytvořil(a) úkol {todo} v seznamu {calendar}", + "You created to-do {todo} in list {calendar}" : "Vytvořili jste úkol {todo} v seznamu {calendar}", + "{actor} deleted to-do {todo} from list {calendar}" : "{actor} vymazal(a) úkol {todo} ze seznamu {calendar}", + "You deleted to-do {todo} from list {calendar}" : "Vymazali jste úkol {todo} ze seznamu {calendar}", + "{actor} updated to-do {todo} in list {calendar}" : "{actor} aktualizoval(a) úkol {todo} v seznamu {calendar}", + "You updated to-do {todo} in list {calendar}" : "Aktualizovali jste úkol {todo} v seznamu {calendar}", + "{actor} solved to-do {todo} in list {calendar}" : "{actor} vyřešil(a) úkol {todo} v seznamu {calendar}", + "You solved to-do {todo} in list {calendar}" : "Vyřešili jste úkol {todo} v seznamu {calendar}", + "{actor} reopened to-do {todo} in list {calendar}" : "{actor} znovu otevřel(a) úkol {todo} v seznamu {calendar}", + "You reopened to-do {todo} in list {calendar}" : "Znovuotevřeli jste úkol {todo} v seznamu {calendar}", + "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor} přesunul(a) úkol {todo} ze seznamu {sourceCalendar} do seznamu {targetCalendar}", + "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "Přesunuli jste úkol {todo} ze seznamu {sourceCalendar} do seznamu {targetCalendar}", "Calendar, contacts and tasks" : "Kalendář, kontakty a úkoly", "A <strong>calendar</strong> was modified" : "<strong>Kalendář</strong> byl změněn", "A calendar <strong>event</strong> was modified" : "<strong>Událost</strong> v kalendáři byla změněna", - "A calendar <strong>todo</strong> was modified" : "<strong>Úkol</strong> v kalendáři byl změněn", + "A calendar <strong>to-do</strong> was modified" : "Kalendář <strong>úkoly</strong> byl upraven", "Contact birthdays" : "Narozeniny kontaktů", "Death of %s" : "Datum úmrtí %s", "Calendar:" : "Kalendář:", @@ -153,6 +157,7 @@ "Friday" : "pátek", "Saturday" : "sobota", "Sunday" : "neděle", + "Automatically set user status to \"Do not disturb\" outside of availability to mute all notifications." : "V době, kdy není k dispozici, automaticky nastavit stav uživatele jako „Nerušit“ a ztlumit tak veškerá upozornění pro něho.", "Save" : "Uložit", "Failed to load availability" : "Nepodařilo se načíst dostupnost", "Saved availability" : "Uložena dostupnost", @@ -175,6 +180,18 @@ "Tentative" : "Nezávazně", "Number of guests" : "Počet hostů", "Comment" : "Komentář", - "Your attendance was updated successfully." : "Vaše účast byla úspěšně aktualizována." + "Your attendance was updated successfully." : "Vaše účast byla úspěšně aktualizována.", + "Todos" : "Úkoly", + "{actor} created todo {todo} in list {calendar}" : "{actor} vytvořil(a) v seznamu {calendar} vytvořila úkol {todo}", + "You created todo {todo} in list {calendar}" : "V seznamu {calendar} jste vytvořili úkol {todo}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} smazal(a) úkol {todo} ze seznamu {calendar}", + "You deleted todo {todo} from list {calendar}" : "Ze seznamu {calendar} jste smazali úkol {todo}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} aktualizoval(a) úkol {todo} v seznamu {calendar}", + "You updated todo {todo} in list {calendar}" : "Aktualizovali jste úkol {todo} v seznamu {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} vyřešil(a) úkol {todo} v seznamu {calendar}", + "You solved todo {todo} in list {calendar}" : "Vyřešili jste úkol {todo} v seznamu {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} znovu otevřel(a) úkol {todo} v seznamu {calendar}", + "You reopened todo {todo} in list {calendar}" : "Znovu jste otevřeli úkol {todo} v seznamu {calendar}", + "A calendar <strong>todo</strong> was modified" : "<strong>Úkol</strong> v kalendáři byl změněn" },"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/apps/dav/l10n/da.js b/apps/dav/l10n/da.js index ec7ca67b4c7..0018b8f7947 100644 --- a/apps/dav/l10n/da.js +++ b/apps/dav/l10n/da.js @@ -2,7 +2,6 @@ OC.L10N.register( "dav", { "Calendar" : "Kalender", - "Todos" : "Opgaver", "Personal" : "Personligt", "{actor} created calendar {calendar}" : "{actor} oprettede kalenderen {calendar}", "You created calendar {calendar}" : "Du oprettede kalenderen {calendar}", @@ -35,20 +34,9 @@ OC.L10N.register( "{actor} restored event {event} of calendar {calendar}" : "{actor} gendannede begivenhed {event} i kalender {calendar}", "You restored event {event} of calendar {calendar}" : "Du gendannede begivenhed {begivenhed} i kalender {kalender}", "Busy" : "Optaget", - "{actor} created todo {todo} in list {calendar}" : "{actor} oprettede en opgave {todo} i listen {calendar}", - "You created todo {todo} in list {calendar}" : "Du oprettede opgaven {todo} i listen {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} slettede opgaven {todo} fra listen {calendar}", - "You deleted todo {todo} from list {calendar}" : "Du slettede opgaven {todo} fra listen {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} opdaterede opgaven {todo} i listen {calendar}", - "You updated todo {todo} in list {calendar}" : "Du opdaterede opgaven {todo} i listen {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} løste opgaven {todo} i listen {calendar}", - "You solved todo {todo} in list {calendar}" : "Du løste opgaven {todo} i listen {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} genåbnede opgaven {todo} i listen {calendar}", - "You reopened todo {todo} in list {calendar}" : "Du genåbnede opgaven {todo} i listen {calendar}", "Calendar, contacts and tasks" : "Kalender, kontakter og opgaver", "A <strong>calendar</strong> was modified" : "En <strong>kalender</strong> er blevet ændret", "A calendar <strong>event</strong> was modified" : "En kalender <strong>begivenhed</strong> er blevet ændret", - "A calendar <strong>todo</strong> was modified" : "En kalender <strong>opgave</strong> blev ændret", "Contact birthdays" : "Kontakt fødselsdag", "Death of %s" : "Død af%s", "Calendar:" : "Kalender:", @@ -102,6 +90,18 @@ OC.L10N.register( "Hence they will not be available immediately after enabling but will show up after some time." : "Derfor vil de ikke blive synlige med det samme efter aktivering, men vil vise sig efter noget tid.", "Are you accepting the invitation?" : "Accepter du invitationen?", "Tentative" : "Foreløbig", - "Comment" : "Kommentér" + "Comment" : "Kommentér", + "Todos" : "Opgaver", + "{actor} created todo {todo} in list {calendar}" : "{actor} oprettede en opgave {todo} i listen {calendar}", + "You created todo {todo} in list {calendar}" : "Du oprettede opgaven {todo} i listen {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} slettede opgaven {todo} fra listen {calendar}", + "You deleted todo {todo} from list {calendar}" : "Du slettede opgaven {todo} fra listen {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} opdaterede opgaven {todo} i listen {calendar}", + "You updated todo {todo} in list {calendar}" : "Du opdaterede opgaven {todo} i listen {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} løste opgaven {todo} i listen {calendar}", + "You solved todo {todo} in list {calendar}" : "Du løste opgaven {todo} i listen {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} genåbnede opgaven {todo} i listen {calendar}", + "You reopened todo {todo} in list {calendar}" : "Du genåbnede opgaven {todo} i listen {calendar}", + "A calendar <strong>todo</strong> was modified" : "En kalender <strong>opgave</strong> blev ændret" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/dav/l10n/da.json b/apps/dav/l10n/da.json index 56cbfd455cd..aa71d4631af 100644 --- a/apps/dav/l10n/da.json +++ b/apps/dav/l10n/da.json @@ -1,6 +1,5 @@ { "translations": { "Calendar" : "Kalender", - "Todos" : "Opgaver", "Personal" : "Personligt", "{actor} created calendar {calendar}" : "{actor} oprettede kalenderen {calendar}", "You created calendar {calendar}" : "Du oprettede kalenderen {calendar}", @@ -33,20 +32,9 @@ "{actor} restored event {event} of calendar {calendar}" : "{actor} gendannede begivenhed {event} i kalender {calendar}", "You restored event {event} of calendar {calendar}" : "Du gendannede begivenhed {begivenhed} i kalender {kalender}", "Busy" : "Optaget", - "{actor} created todo {todo} in list {calendar}" : "{actor} oprettede en opgave {todo} i listen {calendar}", - "You created todo {todo} in list {calendar}" : "Du oprettede opgaven {todo} i listen {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} slettede opgaven {todo} fra listen {calendar}", - "You deleted todo {todo} from list {calendar}" : "Du slettede opgaven {todo} fra listen {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} opdaterede opgaven {todo} i listen {calendar}", - "You updated todo {todo} in list {calendar}" : "Du opdaterede opgaven {todo} i listen {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} løste opgaven {todo} i listen {calendar}", - "You solved todo {todo} in list {calendar}" : "Du løste opgaven {todo} i listen {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} genåbnede opgaven {todo} i listen {calendar}", - "You reopened todo {todo} in list {calendar}" : "Du genåbnede opgaven {todo} i listen {calendar}", "Calendar, contacts and tasks" : "Kalender, kontakter og opgaver", "A <strong>calendar</strong> was modified" : "En <strong>kalender</strong> er blevet ændret", "A calendar <strong>event</strong> was modified" : "En kalender <strong>begivenhed</strong> er blevet ændret", - "A calendar <strong>todo</strong> was modified" : "En kalender <strong>opgave</strong> blev ændret", "Contact birthdays" : "Kontakt fødselsdag", "Death of %s" : "Død af%s", "Calendar:" : "Kalender:", @@ -100,6 +88,18 @@ "Hence they will not be available immediately after enabling but will show up after some time." : "Derfor vil de ikke blive synlige med det samme efter aktivering, men vil vise sig efter noget tid.", "Are you accepting the invitation?" : "Accepter du invitationen?", "Tentative" : "Foreløbig", - "Comment" : "Kommentér" + "Comment" : "Kommentér", + "Todos" : "Opgaver", + "{actor} created todo {todo} in list {calendar}" : "{actor} oprettede en opgave {todo} i listen {calendar}", + "You created todo {todo} in list {calendar}" : "Du oprettede opgaven {todo} i listen {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} slettede opgaven {todo} fra listen {calendar}", + "You deleted todo {todo} from list {calendar}" : "Du slettede opgaven {todo} fra listen {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} opdaterede opgaven {todo} i listen {calendar}", + "You updated todo {todo} in list {calendar}" : "Du opdaterede opgaven {todo} i listen {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} løste opgaven {todo} i listen {calendar}", + "You solved todo {todo} in list {calendar}" : "Du løste opgaven {todo} i listen {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} genåbnede opgaven {todo} i listen {calendar}", + "You reopened todo {todo} in list {calendar}" : "Du genåbnede opgaven {todo} i listen {calendar}", + "A calendar <strong>todo</strong> was modified" : "En kalender <strong>opgave</strong> blev ændret" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/dav/l10n/de.js b/apps/dav/l10n/de.js index 7f60996b78e..e7e0695f4d0 100644 --- a/apps/dav/l10n/de.js +++ b/apps/dav/l10n/de.js @@ -2,7 +2,7 @@ OC.L10N.register( "dav", { "Calendar" : "Kalender", - "Todos" : "Aufgaben", + "To-dos" : "Aufgaben", "Personal" : "Persönlich", "{actor} created calendar {calendar}" : "{actor} hat den Kalender {calendar} erstellt", "You created calendar {calendar}" : "Du hast den Kalender {calendar} erstellt", @@ -14,10 +14,10 @@ OC.L10N.register( "You restored calendar {calendar}" : "Du hast den Kalender {calendar} wiederhergestellt", "You shared calendar {calendar} as public link" : "Du hast den Kalender {calendar} als öffentlichen Link geteilt", "You removed public link for calendar {calendar}" : "Du hast den öffentlichen Link für Kalender {calendar} entfernt", - "{actor} shared calendar {calendar} with you" : "{actor} hat den Kalender {calendar} mit Dir geteilt", + "{actor} shared calendar {calendar} with you" : "{actor} hat den Kalender {calendar} mit dir geteilt", "You shared calendar {calendar} with {user}" : "Du hast den Kalender {calendar} mit {user} geteilt", "{actor} shared calendar {calendar} with {user}" : "{actor} hat den Kalender {calendar} mit {user} geteilt", - "{actor} unshared calendar {calendar} from you" : "{actor} teilt den Kalender {calendar} nicht mehr mit Dir", + "{actor} unshared calendar {calendar} from you" : "{actor} teilt den Kalender {calendar} nicht mehr mit dir", "You unshared calendar {calendar} from {user}" : "Du teilst den Kalender {calendar} nicht mehr mit {user}", "{actor} unshared calendar {calendar} from {user}" : "{actor} teilt den Kalender {calendar} nicht mehr mit {user}", "{actor} unshared calendar {calendar} from themselves" : "{actor} teilt den Kalender {calendar} nicht mehr mit sich selbst", @@ -32,23 +32,27 @@ OC.L10N.register( "You deleted event {event} from calendar {calendar}" : "Du hast den Termin {event} im Kalender {calendar} gelöscht", "{actor} updated event {event} in calendar {calendar}" : "{actor} hat den Termin {event} im Kalender {calendar} aktualisiert", "You updated event {event} in calendar {calendar}" : "Du hast den Termin {event} im Kalender {calendar} aktualisiert", - "{actor} restored event {event} of calendar {calendar}" : "{actor} hat das Adressbuch {addressbook} mit Dir geteilt", + "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{actor} hat das Ereignis {event} vom Kalender {sourceCalendar} in den Kalender {targetCalendar} verschoben", + "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "Du hast das Ereignis {event} vom Kalender {sourceCalendar} in den Kalender {targetCalendar} verschoben", + "{actor} restored event {event} of calendar {calendar}" : "{actor} hat das Adressbuch {addressbook} mit dir geteilt", "You restored event {event} of calendar {calendar}" : "Du hast den Termin {event} im Kalender {calendar} wiederhergestellt", "Busy" : "Beschäftigt", - "{actor} created todo {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} erstellt", - "You created todo {todo} in list {calendar}" : "Du hast die Aufgabe {todo} in der Liste {calendar} erstellt", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} gelöscht", - "You deleted todo {todo} from list {calendar}" : "Du hast die Aufgabe {todo} in der Liste {calendar} gelöscht", - "{actor} updated todo {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} aktualisiert", - "You updated todo {todo} in list {calendar}" : "Du hast die Aufgabe {todo} in der Liste {calendar} aktualisiert", - "{actor} solved todo {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} erledigt", - "You solved todo {todo} in list {calendar}" : "Du hast die Aufgabe {todo} in der Liste {calendar} erledigt", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} wiedereröffnet", - "You reopened todo {todo} in list {calendar}" : "Du hast die Aufgabe {todo} in der Liste {calendar} wiedereröffnet", + "{actor} created to-do {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} erstellt", + "You created to-do {todo} in list {calendar}" : "Du hast eine Aufgabe {todo} in der Liste {calendar} erstellt", + "{actor} deleted to-do {todo} from list {calendar}" : "{actor} hat die Aufgabe {todo} aus der Liste {calendar} gelöscht", + "You deleted to-do {todo} from list {calendar}" : "Du hast die Aufgabe {todo} aus der Liste {calendar} gelöscht", + "{actor} updated to-do {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} aktualisiert", + "You updated to-do {todo} in list {calendar}" : "Du hast die Aufgabe {todo} in der Liste {calendar} aktualisiert", + "{actor} solved to-do {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} erledigt", + "You solved to-do {todo} in list {calendar}" : "Du hast die Aufgabe {todo} in der Liste {calendar} erledigt", + "{actor} reopened to-do {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} wiedereröffnet", + "You reopened to-do {todo} in list {calendar}" : "Du hast die Aufgabe {todo} in der Liste {calendar} wiedereröffnet", + "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor} hat die Aufgabe {todo} von der Liste {sourceCalendar} in die Liste {targetCalendar} verschoben", + "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "Du hast die Aufgabe {todo} von der Liste {sourceCalendar} in die Liste {targetCalendar} verschoben", "Calendar, contacts and tasks" : "Kalender, Kontakte und Aufgaben", "A <strong>calendar</strong> was modified" : "Ein <strong>Kalender</strong> wurde bearbeitet", "A calendar <strong>event</strong> was modified" : "Ein Kalender-<strong>Termin</strong> wurde bearbeitet", - "A calendar <strong>todo</strong> was modified" : "Eine Kalender-<strong>Aufgabe</strong> wurde bearbeitet", + "A calendar <strong>to-do</strong> was modified" : "Eine Kalender-<strong>Aufgabe</strong> wurde geändert", "Contact birthdays" : "Geburtstage von Kontakten", "Death of %s" : "Todestag von %s", "Calendar:" : "Kalender:", @@ -90,13 +94,13 @@ OC.L10N.register( "You deleted address book {addressbook}" : "Du hast das Adressbuch {addressbook} gelöscht", "{actor} updated address book {addressbook}" : "{actor} hat das Adressbuch {addressbook} aktualisiert", "You updated address book {addressbook}" : "Du hast das Adressbuch {addressbook} aktualisiert", - "{actor} shared address book {addressbook} with you" : "{actor} hat das Adressbuch {addressbook} mit Dir geteilt", + "{actor} shared address book {addressbook} with you" : "{actor} hat das Adressbuch {addressbook} mit dir geteilt", "You shared address book {addressbook} with {user}" : "Du hast das Adressbuch {addressbook} geteilt", "{actor} shared address book {addressbook} with {user}" : "{actor} hat das Adressbuch {addressbook} mit {user} geteilt", - "{actor} unshared address book {addressbook} from you" : "{actor} teilt das Adressbuch {addressbook} nicht mehr mit Dir", + "{actor} unshared address book {addressbook} from you" : "{actor} teilt das Adressbuch {addressbook} nicht mehr mit dir.", "You unshared address book {addressbook} from {user}" : "Du teilst das Adressbuch {addressbook} nicht mehr mit {user}", "{actor} unshared address book {addressbook} from {user}" : "{actor} teilt das Adressbuch {addressbook} nicht mehr mit {user}", - "{actor} unshared address book {addressbook} from themselves" : "{actor} teilt das Adressbuch {addressbook} nicht mehr mit Dir", + "{actor} unshared address book {addressbook} from themselves" : "{actor} teilt das Adressbuch {addressbook} nicht mehr mit dir.", "You shared address book {addressbook} with group {group}" : "Du hast das Adressbuch {addressbook} mit der Gruppe {group} geteilt", "{actor} shared address book {addressbook} with group {group}" : "{actor} hat das Adressbuch {addressbook} mit der Gruppe {group} geteilt", "You unshared address book {addressbook} from group {group}" : "Du teilst das Adressbuch {addressbook} nicht mehr mit der Gruppe {group}", @@ -142,7 +146,7 @@ OC.L10N.register( "WebDAV" : "WebDAV", "WebDAV endpoint" : "WebDAV-Endpunkt", "Availability" : "Verfügbarkeit", - "If you configure your working hours, other users will see when you are out of office when they book a meeting." : "Wenn Du Deine Arbeitszeiten konfigurierst, können andere Benutzer sehen, wann Du nicht im Büro bist, wenn sie eine Besprechung buchen.", + "If you configure your working hours, other users will see when you are out of office when they book a meeting." : "Wenn du deine Arbeitszeiten konfigurierst, können andere Benutzer sehen, wann du nicht im Büro bist, wenn sie eine Besprechung buchen.", "Time zone:" : "Zeitzone:", "to" : "an", "Delete slot" : "Slot löschen", @@ -155,6 +159,7 @@ OC.L10N.register( "Friday" : "Freitag", "Saturday" : "Samstag", "Sunday" : "Sonntag", + "Automatically set user status to \"Do not disturb\" outside of availability to mute all notifications." : "Setze den Benutzerstatus automatisch auf „Nicht stören“, wenn du nicht erreichbar bist, um alle Benachrichtigungen stumm zu schalten.", "Save" : "Speichern", "Failed to load availability" : "Fehler beim Laden der Verfügbarkeit", "Saved availability" : "Verfügbarkeit gespeichert", @@ -163,20 +168,32 @@ OC.L10N.register( "Send invitations to attendees" : "Einladungen an die Teilnehmer versenden", "Automatically generate a birthday calendar" : "Automatisch einen Kalender für Geburtstage erstellen", "Birthday calendars will be generated by a background job." : "Kalender für Geburtstage werden von einem Hintergrund-Auftrag erstellt", - "Hence they will not be available immediately after enabling but will show up after some time." : "Die Einträge werden nicht sofort angezeigt. Nach der Aktivierung wird es ein wenig dauern bis zur Anzeige.", + "Hence they will not be available immediately after enabling but will show up after some time." : "Die Einträge werden nicht sofort angezeigt. Nach der Aktivierung wird es bis zur Anzeige ein wenig dauern.", "Send notifications for events" : "Sende Benachrichtigungen für Termine", - "Notifications are sent via background jobs, so these must occur often enough." : "Benachrichtigungen werden von Hintergrundjobs versendet, so dass diese häufig genug ausgeführt werden müssen.", + "Notifications are sent via background jobs, so these must occur often enough." : "Benachrichtigungen werden von Hintergrundjobs versendet, so dass diese häufig genug ausgeführt werden.", "Send reminder notifications to calendar sharees as well" : "Erinnerungsbenachrichtigungen auch an die freigegebenen Kalender senden", "Reminders are always sent to organizers and attendees." : "Erinnerungen werden immer an Organisatoren und Teilnehmer gesendet.", "Enable notifications for events via push" : "Benachrichtigungen für Termine per Push aktivieren", - "Also install the {calendarappstoreopen}Calendar app{linkclose}, or {calendardocopen}connect your desktop & mobile for syncing ↗{linkclose}." : "Installiere außerdem die {calendarappstoreopen}Kalender-App{linkclose} oder {calendardocopen}verbinde Deinen Desktop & Mobilgerät zur Synchronisierung ↗{linkclose}.", - "Please make sure to properly set up {emailopen}the email server{linkclose}." : "Bitte stelle sicher, dass Du {emailopen}den E-Mail Server{linkclose} ordnungsgemäß einrichtest.", - "There was an error updating your attendance status." : "Es ist ein Fehler beim Aktualisieren Deines Teilnehmerstatus aufgetreten.", + "Also install the {calendarappstoreopen}Calendar app{linkclose}, or {calendardocopen}connect your desktop & mobile for syncing ↗{linkclose}." : "Installiere außerdem die {calendarappstoreopen}Kalender-App{linkclose} oder {calendardocopen}verbinde deinen Desktop & Mobilgerät zur Synchronisierung ↗{linkclose}.", + "Please make sure to properly set up {emailopen}the email server{linkclose}." : "Bitte stelle sicher, dass du {emailopen}den E-Mail Server{linkclose} ordnungsgemäß einrichtest.", + "There was an error updating your attendance status." : "Es ist ein Fehler beim Aktualisieren deines Teilnehmerstatus aufgetreten.", "Please contact the organizer directly." : "Bitte den Organisator direkt kontaktieren.", "Are you accepting the invitation?" : "Die Einladung annehmen?", "Tentative" : "Vorläufig", "Number of guests" : "Anzahl Gäste", "Comment" : "Kommentar", - "Your attendance was updated successfully." : "Dein Teilnehmerstatus wurde aktualisiert." + "Your attendance was updated successfully." : "Dein Teilnehmerstatus wurde aktualisiert.", + "Todos" : "Aufgaben", + "{actor} created todo {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} erstellt", + "You created todo {todo} in list {calendar}" : "Du hast die Aufgabe {todo} in der Liste {calendar} erstellt", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} gelöscht", + "You deleted todo {todo} from list {calendar}" : "Du hast die Aufgabe {todo} in der Liste {calendar} gelöscht", + "{actor} updated todo {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} aktualisiert", + "You updated todo {todo} in list {calendar}" : "Du hast die Aufgabe {todo} in der Liste {calendar} aktualisiert", + "{actor} solved todo {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} erledigt", + "You solved todo {todo} in list {calendar}" : "Du hast die Aufgabe {todo} in der Liste {calendar} erledigt", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} wiedereröffnet", + "You reopened todo {todo} in list {calendar}" : "Du hast die Aufgabe {todo} in der Liste {calendar} wiedereröffnet", + "A calendar <strong>todo</strong> was modified" : "Eine Kalender-<strong>Aufgabe</strong> wurde bearbeitet" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/dav/l10n/de.json b/apps/dav/l10n/de.json index a53bd9f0473..0bdb670759e 100644 --- a/apps/dav/l10n/de.json +++ b/apps/dav/l10n/de.json @@ -1,6 +1,6 @@ { "translations": { "Calendar" : "Kalender", - "Todos" : "Aufgaben", + "To-dos" : "Aufgaben", "Personal" : "Persönlich", "{actor} created calendar {calendar}" : "{actor} hat den Kalender {calendar} erstellt", "You created calendar {calendar}" : "Du hast den Kalender {calendar} erstellt", @@ -12,10 +12,10 @@ "You restored calendar {calendar}" : "Du hast den Kalender {calendar} wiederhergestellt", "You shared calendar {calendar} as public link" : "Du hast den Kalender {calendar} als öffentlichen Link geteilt", "You removed public link for calendar {calendar}" : "Du hast den öffentlichen Link für Kalender {calendar} entfernt", - "{actor} shared calendar {calendar} with you" : "{actor} hat den Kalender {calendar} mit Dir geteilt", + "{actor} shared calendar {calendar} with you" : "{actor} hat den Kalender {calendar} mit dir geteilt", "You shared calendar {calendar} with {user}" : "Du hast den Kalender {calendar} mit {user} geteilt", "{actor} shared calendar {calendar} with {user}" : "{actor} hat den Kalender {calendar} mit {user} geteilt", - "{actor} unshared calendar {calendar} from you" : "{actor} teilt den Kalender {calendar} nicht mehr mit Dir", + "{actor} unshared calendar {calendar} from you" : "{actor} teilt den Kalender {calendar} nicht mehr mit dir", "You unshared calendar {calendar} from {user}" : "Du teilst den Kalender {calendar} nicht mehr mit {user}", "{actor} unshared calendar {calendar} from {user}" : "{actor} teilt den Kalender {calendar} nicht mehr mit {user}", "{actor} unshared calendar {calendar} from themselves" : "{actor} teilt den Kalender {calendar} nicht mehr mit sich selbst", @@ -30,23 +30,27 @@ "You deleted event {event} from calendar {calendar}" : "Du hast den Termin {event} im Kalender {calendar} gelöscht", "{actor} updated event {event} in calendar {calendar}" : "{actor} hat den Termin {event} im Kalender {calendar} aktualisiert", "You updated event {event} in calendar {calendar}" : "Du hast den Termin {event} im Kalender {calendar} aktualisiert", - "{actor} restored event {event} of calendar {calendar}" : "{actor} hat das Adressbuch {addressbook} mit Dir geteilt", + "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{actor} hat das Ereignis {event} vom Kalender {sourceCalendar} in den Kalender {targetCalendar} verschoben", + "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "Du hast das Ereignis {event} vom Kalender {sourceCalendar} in den Kalender {targetCalendar} verschoben", + "{actor} restored event {event} of calendar {calendar}" : "{actor} hat das Adressbuch {addressbook} mit dir geteilt", "You restored event {event} of calendar {calendar}" : "Du hast den Termin {event} im Kalender {calendar} wiederhergestellt", "Busy" : "Beschäftigt", - "{actor} created todo {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} erstellt", - "You created todo {todo} in list {calendar}" : "Du hast die Aufgabe {todo} in der Liste {calendar} erstellt", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} gelöscht", - "You deleted todo {todo} from list {calendar}" : "Du hast die Aufgabe {todo} in der Liste {calendar} gelöscht", - "{actor} updated todo {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} aktualisiert", - "You updated todo {todo} in list {calendar}" : "Du hast die Aufgabe {todo} in der Liste {calendar} aktualisiert", - "{actor} solved todo {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} erledigt", - "You solved todo {todo} in list {calendar}" : "Du hast die Aufgabe {todo} in der Liste {calendar} erledigt", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} wiedereröffnet", - "You reopened todo {todo} in list {calendar}" : "Du hast die Aufgabe {todo} in der Liste {calendar} wiedereröffnet", + "{actor} created to-do {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} erstellt", + "You created to-do {todo} in list {calendar}" : "Du hast eine Aufgabe {todo} in der Liste {calendar} erstellt", + "{actor} deleted to-do {todo} from list {calendar}" : "{actor} hat die Aufgabe {todo} aus der Liste {calendar} gelöscht", + "You deleted to-do {todo} from list {calendar}" : "Du hast die Aufgabe {todo} aus der Liste {calendar} gelöscht", + "{actor} updated to-do {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} aktualisiert", + "You updated to-do {todo} in list {calendar}" : "Du hast die Aufgabe {todo} in der Liste {calendar} aktualisiert", + "{actor} solved to-do {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} erledigt", + "You solved to-do {todo} in list {calendar}" : "Du hast die Aufgabe {todo} in der Liste {calendar} erledigt", + "{actor} reopened to-do {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} wiedereröffnet", + "You reopened to-do {todo} in list {calendar}" : "Du hast die Aufgabe {todo} in der Liste {calendar} wiedereröffnet", + "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor} hat die Aufgabe {todo} von der Liste {sourceCalendar} in die Liste {targetCalendar} verschoben", + "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "Du hast die Aufgabe {todo} von der Liste {sourceCalendar} in die Liste {targetCalendar} verschoben", "Calendar, contacts and tasks" : "Kalender, Kontakte und Aufgaben", "A <strong>calendar</strong> was modified" : "Ein <strong>Kalender</strong> wurde bearbeitet", "A calendar <strong>event</strong> was modified" : "Ein Kalender-<strong>Termin</strong> wurde bearbeitet", - "A calendar <strong>todo</strong> was modified" : "Eine Kalender-<strong>Aufgabe</strong> wurde bearbeitet", + "A calendar <strong>to-do</strong> was modified" : "Eine Kalender-<strong>Aufgabe</strong> wurde geändert", "Contact birthdays" : "Geburtstage von Kontakten", "Death of %s" : "Todestag von %s", "Calendar:" : "Kalender:", @@ -88,13 +92,13 @@ "You deleted address book {addressbook}" : "Du hast das Adressbuch {addressbook} gelöscht", "{actor} updated address book {addressbook}" : "{actor} hat das Adressbuch {addressbook} aktualisiert", "You updated address book {addressbook}" : "Du hast das Adressbuch {addressbook} aktualisiert", - "{actor} shared address book {addressbook} with you" : "{actor} hat das Adressbuch {addressbook} mit Dir geteilt", + "{actor} shared address book {addressbook} with you" : "{actor} hat das Adressbuch {addressbook} mit dir geteilt", "You shared address book {addressbook} with {user}" : "Du hast das Adressbuch {addressbook} geteilt", "{actor} shared address book {addressbook} with {user}" : "{actor} hat das Adressbuch {addressbook} mit {user} geteilt", - "{actor} unshared address book {addressbook} from you" : "{actor} teilt das Adressbuch {addressbook} nicht mehr mit Dir", + "{actor} unshared address book {addressbook} from you" : "{actor} teilt das Adressbuch {addressbook} nicht mehr mit dir.", "You unshared address book {addressbook} from {user}" : "Du teilst das Adressbuch {addressbook} nicht mehr mit {user}", "{actor} unshared address book {addressbook} from {user}" : "{actor} teilt das Adressbuch {addressbook} nicht mehr mit {user}", - "{actor} unshared address book {addressbook} from themselves" : "{actor} teilt das Adressbuch {addressbook} nicht mehr mit Dir", + "{actor} unshared address book {addressbook} from themselves" : "{actor} teilt das Adressbuch {addressbook} nicht mehr mit dir.", "You shared address book {addressbook} with group {group}" : "Du hast das Adressbuch {addressbook} mit der Gruppe {group} geteilt", "{actor} shared address book {addressbook} with group {group}" : "{actor} hat das Adressbuch {addressbook} mit der Gruppe {group} geteilt", "You unshared address book {addressbook} from group {group}" : "Du teilst das Adressbuch {addressbook} nicht mehr mit der Gruppe {group}", @@ -140,7 +144,7 @@ "WebDAV" : "WebDAV", "WebDAV endpoint" : "WebDAV-Endpunkt", "Availability" : "Verfügbarkeit", - "If you configure your working hours, other users will see when you are out of office when they book a meeting." : "Wenn Du Deine Arbeitszeiten konfigurierst, können andere Benutzer sehen, wann Du nicht im Büro bist, wenn sie eine Besprechung buchen.", + "If you configure your working hours, other users will see when you are out of office when they book a meeting." : "Wenn du deine Arbeitszeiten konfigurierst, können andere Benutzer sehen, wann du nicht im Büro bist, wenn sie eine Besprechung buchen.", "Time zone:" : "Zeitzone:", "to" : "an", "Delete slot" : "Slot löschen", @@ -153,6 +157,7 @@ "Friday" : "Freitag", "Saturday" : "Samstag", "Sunday" : "Sonntag", + "Automatically set user status to \"Do not disturb\" outside of availability to mute all notifications." : "Setze den Benutzerstatus automatisch auf „Nicht stören“, wenn du nicht erreichbar bist, um alle Benachrichtigungen stumm zu schalten.", "Save" : "Speichern", "Failed to load availability" : "Fehler beim Laden der Verfügbarkeit", "Saved availability" : "Verfügbarkeit gespeichert", @@ -161,20 +166,32 @@ "Send invitations to attendees" : "Einladungen an die Teilnehmer versenden", "Automatically generate a birthday calendar" : "Automatisch einen Kalender für Geburtstage erstellen", "Birthday calendars will be generated by a background job." : "Kalender für Geburtstage werden von einem Hintergrund-Auftrag erstellt", - "Hence they will not be available immediately after enabling but will show up after some time." : "Die Einträge werden nicht sofort angezeigt. Nach der Aktivierung wird es ein wenig dauern bis zur Anzeige.", + "Hence they will not be available immediately after enabling but will show up after some time." : "Die Einträge werden nicht sofort angezeigt. Nach der Aktivierung wird es bis zur Anzeige ein wenig dauern.", "Send notifications for events" : "Sende Benachrichtigungen für Termine", - "Notifications are sent via background jobs, so these must occur often enough." : "Benachrichtigungen werden von Hintergrundjobs versendet, so dass diese häufig genug ausgeführt werden müssen.", + "Notifications are sent via background jobs, so these must occur often enough." : "Benachrichtigungen werden von Hintergrundjobs versendet, so dass diese häufig genug ausgeführt werden.", "Send reminder notifications to calendar sharees as well" : "Erinnerungsbenachrichtigungen auch an die freigegebenen Kalender senden", "Reminders are always sent to organizers and attendees." : "Erinnerungen werden immer an Organisatoren und Teilnehmer gesendet.", "Enable notifications for events via push" : "Benachrichtigungen für Termine per Push aktivieren", - "Also install the {calendarappstoreopen}Calendar app{linkclose}, or {calendardocopen}connect your desktop & mobile for syncing ↗{linkclose}." : "Installiere außerdem die {calendarappstoreopen}Kalender-App{linkclose} oder {calendardocopen}verbinde Deinen Desktop & Mobilgerät zur Synchronisierung ↗{linkclose}.", - "Please make sure to properly set up {emailopen}the email server{linkclose}." : "Bitte stelle sicher, dass Du {emailopen}den E-Mail Server{linkclose} ordnungsgemäß einrichtest.", - "There was an error updating your attendance status." : "Es ist ein Fehler beim Aktualisieren Deines Teilnehmerstatus aufgetreten.", + "Also install the {calendarappstoreopen}Calendar app{linkclose}, or {calendardocopen}connect your desktop & mobile for syncing ↗{linkclose}." : "Installiere außerdem die {calendarappstoreopen}Kalender-App{linkclose} oder {calendardocopen}verbinde deinen Desktop & Mobilgerät zur Synchronisierung ↗{linkclose}.", + "Please make sure to properly set up {emailopen}the email server{linkclose}." : "Bitte stelle sicher, dass du {emailopen}den E-Mail Server{linkclose} ordnungsgemäß einrichtest.", + "There was an error updating your attendance status." : "Es ist ein Fehler beim Aktualisieren deines Teilnehmerstatus aufgetreten.", "Please contact the organizer directly." : "Bitte den Organisator direkt kontaktieren.", "Are you accepting the invitation?" : "Die Einladung annehmen?", "Tentative" : "Vorläufig", "Number of guests" : "Anzahl Gäste", "Comment" : "Kommentar", - "Your attendance was updated successfully." : "Dein Teilnehmerstatus wurde aktualisiert." + "Your attendance was updated successfully." : "Dein Teilnehmerstatus wurde aktualisiert.", + "Todos" : "Aufgaben", + "{actor} created todo {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} erstellt", + "You created todo {todo} in list {calendar}" : "Du hast die Aufgabe {todo} in der Liste {calendar} erstellt", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} gelöscht", + "You deleted todo {todo} from list {calendar}" : "Du hast die Aufgabe {todo} in der Liste {calendar} gelöscht", + "{actor} updated todo {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} aktualisiert", + "You updated todo {todo} in list {calendar}" : "Du hast die Aufgabe {todo} in der Liste {calendar} aktualisiert", + "{actor} solved todo {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} erledigt", + "You solved todo {todo} in list {calendar}" : "Du hast die Aufgabe {todo} in der Liste {calendar} erledigt", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} wiedereröffnet", + "You reopened todo {todo} in list {calendar}" : "Du hast die Aufgabe {todo} in der Liste {calendar} wiedereröffnet", + "A calendar <strong>todo</strong> was modified" : "Eine Kalender-<strong>Aufgabe</strong> wurde bearbeitet" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/dav/l10n/de_DE.js b/apps/dav/l10n/de_DE.js index 3c230ad7d00..2a39b390d40 100644 --- a/apps/dav/l10n/de_DE.js +++ b/apps/dav/l10n/de_DE.js @@ -2,7 +2,7 @@ OC.L10N.register( "dav", { "Calendar" : "Kalender", - "Todos" : "Aufgaben", + "To-dos" : "Aufgaben", "Personal" : "Persönlich", "{actor} created calendar {calendar}" : "{actor} hat den Kalender {calendar} erstellt", "You created calendar {calendar}" : "Sie haben den Kalender {calendar} erstellt", @@ -32,23 +32,27 @@ OC.L10N.register( "You deleted event {event} from calendar {calendar}" : "Sie haben den Termin {event} im Kalender {calendar} gelöscht", "{actor} updated event {event} in calendar {calendar}" : "{actor} hat den Termin {event} im Kalender {calendar} aktualisiert", "You updated event {event} in calendar {calendar}" : "Sie haben den Termin {event} im Kalender {calendar} aktualisiert", + "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{actor} hat das Ereignis {event} vom Kalender {sourceCalendar} in den Kalender {targetCalendar} verschoben", + "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "Sie haben das Ereignis {event} vom Kalender {sourceCalendar} in den Kalender {targetCalendar} verschoben", "{actor} restored event {event} of calendar {calendar}" : "{actor} hat den Termin {event} im Kalender {calendar} wiederhergestellt", "You restored event {event} of calendar {calendar}" : "Sie haben den Termin {event} im Kalender {calendar} wiederhergestellt", "Busy" : "Beschäftigt", - "{actor} created todo {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} erstellt", - "You created todo {todo} in list {calendar}" : "Sie haben die Aufgabe {todo} in der Liste {calendar} erstellt", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} gelöscht", - "You deleted todo {todo} from list {calendar}" : "Sie haben die Aufgabe {todo} in der Liste {calendar} gelöscht", - "{actor} updated todo {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} aktualisiert", - "You updated todo {todo} in list {calendar}" : "Sie haben die Aufgabe {todo} in der Liste {calendar} aktualisiert", - "{actor} solved todo {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} erledigt", - "You solved todo {todo} in list {calendar}" : "Sie haben die Aufgabe {todo} in der Liste {calendar} erledigt", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} wiedereröffnet", - "You reopened todo {todo} in list {calendar}" : "Sie haben die Aufgabe {todo} in der Liste {calendar} wiedereröffnet", + "{actor} created to-do {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} erstellt", + "You created to-do {todo} in list {calendar}" : "Sie haben eine Aufgabe {todo} in der Liste {calendar} erstellt", + "{actor} deleted to-do {todo} from list {calendar}" : "{actor} hat die Aufgabe {todo} aus der Liste {calendar} gelöscht", + "You deleted to-do {todo} from list {calendar}" : "Sie haben die Aufgabe {todo} aus der Liste {calendar} gelöscht", + "{actor} updated to-do {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} aktualisiert", + "You updated to-do {todo} in list {calendar}" : "Sie haben die Aufgabe {todo} in der Liste {calendar} aktualisiert", + "{actor} solved to-do {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} erledigt", + "You solved to-do {todo} in list {calendar}" : "Sie haben die Aufgabe {todo} in der Liste {calendar} erledigt", + "{actor} reopened to-do {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} wiedereröffnet", + "You reopened to-do {todo} in list {calendar}" : "Sie haben die Aufgabe {todo} in der Liste {calendar} wiedereröffnet", + "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor} hat die Aufgabe {todo} von der Liste {sourceCalendar} in die Liste {targetCalendar} verschoben", + "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "Sie haben die Aufgabe {todo} von der Liste {sourceCalendar} in die Liste {targetCalendar} verschoben", "Calendar, contacts and tasks" : "Kalender, Kontakte und Aufgaben", "A <strong>calendar</strong> was modified" : "Ein <strong>Kalender</strong> wurde bearbeitet", "A calendar <strong>event</strong> was modified" : "Ein Kalender-<strong>Termin</strong> wurde bearbeitet", - "A calendar <strong>todo</strong> was modified" : "Eine Kalender-<strong>Aufgabe</strong> wurde bearbeitet", + "A calendar <strong>to-do</strong> was modified" : "Eine Kalender-<strong>Aufgabe</strong> wurde bearbeitet", "Contact birthdays" : "Geburtstage von Kontakten", "Death of %s" : "Todestag von %s", "Calendar:" : "Kalender:", @@ -155,6 +159,7 @@ OC.L10N.register( "Friday" : "Freitag", "Saturday" : "Samstag", "Sunday" : "Sonntag", + "Automatically set user status to \"Do not disturb\" outside of availability to mute all notifications." : "Setzen Sie den Benutzerstatus wenn Sie nicht erreichbar sind automatisch auf „Nicht stören“, um alle Benachrichtigungen stumm zu schalten.", "Save" : "Speichern", "Failed to load availability" : "Laden der Verfügbarkeit fehlgeschlagen", "Saved availability" : "Verfügbarkeit gespeichert", @@ -177,6 +182,18 @@ OC.L10N.register( "Tentative" : "Vorläufig", "Number of guests" : "Anzahl Gäste", "Comment" : "Kommentar", - "Your attendance was updated successfully." : "Ihr Teilnehmerstatus wurde aktualisiert." + "Your attendance was updated successfully." : "Ihr Teilnehmerstatus wurde aktualisiert.", + "Todos" : "Aufgaben", + "{actor} created todo {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} erstellt", + "You created todo {todo} in list {calendar}" : "Sie haben die Aufgabe {todo} in der Liste {calendar} erstellt", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} gelöscht", + "You deleted todo {todo} from list {calendar}" : "Sie haben die Aufgabe {todo} in der Liste {calendar} gelöscht", + "{actor} updated todo {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} aktualisiert", + "You updated todo {todo} in list {calendar}" : "Sie haben die Aufgabe {todo} in der Liste {calendar} aktualisiert", + "{actor} solved todo {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} erledigt", + "You solved todo {todo} in list {calendar}" : "Sie haben die Aufgabe {todo} in der Liste {calendar} erledigt", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} wiedereröffnet", + "You reopened todo {todo} in list {calendar}" : "Sie haben die Aufgabe {todo} in der Liste {calendar} wiedereröffnet", + "A calendar <strong>todo</strong> was modified" : "Eine Kalender-<strong>Aufgabe</strong> wurde bearbeitet" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/dav/l10n/de_DE.json b/apps/dav/l10n/de_DE.json index 9921f64e22b..c264ef62fde 100644 --- a/apps/dav/l10n/de_DE.json +++ b/apps/dav/l10n/de_DE.json @@ -1,6 +1,6 @@ { "translations": { "Calendar" : "Kalender", - "Todos" : "Aufgaben", + "To-dos" : "Aufgaben", "Personal" : "Persönlich", "{actor} created calendar {calendar}" : "{actor} hat den Kalender {calendar} erstellt", "You created calendar {calendar}" : "Sie haben den Kalender {calendar} erstellt", @@ -30,23 +30,27 @@ "You deleted event {event} from calendar {calendar}" : "Sie haben den Termin {event} im Kalender {calendar} gelöscht", "{actor} updated event {event} in calendar {calendar}" : "{actor} hat den Termin {event} im Kalender {calendar} aktualisiert", "You updated event {event} in calendar {calendar}" : "Sie haben den Termin {event} im Kalender {calendar} aktualisiert", + "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{actor} hat das Ereignis {event} vom Kalender {sourceCalendar} in den Kalender {targetCalendar} verschoben", + "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "Sie haben das Ereignis {event} vom Kalender {sourceCalendar} in den Kalender {targetCalendar} verschoben", "{actor} restored event {event} of calendar {calendar}" : "{actor} hat den Termin {event} im Kalender {calendar} wiederhergestellt", "You restored event {event} of calendar {calendar}" : "Sie haben den Termin {event} im Kalender {calendar} wiederhergestellt", "Busy" : "Beschäftigt", - "{actor} created todo {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} erstellt", - "You created todo {todo} in list {calendar}" : "Sie haben die Aufgabe {todo} in der Liste {calendar} erstellt", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} gelöscht", - "You deleted todo {todo} from list {calendar}" : "Sie haben die Aufgabe {todo} in der Liste {calendar} gelöscht", - "{actor} updated todo {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} aktualisiert", - "You updated todo {todo} in list {calendar}" : "Sie haben die Aufgabe {todo} in der Liste {calendar} aktualisiert", - "{actor} solved todo {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} erledigt", - "You solved todo {todo} in list {calendar}" : "Sie haben die Aufgabe {todo} in der Liste {calendar} erledigt", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} wiedereröffnet", - "You reopened todo {todo} in list {calendar}" : "Sie haben die Aufgabe {todo} in der Liste {calendar} wiedereröffnet", + "{actor} created to-do {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} erstellt", + "You created to-do {todo} in list {calendar}" : "Sie haben eine Aufgabe {todo} in der Liste {calendar} erstellt", + "{actor} deleted to-do {todo} from list {calendar}" : "{actor} hat die Aufgabe {todo} aus der Liste {calendar} gelöscht", + "You deleted to-do {todo} from list {calendar}" : "Sie haben die Aufgabe {todo} aus der Liste {calendar} gelöscht", + "{actor} updated to-do {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} aktualisiert", + "You updated to-do {todo} in list {calendar}" : "Sie haben die Aufgabe {todo} in der Liste {calendar} aktualisiert", + "{actor} solved to-do {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} erledigt", + "You solved to-do {todo} in list {calendar}" : "Sie haben die Aufgabe {todo} in der Liste {calendar} erledigt", + "{actor} reopened to-do {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} wiedereröffnet", + "You reopened to-do {todo} in list {calendar}" : "Sie haben die Aufgabe {todo} in der Liste {calendar} wiedereröffnet", + "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor} hat die Aufgabe {todo} von der Liste {sourceCalendar} in die Liste {targetCalendar} verschoben", + "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "Sie haben die Aufgabe {todo} von der Liste {sourceCalendar} in die Liste {targetCalendar} verschoben", "Calendar, contacts and tasks" : "Kalender, Kontakte und Aufgaben", "A <strong>calendar</strong> was modified" : "Ein <strong>Kalender</strong> wurde bearbeitet", "A calendar <strong>event</strong> was modified" : "Ein Kalender-<strong>Termin</strong> wurde bearbeitet", - "A calendar <strong>todo</strong> was modified" : "Eine Kalender-<strong>Aufgabe</strong> wurde bearbeitet", + "A calendar <strong>to-do</strong> was modified" : "Eine Kalender-<strong>Aufgabe</strong> wurde bearbeitet", "Contact birthdays" : "Geburtstage von Kontakten", "Death of %s" : "Todestag von %s", "Calendar:" : "Kalender:", @@ -153,6 +157,7 @@ "Friday" : "Freitag", "Saturday" : "Samstag", "Sunday" : "Sonntag", + "Automatically set user status to \"Do not disturb\" outside of availability to mute all notifications." : "Setzen Sie den Benutzerstatus wenn Sie nicht erreichbar sind automatisch auf „Nicht stören“, um alle Benachrichtigungen stumm zu schalten.", "Save" : "Speichern", "Failed to load availability" : "Laden der Verfügbarkeit fehlgeschlagen", "Saved availability" : "Verfügbarkeit gespeichert", @@ -175,6 +180,18 @@ "Tentative" : "Vorläufig", "Number of guests" : "Anzahl Gäste", "Comment" : "Kommentar", - "Your attendance was updated successfully." : "Ihr Teilnehmerstatus wurde aktualisiert." + "Your attendance was updated successfully." : "Ihr Teilnehmerstatus wurde aktualisiert.", + "Todos" : "Aufgaben", + "{actor} created todo {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} erstellt", + "You created todo {todo} in list {calendar}" : "Sie haben die Aufgabe {todo} in der Liste {calendar} erstellt", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} gelöscht", + "You deleted todo {todo} from list {calendar}" : "Sie haben die Aufgabe {todo} in der Liste {calendar} gelöscht", + "{actor} updated todo {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} aktualisiert", + "You updated todo {todo} in list {calendar}" : "Sie haben die Aufgabe {todo} in der Liste {calendar} aktualisiert", + "{actor} solved todo {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} erledigt", + "You solved todo {todo} in list {calendar}" : "Sie haben die Aufgabe {todo} in der Liste {calendar} erledigt", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} hat die Aufgabe {todo} in der Liste {calendar} wiedereröffnet", + "You reopened todo {todo} in list {calendar}" : "Sie haben die Aufgabe {todo} in der Liste {calendar} wiedereröffnet", + "A calendar <strong>todo</strong> was modified" : "Eine Kalender-<strong>Aufgabe</strong> wurde bearbeitet" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/dav/l10n/el.js b/apps/dav/l10n/el.js index e9a8c403943..45ce51a502f 100644 --- a/apps/dav/l10n/el.js +++ b/apps/dav/l10n/el.js @@ -2,7 +2,6 @@ OC.L10N.register( "dav", { "Calendar" : "Ημερολόγιο", - "Todos" : "Εργασίες προς εκτέλεση", "Personal" : "Προσωπικά", "{actor} created calendar {calendar}" : "{actor} δημιουργήθηκε το ημερολόγιο {calendar}", "You created calendar {calendar}" : "Δημιουργήσατε ημερολόγιο {ημερολόγιο}", @@ -10,6 +9,7 @@ OC.L10N.register( "You deleted calendar {calendar}" : "Διαγράψατε το ημερολόγιο {calendar}", "{actor} updated calendar {calendar}" : "{actor} ενημέρωσε το ημερολόγιο {calendar}", "You updated calendar {calendar}" : "Έχετε ενημερώσει το ημερολόγιο {calendar}", + "You restored calendar {calendar}" : "Επαναφέρατε το ημερολόγιο {calendar}", "You shared calendar {calendar} as public link" : "Μοιραστήκατε το ημερολόγιο {calendar} με δημόσιο σύνδεσμο.", "You removed public link for calendar {calendar}" : "Αφαιρέσατε τον δημόσιο σύνδεσμο για το ημερολόγιο {calendar}", "{actor} shared calendar {calendar} with you" : "{actor} διαμοιράστηκε το ημερολόγιο {calendar} με εσάς", @@ -31,19 +31,8 @@ OC.L10N.register( "{actor} updated event {event} in calendar {calendar}" : "Ο {actor} ενημέρωσε το γεγονός {event} στο ημερολόγιο {calendar}", "You updated event {event} in calendar {calendar}" : "Ενημερώσατε το συμβάν {event} στο ημερολόγιο {calendar}", "Busy" : "Απασχολημένος", - "{actor} created todo {todo} in list {calendar}" : "{actor} δημιούργησε την εκκρεμότητα {todo} στη λίστα {ημερολόγιο}", - "You created todo {todo} in list {calendar}" : "Δημιουργήσατε την εκκρεμότητα {todo} στη λίστα {ημερολόγιο}", - "{actor} deleted todo {todo} from list {calendar}" : "Ο {actor} διέγραψε την εκκρεμότητα {todo} από τη λίστα {ημερολόγιο}", - "You deleted todo {todo} from list {calendar}" : "Διέγραψες την εκκρεμότητα {todo} από τη λίστα {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} ενημέρωσε την εκκρεμότητα {todo} στη λίστα {calendar}", - "You updated todo {todo} in list {calendar}" : "Ενημέρωσες την εκκρεμότητα {todo} στη λίστα {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} επίλυσε την εκκρεμότητα {todo} στην λίστα {calendar}", - "You solved todo {todo} in list {calendar}" : "Επίλυσες την εκκρεμότητα {todo} στην λίστα {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} άνοιξε ξανά την εκκρεμότητα {todo} στην λίστα {calendar}", - "You reopened todo {todo} in list {calendar}" : "Άνοιξες ξανά την εκκρεμότητα {todo} στην λίστα {calendar}", "A <strong>calendar</strong> was modified" : "Τροποποιήθηκε ένα <strong>ημερολόγιο</strong> ", "A calendar <strong>event</strong> was modified" : "Τροποποιήθηκε ένα <strong>γεγονός</strong> του ημερολογίου", - "A calendar <strong>todo</strong> was modified" : "Ενός ημερολογίου η <strong>εκκρεμότητα</strong> τροποποιήθηκε", "Contact birthdays" : "Γενέθλια επαφών", "Death of %s" : "Θάνατος του %s", "Calendar:" : "Ημερολόγιο:", @@ -76,6 +65,7 @@ OC.L10N.register( "More options …" : "Περισσότερες επιλογές...", "More options at %s" : "Περισσότερες επιλογές στο %s", "Contacts" : "Επαφές", + "System is in maintenance mode." : "Το σύστημα βρίσκεται σε λειτουργία συντήρησης.", "Upgrade needed" : "Απαιτείται αναβάθμιση", "Your %s needs to be configured to use HTTPS in order to use CalDAV and CardDAV with iOS/macOS." : "Το %s θα πρέπει να ρυθμιστεί για να χρησιμοποιεί HTTPS για την χρήση του CalDAV και του CardDAV με το iOS/macOS.", "Configures a CalDAV account" : "Ρυθμίσεις λογαριασμού CalDAV", @@ -87,9 +77,12 @@ OC.L10N.register( "Contacts and groups" : "Επαφές και ομάδες", "WebDAV" : "WebDAV", "WebDAV endpoint" : "Τερματικό WebDAV", + "Availability" : "Διαθεσιμότητα", + "If you configure your working hours, other users will see when you are out of office when they book a meeting." : "Εάν διαμορφώσετε τις ώρες εργασίας σας, οι άλλοι χρήστες θα βλέπουν πότε είστε εκτός γραφείου όταν κάνουν κράτηση για μια συνάντηση.", "Time zone:" : "Ζώνη ώρας:", "to" : "προς", "Delete slot" : "Διαγραφή θέσης", + "No working hours set" : "Δεν έχει οριστεί ωράριο εργασίας", "Monday" : "Δευτέρα", "Tuesday" : "Τρίτη", "Wednesday" : "Τετάρτη", @@ -98,6 +91,8 @@ OC.L10N.register( "Saturday" : "Σάββατο", "Sunday" : "Κυριακή", "Save" : "Αποθήκευση", + "Failed to load availability" : "Αποτυχία φόρτωσης της διαθεσιμότητας", + "Failed to save availability" : "Αποτυχία αποθήκευσης της διαθεσιμότητας", "Calendar server" : "Διακομιστής ημερολογίου", "Send invitations to attendees" : "Αποστολή προσκλήσεων στους συμμετέχοντες.", "Automatically generate a birthday calendar" : "Δημιουργία ημερολογίου γενεθλίων αυτόματα", @@ -105,6 +100,8 @@ OC.L10N.register( "Hence they will not be available immediately after enabling but will show up after some time." : "Ως εκ τούτου, δεν θα είναι διαθέσιμα αμέσως μετά την ενεργοποίηση, αλλά θα εμφανιστούν μετά από λίγη ώρα.", "Send notifications for events" : "Αποστολή ειδοποιήσεων για γεγονότα", "Notifications are sent via background jobs, so these must occur often enough." : "Οι ειδοποιήσεις αποστέλλονται μέσω εργασιών παρασκηνίου, οπότε πρέπει να εμφανίζονται αρκετά συχνά.", + "Send reminder notifications to calendar sharees as well" : "Αποστολή ειδοποιήσεων υπενθύμισης και στους κοινούς χρήστες του ημερολογίου", + "Reminders are always sent to organizers and attendees." : "Οι υπενθυμίσεις αποστέλλονται πάντα στους διοργανωτές και στους συμμετέχοντες.", "Enable notifications for events via push" : "Ενεργοποίηση ειδοποιήσεων μέσω push", "Also install the {calendarappstoreopen}Calendar app{linkclose}, or {calendardocopen}connect your desktop & mobile for syncing ↗{linkclose}." : "Εγκαταστήστε επίσης την {calendarappstoreopen}Εφαρμογή ημερολογίου{linkclose}, ή {calendardocopen}συνδέστε τον υπολογιστή & το κινητό σας για συγχρονισμό ↗{linkclose}.", "Please make sure to properly set up {emailopen}the email server{linkclose}." : "Παρακαλώ σιγουρευτείτε για την σωστή ρύθμιση {emailopen}του διακομιστή αλληλογραφίας{linkclose}.", @@ -112,7 +109,20 @@ OC.L10N.register( "Please contact the organizer directly." : "Παρακαλώ επικοινωνήστε απ' ευθείας με τον διοργανωτή.", "Are you accepting the invitation?" : "Αποδέχεστε την πρόσκληση;", "Tentative" : "Δοκιμαστικό", + "Number of guests" : "Πλήθος επισκεπτών", "Comment" : "Σχόλιο", - "Your attendance was updated successfully." : "Η παρουσία σας ενημερώθηκε με επιτυχία." + "Your attendance was updated successfully." : "Η παρουσία σας ενημερώθηκε με επιτυχία.", + "Todos" : "Εργασίες προς εκτέλεση", + "{actor} created todo {todo} in list {calendar}" : "{actor} δημιούργησε την εκκρεμότητα {todo} στη λίστα {ημερολόγιο}", + "You created todo {todo} in list {calendar}" : "Δημιουργήσατε την εκκρεμότητα {todo} στη λίστα {ημερολόγιο}", + "{actor} deleted todo {todo} from list {calendar}" : "Ο {actor} διέγραψε την εκκρεμότητα {todo} από τη λίστα {ημερολόγιο}", + "You deleted todo {todo} from list {calendar}" : "Διέγραψες την εκκρεμότητα {todo} από τη λίστα {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} ενημέρωσε την εκκρεμότητα {todo} στη λίστα {calendar}", + "You updated todo {todo} in list {calendar}" : "Ενημέρωσες την εκκρεμότητα {todo} στη λίστα {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} επίλυσε την εκκρεμότητα {todo} στην λίστα {calendar}", + "You solved todo {todo} in list {calendar}" : "Επίλυσες την εκκρεμότητα {todo} στην λίστα {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} άνοιξε ξανά την εκκρεμότητα {todo} στην λίστα {calendar}", + "You reopened todo {todo} in list {calendar}" : "Άνοιξες ξανά την εκκρεμότητα {todo} στην λίστα {calendar}", + "A calendar <strong>todo</strong> was modified" : "Ενός ημερολογίου η <strong>εκκρεμότητα</strong> τροποποιήθηκε" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/dav/l10n/el.json b/apps/dav/l10n/el.json index 79151b2d754..019d0e757c9 100644 --- a/apps/dav/l10n/el.json +++ b/apps/dav/l10n/el.json @@ -1,6 +1,5 @@ { "translations": { "Calendar" : "Ημερολόγιο", - "Todos" : "Εργασίες προς εκτέλεση", "Personal" : "Προσωπικά", "{actor} created calendar {calendar}" : "{actor} δημιουργήθηκε το ημερολόγιο {calendar}", "You created calendar {calendar}" : "Δημιουργήσατε ημερολόγιο {ημερολόγιο}", @@ -8,6 +7,7 @@ "You deleted calendar {calendar}" : "Διαγράψατε το ημερολόγιο {calendar}", "{actor} updated calendar {calendar}" : "{actor} ενημέρωσε το ημερολόγιο {calendar}", "You updated calendar {calendar}" : "Έχετε ενημερώσει το ημερολόγιο {calendar}", + "You restored calendar {calendar}" : "Επαναφέρατε το ημερολόγιο {calendar}", "You shared calendar {calendar} as public link" : "Μοιραστήκατε το ημερολόγιο {calendar} με δημόσιο σύνδεσμο.", "You removed public link for calendar {calendar}" : "Αφαιρέσατε τον δημόσιο σύνδεσμο για το ημερολόγιο {calendar}", "{actor} shared calendar {calendar} with you" : "{actor} διαμοιράστηκε το ημερολόγιο {calendar} με εσάς", @@ -29,19 +29,8 @@ "{actor} updated event {event} in calendar {calendar}" : "Ο {actor} ενημέρωσε το γεγονός {event} στο ημερολόγιο {calendar}", "You updated event {event} in calendar {calendar}" : "Ενημερώσατε το συμβάν {event} στο ημερολόγιο {calendar}", "Busy" : "Απασχολημένος", - "{actor} created todo {todo} in list {calendar}" : "{actor} δημιούργησε την εκκρεμότητα {todo} στη λίστα {ημερολόγιο}", - "You created todo {todo} in list {calendar}" : "Δημιουργήσατε την εκκρεμότητα {todo} στη λίστα {ημερολόγιο}", - "{actor} deleted todo {todo} from list {calendar}" : "Ο {actor} διέγραψε την εκκρεμότητα {todo} από τη λίστα {ημερολόγιο}", - "You deleted todo {todo} from list {calendar}" : "Διέγραψες την εκκρεμότητα {todo} από τη λίστα {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} ενημέρωσε την εκκρεμότητα {todo} στη λίστα {calendar}", - "You updated todo {todo} in list {calendar}" : "Ενημέρωσες την εκκρεμότητα {todo} στη λίστα {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} επίλυσε την εκκρεμότητα {todo} στην λίστα {calendar}", - "You solved todo {todo} in list {calendar}" : "Επίλυσες την εκκρεμότητα {todo} στην λίστα {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} άνοιξε ξανά την εκκρεμότητα {todo} στην λίστα {calendar}", - "You reopened todo {todo} in list {calendar}" : "Άνοιξες ξανά την εκκρεμότητα {todo} στην λίστα {calendar}", "A <strong>calendar</strong> was modified" : "Τροποποιήθηκε ένα <strong>ημερολόγιο</strong> ", "A calendar <strong>event</strong> was modified" : "Τροποποιήθηκε ένα <strong>γεγονός</strong> του ημερολογίου", - "A calendar <strong>todo</strong> was modified" : "Ενός ημερολογίου η <strong>εκκρεμότητα</strong> τροποποιήθηκε", "Contact birthdays" : "Γενέθλια επαφών", "Death of %s" : "Θάνατος του %s", "Calendar:" : "Ημερολόγιο:", @@ -74,6 +63,7 @@ "More options …" : "Περισσότερες επιλογές...", "More options at %s" : "Περισσότερες επιλογές στο %s", "Contacts" : "Επαφές", + "System is in maintenance mode." : "Το σύστημα βρίσκεται σε λειτουργία συντήρησης.", "Upgrade needed" : "Απαιτείται αναβάθμιση", "Your %s needs to be configured to use HTTPS in order to use CalDAV and CardDAV with iOS/macOS." : "Το %s θα πρέπει να ρυθμιστεί για να χρησιμοποιεί HTTPS για την χρήση του CalDAV και του CardDAV με το iOS/macOS.", "Configures a CalDAV account" : "Ρυθμίσεις λογαριασμού CalDAV", @@ -85,9 +75,12 @@ "Contacts and groups" : "Επαφές και ομάδες", "WebDAV" : "WebDAV", "WebDAV endpoint" : "Τερματικό WebDAV", + "Availability" : "Διαθεσιμότητα", + "If you configure your working hours, other users will see when you are out of office when they book a meeting." : "Εάν διαμορφώσετε τις ώρες εργασίας σας, οι άλλοι χρήστες θα βλέπουν πότε είστε εκτός γραφείου όταν κάνουν κράτηση για μια συνάντηση.", "Time zone:" : "Ζώνη ώρας:", "to" : "προς", "Delete slot" : "Διαγραφή θέσης", + "No working hours set" : "Δεν έχει οριστεί ωράριο εργασίας", "Monday" : "Δευτέρα", "Tuesday" : "Τρίτη", "Wednesday" : "Τετάρτη", @@ -96,6 +89,8 @@ "Saturday" : "Σάββατο", "Sunday" : "Κυριακή", "Save" : "Αποθήκευση", + "Failed to load availability" : "Αποτυχία φόρτωσης της διαθεσιμότητας", + "Failed to save availability" : "Αποτυχία αποθήκευσης της διαθεσιμότητας", "Calendar server" : "Διακομιστής ημερολογίου", "Send invitations to attendees" : "Αποστολή προσκλήσεων στους συμμετέχοντες.", "Automatically generate a birthday calendar" : "Δημιουργία ημερολογίου γενεθλίων αυτόματα", @@ -103,6 +98,8 @@ "Hence they will not be available immediately after enabling but will show up after some time." : "Ως εκ τούτου, δεν θα είναι διαθέσιμα αμέσως μετά την ενεργοποίηση, αλλά θα εμφανιστούν μετά από λίγη ώρα.", "Send notifications for events" : "Αποστολή ειδοποιήσεων για γεγονότα", "Notifications are sent via background jobs, so these must occur often enough." : "Οι ειδοποιήσεις αποστέλλονται μέσω εργασιών παρασκηνίου, οπότε πρέπει να εμφανίζονται αρκετά συχνά.", + "Send reminder notifications to calendar sharees as well" : "Αποστολή ειδοποιήσεων υπενθύμισης και στους κοινούς χρήστες του ημερολογίου", + "Reminders are always sent to organizers and attendees." : "Οι υπενθυμίσεις αποστέλλονται πάντα στους διοργανωτές και στους συμμετέχοντες.", "Enable notifications for events via push" : "Ενεργοποίηση ειδοποιήσεων μέσω push", "Also install the {calendarappstoreopen}Calendar app{linkclose}, or {calendardocopen}connect your desktop & mobile for syncing ↗{linkclose}." : "Εγκαταστήστε επίσης την {calendarappstoreopen}Εφαρμογή ημερολογίου{linkclose}, ή {calendardocopen}συνδέστε τον υπολογιστή & το κινητό σας για συγχρονισμό ↗{linkclose}.", "Please make sure to properly set up {emailopen}the email server{linkclose}." : "Παρακαλώ σιγουρευτείτε για την σωστή ρύθμιση {emailopen}του διακομιστή αλληλογραφίας{linkclose}.", @@ -110,7 +107,20 @@ "Please contact the organizer directly." : "Παρακαλώ επικοινωνήστε απ' ευθείας με τον διοργανωτή.", "Are you accepting the invitation?" : "Αποδέχεστε την πρόσκληση;", "Tentative" : "Δοκιμαστικό", + "Number of guests" : "Πλήθος επισκεπτών", "Comment" : "Σχόλιο", - "Your attendance was updated successfully." : "Η παρουσία σας ενημερώθηκε με επιτυχία." + "Your attendance was updated successfully." : "Η παρουσία σας ενημερώθηκε με επιτυχία.", + "Todos" : "Εργασίες προς εκτέλεση", + "{actor} created todo {todo} in list {calendar}" : "{actor} δημιούργησε την εκκρεμότητα {todo} στη λίστα {ημερολόγιο}", + "You created todo {todo} in list {calendar}" : "Δημιουργήσατε την εκκρεμότητα {todo} στη λίστα {ημερολόγιο}", + "{actor} deleted todo {todo} from list {calendar}" : "Ο {actor} διέγραψε την εκκρεμότητα {todo} από τη λίστα {ημερολόγιο}", + "You deleted todo {todo} from list {calendar}" : "Διέγραψες την εκκρεμότητα {todo} από τη λίστα {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} ενημέρωσε την εκκρεμότητα {todo} στη λίστα {calendar}", + "You updated todo {todo} in list {calendar}" : "Ενημέρωσες την εκκρεμότητα {todo} στη λίστα {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} επίλυσε την εκκρεμότητα {todo} στην λίστα {calendar}", + "You solved todo {todo} in list {calendar}" : "Επίλυσες την εκκρεμότητα {todo} στην λίστα {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} άνοιξε ξανά την εκκρεμότητα {todo} στην λίστα {calendar}", + "You reopened todo {todo} in list {calendar}" : "Άνοιξες ξανά την εκκρεμότητα {todo} στην λίστα {calendar}", + "A calendar <strong>todo</strong> was modified" : "Ενός ημερολογίου η <strong>εκκρεμότητα</strong> τροποποιήθηκε" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/dav/l10n/eo.js b/apps/dav/l10n/eo.js index 63861008c39..50cb8077a10 100644 --- a/apps/dav/l10n/eo.js +++ b/apps/dav/l10n/eo.js @@ -2,7 +2,6 @@ OC.L10N.register( "dav", { "Calendar" : "Kalendaro", - "Todos" : "Taskoj", "Personal" : "Persona", "{actor} created calendar {calendar}" : "{actor} kreis kalendaron {calendar}", "You created calendar {calendar}" : "Vi kreis kalendaron {calendar}", @@ -31,19 +30,8 @@ OC.L10N.register( "{actor} updated event {event} in calendar {calendar}" : "{actor} ĝisdatigis okazaĵon {event} en kalendaro {calendar}", "You updated event {event} in calendar {calendar}" : "Vi ĝisdatigis okazaĵon {event} en kalendaro {calendar}", "Busy" : "Okupita", - "{actor} created todo {todo} in list {calendar}" : "{actor} kreis farendaĵon {todo} en listo {calendar}", - "You created todo {todo} in list {calendar}" : "Vi kreis farendaĵon {todo} en listo {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} forigis farendaĵon {todo} en listo {calendar}", - "You deleted todo {todo} from list {calendar}" : "Vi forigis farendaĵon {todo} en listo {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} ĝisdatigis farendaĵon {todo} en listo {calendar}", - "You updated todo {todo} in list {calendar}" : "Vi ĝisdatigis farendaĵon {todo} en listo {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} plenumis farendaĵon {todo} en listo {calendar}", - "You solved todo {todo} in list {calendar}" : "Vi plenumis farendaĵon {todo} en listo {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} remalfermis farendaĵon {todo} en listo {calendar}", - "You reopened todo {todo} in list {calendar}" : "Vi remalfermis farendaĵon {todo} en listo {calendar}", "A <strong>calendar</strong> was modified" : "<strong>Kalendaro</strong> estis modifita", "A calendar <strong>event</strong> was modified" : "Kalendara <strong>okazaĵo</strong> estis modifita", - "A calendar <strong>todo</strong> was modified" : "Kalendara <strong>farendaĵo</strong> estis modifita", "Contact birthdays" : "Kontaktaj datrevenoj", "Death of %s" : "Morto de %s", "Calendar:" : "Kalendaro:", @@ -100,6 +88,18 @@ OC.L10N.register( "Are you accepting the invitation?" : "Ĉu vi akceptas la inviton?", "Tentative" : "Nekonfirmita", "Comment" : "Komento", - "Your attendance was updated successfully." : "Via ĉeesto sukcese ĝisdatiĝis." + "Your attendance was updated successfully." : "Via ĉeesto sukcese ĝisdatiĝis.", + "Todos" : "Taskoj", + "{actor} created todo {todo} in list {calendar}" : "{actor} kreis farendaĵon {todo} en listo {calendar}", + "You created todo {todo} in list {calendar}" : "Vi kreis farendaĵon {todo} en listo {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} forigis farendaĵon {todo} en listo {calendar}", + "You deleted todo {todo} from list {calendar}" : "Vi forigis farendaĵon {todo} en listo {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} ĝisdatigis farendaĵon {todo} en listo {calendar}", + "You updated todo {todo} in list {calendar}" : "Vi ĝisdatigis farendaĵon {todo} en listo {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} plenumis farendaĵon {todo} en listo {calendar}", + "You solved todo {todo} in list {calendar}" : "Vi plenumis farendaĵon {todo} en listo {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} remalfermis farendaĵon {todo} en listo {calendar}", + "You reopened todo {todo} in list {calendar}" : "Vi remalfermis farendaĵon {todo} en listo {calendar}", + "A calendar <strong>todo</strong> was modified" : "Kalendara <strong>farendaĵo</strong> estis modifita" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/dav/l10n/eo.json b/apps/dav/l10n/eo.json index 2eb6017f344..8025d45c597 100644 --- a/apps/dav/l10n/eo.json +++ b/apps/dav/l10n/eo.json @@ -1,6 +1,5 @@ { "translations": { "Calendar" : "Kalendaro", - "Todos" : "Taskoj", "Personal" : "Persona", "{actor} created calendar {calendar}" : "{actor} kreis kalendaron {calendar}", "You created calendar {calendar}" : "Vi kreis kalendaron {calendar}", @@ -29,19 +28,8 @@ "{actor} updated event {event} in calendar {calendar}" : "{actor} ĝisdatigis okazaĵon {event} en kalendaro {calendar}", "You updated event {event} in calendar {calendar}" : "Vi ĝisdatigis okazaĵon {event} en kalendaro {calendar}", "Busy" : "Okupita", - "{actor} created todo {todo} in list {calendar}" : "{actor} kreis farendaĵon {todo} en listo {calendar}", - "You created todo {todo} in list {calendar}" : "Vi kreis farendaĵon {todo} en listo {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} forigis farendaĵon {todo} en listo {calendar}", - "You deleted todo {todo} from list {calendar}" : "Vi forigis farendaĵon {todo} en listo {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} ĝisdatigis farendaĵon {todo} en listo {calendar}", - "You updated todo {todo} in list {calendar}" : "Vi ĝisdatigis farendaĵon {todo} en listo {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} plenumis farendaĵon {todo} en listo {calendar}", - "You solved todo {todo} in list {calendar}" : "Vi plenumis farendaĵon {todo} en listo {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} remalfermis farendaĵon {todo} en listo {calendar}", - "You reopened todo {todo} in list {calendar}" : "Vi remalfermis farendaĵon {todo} en listo {calendar}", "A <strong>calendar</strong> was modified" : "<strong>Kalendaro</strong> estis modifita", "A calendar <strong>event</strong> was modified" : "Kalendara <strong>okazaĵo</strong> estis modifita", - "A calendar <strong>todo</strong> was modified" : "Kalendara <strong>farendaĵo</strong> estis modifita", "Contact birthdays" : "Kontaktaj datrevenoj", "Death of %s" : "Morto de %s", "Calendar:" : "Kalendaro:", @@ -98,6 +86,18 @@ "Are you accepting the invitation?" : "Ĉu vi akceptas la inviton?", "Tentative" : "Nekonfirmita", "Comment" : "Komento", - "Your attendance was updated successfully." : "Via ĉeesto sukcese ĝisdatiĝis." + "Your attendance was updated successfully." : "Via ĉeesto sukcese ĝisdatiĝis.", + "Todos" : "Taskoj", + "{actor} created todo {todo} in list {calendar}" : "{actor} kreis farendaĵon {todo} en listo {calendar}", + "You created todo {todo} in list {calendar}" : "Vi kreis farendaĵon {todo} en listo {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} forigis farendaĵon {todo} en listo {calendar}", + "You deleted todo {todo} from list {calendar}" : "Vi forigis farendaĵon {todo} en listo {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} ĝisdatigis farendaĵon {todo} en listo {calendar}", + "You updated todo {todo} in list {calendar}" : "Vi ĝisdatigis farendaĵon {todo} en listo {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} plenumis farendaĵon {todo} en listo {calendar}", + "You solved todo {todo} in list {calendar}" : "Vi plenumis farendaĵon {todo} en listo {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} remalfermis farendaĵon {todo} en listo {calendar}", + "You reopened todo {todo} in list {calendar}" : "Vi remalfermis farendaĵon {todo} en listo {calendar}", + "A calendar <strong>todo</strong> was modified" : "Kalendara <strong>farendaĵo</strong> estis modifita" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/dav/l10n/es.js b/apps/dav/l10n/es.js index 375abc0f62b..45c60e806ca 100644 --- a/apps/dav/l10n/es.js +++ b/apps/dav/l10n/es.js @@ -2,7 +2,7 @@ OC.L10N.register( "dav", { "Calendar" : "Calendario", - "Todos" : "Todos", + "To-dos" : "Tareas", "Personal" : "Personal", "{actor} created calendar {calendar}" : "{actor} creó el calendario {calendar}", "You created calendar {calendar}" : "Usted creó el calendario {calendar}", @@ -32,23 +32,27 @@ OC.L10N.register( "You deleted event {event} from calendar {calendar}" : "Usted eliminó el evento {event} del calendario {calendar}", "{actor} updated event {event} in calendar {calendar}" : "{actor} actualizó el evento {event} en el calendario {calendar}", "You updated event {event} in calendar {calendar}" : "Usted actualizó el evento {event} en el calendario {calendar}", + "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{actor} ha movido el evento {event} del calendario {sourceCalendar} al calendario {targetCalendar}", + "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "Has movido el evento {event} del calendario {sourceCalendar} al calendario {targetCalendar}", "{actor} restored event {event} of calendar {calendar}" : "{actor} ha restablecido el evento {event} del calendario {calendar}", "You restored event {event} of calendar {calendar}" : "Has reestablecido el evento {event} del calendario {calendar}", "Busy" : "Ocupado", - "{actor} created todo {todo} in list {calendar}" : "{actor} creó la tarea {todo} en la lista {calendar}", - "You created todo {todo} in list {calendar}" : "Usted creó la tarea {todo} en la lista {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} eliminó la tarea {todo} de la lista {calendar}", - "You deleted todo {todo} from list {calendar}" : "Usted eliminó la tarea {tod} de la lista {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} actualizó la tarea {todo }en la lista {calendar}", - "You updated todo {todo} in list {calendar}" : "Usted actualizó la tarea {todo} en la lista {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} completó la tarea {todo} en la lista {calendar}", - "You solved todo {todo} in list {calendar}" : "Usted completó la tarea {todo} en la lista {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} reabrió la tarea {todo} en la lista {calendar}", - "You reopened todo {todo} in list {calendar}" : "Usted reabrió la tarea {todo} en la lista {calendar}", + "{actor} created to-do {todo} in list {calendar}" : "{actor} ha creado la tarea {todo} en la lista {calendar}", + "You created to-do {todo} in list {calendar}" : "Has creado la tarea {todo} en la lista {calendar}", + "{actor} deleted to-do {todo} from list {calendar}" : "{actor} ha eliminado la tarea{todo} de la lista {calendar}", + "You deleted to-do {todo} from list {calendar}" : "Has eliminado la tarea {todo} de la lista {calendar}", + "{actor} updated to-do {todo} in list {calendar}" : "{actor} ha actualizado la tarea {todo} en la lista {calendar}", + "You updated to-do {todo} in list {calendar}" : "Has actualizado la tarea {todo} en la lista {calendar}", + "{actor} solved to-do {todo} in list {calendar}" : "{actor} ha resuelto la tarea {todo} de la lista {calendar}", + "You solved to-do {todo} in list {calendar}" : "Has resuelto la tarea {todo} de la lista {calendar}", + "{actor} reopened to-do {todo} in list {calendar}" : "{actor} ha reabierto la tarea {todo} en la lista {calendar}", + "You reopened to-do {todo} in list {calendar}" : "Has reabierto la tarea {todo} en la lista {calendar}", + "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor} ha movido la tarea {todo} de la lista {sourceCalendar} a la lista{targetCalendar}", + "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "Has movido la tarea {todo} de la lista {sourceCalendar} a la lista {targetCalendar}", "Calendar, contacts and tasks" : "Calendario, contactos y tareas", "A <strong>calendar</strong> was modified" : "Un <strong>calendario</strong> fue modificado.", "A calendar <strong>event</strong> was modified" : "Un <strong>evento</strong> del calendario fue modificado.", - "A calendar <strong>todo</strong> was modified" : "Una <strong>lista de tareas</strong> fue modificada", + "A calendar <strong>to-do</strong> was modified" : "Se ha modificado una <strong>tarea</strong> de calendario", "Contact birthdays" : "Cumpleaños del contacto", "Death of %s" : "Muerte de %s", "Calendar:" : "Calendario:", @@ -155,6 +159,7 @@ OC.L10N.register( "Friday" : "Viernes", "Saturday" : "Sábado", "Sunday" : "Domingo", + "Automatically set user status to \"Do not disturb\" outside of availability to mute all notifications." : "Cambiar automáticamente el estado del usuario a \"No molestar\" cuando no esté disponible para silenciar todas las notificaciones.", "Save" : "Guardar", "Failed to load availability" : "No se ha podido cargar la disponibilidad", "Saved availability" : "Disponibilidad guardada", @@ -177,6 +182,18 @@ OC.L10N.register( "Tentative" : "Provisional", "Number of guests" : "Número de invitados", "Comment" : "Comentario", - "Your attendance was updated successfully." : "Tu asistencia se ha actualizado con éxito." + "Your attendance was updated successfully." : "Tu asistencia se ha actualizado con éxito.", + "Todos" : "Todos", + "{actor} created todo {todo} in list {calendar}" : "{actor} creó la tarea {todo} en la lista {calendar}", + "You created todo {todo} in list {calendar}" : "Usted creó la tarea {todo} en la lista {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} eliminó la tarea {todo} de la lista {calendar}", + "You deleted todo {todo} from list {calendar}" : "Usted eliminó la tarea {tod} de la lista {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} actualizó la tarea {todo }en la lista {calendar}", + "You updated todo {todo} in list {calendar}" : "Usted actualizó la tarea {todo} en la lista {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} completó la tarea {todo} en la lista {calendar}", + "You solved todo {todo} in list {calendar}" : "Usted completó la tarea {todo} en la lista {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} reabrió la tarea {todo} en la lista {calendar}", + "You reopened todo {todo} in list {calendar}" : "Usted reabrió la tarea {todo} en la lista {calendar}", + "A calendar <strong>todo</strong> was modified" : "Una <strong>lista de tareas</strong> fue modificada" }, "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/apps/dav/l10n/es.json b/apps/dav/l10n/es.json index 350c64df063..55f7e459654 100644 --- a/apps/dav/l10n/es.json +++ b/apps/dav/l10n/es.json @@ -1,6 +1,6 @@ { "translations": { "Calendar" : "Calendario", - "Todos" : "Todos", + "To-dos" : "Tareas", "Personal" : "Personal", "{actor} created calendar {calendar}" : "{actor} creó el calendario {calendar}", "You created calendar {calendar}" : "Usted creó el calendario {calendar}", @@ -30,23 +30,27 @@ "You deleted event {event} from calendar {calendar}" : "Usted eliminó el evento {event} del calendario {calendar}", "{actor} updated event {event} in calendar {calendar}" : "{actor} actualizó el evento {event} en el calendario {calendar}", "You updated event {event} in calendar {calendar}" : "Usted actualizó el evento {event} en el calendario {calendar}", + "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{actor} ha movido el evento {event} del calendario {sourceCalendar} al calendario {targetCalendar}", + "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "Has movido el evento {event} del calendario {sourceCalendar} al calendario {targetCalendar}", "{actor} restored event {event} of calendar {calendar}" : "{actor} ha restablecido el evento {event} del calendario {calendar}", "You restored event {event} of calendar {calendar}" : "Has reestablecido el evento {event} del calendario {calendar}", "Busy" : "Ocupado", - "{actor} created todo {todo} in list {calendar}" : "{actor} creó la tarea {todo} en la lista {calendar}", - "You created todo {todo} in list {calendar}" : "Usted creó la tarea {todo} en la lista {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} eliminó la tarea {todo} de la lista {calendar}", - "You deleted todo {todo} from list {calendar}" : "Usted eliminó la tarea {tod} de la lista {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} actualizó la tarea {todo }en la lista {calendar}", - "You updated todo {todo} in list {calendar}" : "Usted actualizó la tarea {todo} en la lista {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} completó la tarea {todo} en la lista {calendar}", - "You solved todo {todo} in list {calendar}" : "Usted completó la tarea {todo} en la lista {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} reabrió la tarea {todo} en la lista {calendar}", - "You reopened todo {todo} in list {calendar}" : "Usted reabrió la tarea {todo} en la lista {calendar}", + "{actor} created to-do {todo} in list {calendar}" : "{actor} ha creado la tarea {todo} en la lista {calendar}", + "You created to-do {todo} in list {calendar}" : "Has creado la tarea {todo} en la lista {calendar}", + "{actor} deleted to-do {todo} from list {calendar}" : "{actor} ha eliminado la tarea{todo} de la lista {calendar}", + "You deleted to-do {todo} from list {calendar}" : "Has eliminado la tarea {todo} de la lista {calendar}", + "{actor} updated to-do {todo} in list {calendar}" : "{actor} ha actualizado la tarea {todo} en la lista {calendar}", + "You updated to-do {todo} in list {calendar}" : "Has actualizado la tarea {todo} en la lista {calendar}", + "{actor} solved to-do {todo} in list {calendar}" : "{actor} ha resuelto la tarea {todo} de la lista {calendar}", + "You solved to-do {todo} in list {calendar}" : "Has resuelto la tarea {todo} de la lista {calendar}", + "{actor} reopened to-do {todo} in list {calendar}" : "{actor} ha reabierto la tarea {todo} en la lista {calendar}", + "You reopened to-do {todo} in list {calendar}" : "Has reabierto la tarea {todo} en la lista {calendar}", + "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor} ha movido la tarea {todo} de la lista {sourceCalendar} a la lista{targetCalendar}", + "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "Has movido la tarea {todo} de la lista {sourceCalendar} a la lista {targetCalendar}", "Calendar, contacts and tasks" : "Calendario, contactos y tareas", "A <strong>calendar</strong> was modified" : "Un <strong>calendario</strong> fue modificado.", "A calendar <strong>event</strong> was modified" : "Un <strong>evento</strong> del calendario fue modificado.", - "A calendar <strong>todo</strong> was modified" : "Una <strong>lista de tareas</strong> fue modificada", + "A calendar <strong>to-do</strong> was modified" : "Se ha modificado una <strong>tarea</strong> de calendario", "Contact birthdays" : "Cumpleaños del contacto", "Death of %s" : "Muerte de %s", "Calendar:" : "Calendario:", @@ -153,6 +157,7 @@ "Friday" : "Viernes", "Saturday" : "Sábado", "Sunday" : "Domingo", + "Automatically set user status to \"Do not disturb\" outside of availability to mute all notifications." : "Cambiar automáticamente el estado del usuario a \"No molestar\" cuando no esté disponible para silenciar todas las notificaciones.", "Save" : "Guardar", "Failed to load availability" : "No se ha podido cargar la disponibilidad", "Saved availability" : "Disponibilidad guardada", @@ -175,6 +180,18 @@ "Tentative" : "Provisional", "Number of guests" : "Número de invitados", "Comment" : "Comentario", - "Your attendance was updated successfully." : "Tu asistencia se ha actualizado con éxito." + "Your attendance was updated successfully." : "Tu asistencia se ha actualizado con éxito.", + "Todos" : "Todos", + "{actor} created todo {todo} in list {calendar}" : "{actor} creó la tarea {todo} en la lista {calendar}", + "You created todo {todo} in list {calendar}" : "Usted creó la tarea {todo} en la lista {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} eliminó la tarea {todo} de la lista {calendar}", + "You deleted todo {todo} from list {calendar}" : "Usted eliminó la tarea {tod} de la lista {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} actualizó la tarea {todo }en la lista {calendar}", + "You updated todo {todo} in list {calendar}" : "Usted actualizó la tarea {todo} en la lista {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} completó la tarea {todo} en la lista {calendar}", + "You solved todo {todo} in list {calendar}" : "Usted completó la tarea {todo} en la lista {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} reabrió la tarea {todo} en la lista {calendar}", + "You reopened todo {todo} in list {calendar}" : "Usted reabrió la tarea {todo} en la lista {calendar}", + "A calendar <strong>todo</strong> was modified" : "Una <strong>lista de tareas</strong> fue modificada" },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/apps/dav/l10n/eu.js b/apps/dav/l10n/eu.js index d9e0da425a1..8e723019d82 100644 --- a/apps/dav/l10n/eu.js +++ b/apps/dav/l10n/eu.js @@ -2,7 +2,7 @@ OC.L10N.register( "dav", { "Calendar" : "Egutegia", - "Todos" : "Egitekoak", + "To-dos" : "Eginbeharrak", "Personal" : "Pertsonala", "{actor} created calendar {calendar}" : "{actor}-k sortutako egutegia: {calendar}", "You created calendar {calendar}" : "{calendar} egutegia sortu duzu", @@ -32,23 +32,27 @@ OC.L10N.register( "You deleted event {event} from calendar {calendar}" : "{event} gertaera ezabatu duzu {calendar} egutegitik ", "{actor} updated event {event} in calendar {calendar}" : "{actor}-(r)ek {event} gertaera eguneratu du {calendar} egutegian", "You updated event {event} in calendar {calendar}" : "{event} gertaera eguneratu duzu {calendar} egutegian ", + "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{actor}-(e)k {event} gertaera {sourceCalendar} egutegitik {targetCalendar} egutegira mugitu duzu", + "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{event} gertaera {sourceCalendar} egutegitik {targetCalendar} egutegira mugitu duzu", "{actor} restored event {event} of calendar {calendar}" : "{actor}-(e)k berrezarri du {calendar} egutegiko {event} gertaera ", "You restored event {event} of calendar {calendar}" : "Berrezarri duzu {calendar} egutegiko {event} gertaera ", "Busy" : "Lanpetua", - "{actor} created todo {todo} in list {calendar}" : "{actor}-ek {calendar} zerrendan {todo} zeregina sortu du.", - "You created todo {todo} in list {calendar}" : "{calendar} zerrendan {todo} ekintza sortu duzu.", - "{actor} deleted todo {todo} from list {calendar}" : "{actor}-rek {calendar} zerrendan {todo} zeregina borratu du.", - "You deleted todo {todo} from list {calendar}" : " {calendar} zerrendan {todo} zeregina borratu duzu.", - "{actor} updated todo {todo} in list {calendar}" : "{actor}-rek {calendar} zerrendan {todo} zeregina eguneratu du.", - "You updated todo {todo} in list {calendar}" : "{calendar} zerrendan {todo} zeregina eguneratu duzu.", - "{actor} solved todo {todo} in list {calendar}" : "{actor}-rek {calendar} zerrendan {todo} zeregina bukatu du.", - "You solved todo {todo} in list {calendar}" : " {calendar} zerrendan {todo} zeregina bukatu duzu.", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} erabiltzaileak {calendar} zerrendan {todo} zeregina berrireki du.", - "You reopened todo {todo} in list {calendar}" : "{calendar} egutegian {todo} zeregina berrireki duzu. ", + "{actor} created to-do {todo} in list {calendar}" : "{actor}-(e)k {calendar} zerrendan {todo} egitekoa sortu du", + "You created to-do {todo} in list {calendar}" : "{calendar} zerrendan {todo} egitekoa sortu duzu", + "{actor} deleted to-do {todo} from list {calendar}" : "{actor}-(e)k {calendar} zerrendan {todo} egitekoa ezabatu du", + "You deleted to-do {todo} from list {calendar}" : " {calendar} zerrendan {todo} egitekoa ezabatu duzu", + "{actor} updated to-do {todo} in list {calendar}" : "{actor}-(e)k {calendar} zerrendan {todo} egitekoa eguneratu du", + "You updated to-do {todo} in list {calendar}" : "{calendar} zerrendan {todo} egitekoa eguneratu duzu", + "{actor} solved to-do {todo} in list {calendar}" : "{actor}-(e)k {calendar} zerrendan {todo} egitekoa bukatu du.", + "You solved to-do {todo} in list {calendar}" : " {calendar} zerrendan {todo} egitekoa bukatu duzu", + "{actor} reopened to-do {todo} in list {calendar}" : "{actor}-(e)k {calendar} zerrendan {todo} egitekoa berrireki du", + "You reopened to-do {todo} in list {calendar}" : "{calendar} zerrendan {todo} egitekoa berrireki duzu", + "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor}-(e)k {todo} egitekoa {sourceCalendar} zerrendatik {targetCalendar} zerrendara mugitu du", + "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{todo} egitekoa {sourceCalendar} zerrendatik {targetCalendar} zerrendara mugitu duzu", "Calendar, contacts and tasks" : "Egutegia, kontaktuak eta atazak", "A <strong>calendar</strong> was modified" : "Egutegia aldatu da", "A calendar <strong>event</strong> was modified" : "Egutegiaren <strong>gertaera</strong> bat aldatu da", - "A calendar <strong>todo</strong> was modified" : "Egutegiaren zeregin bat aldatu da", + "A calendar <strong>to-do</strong> was modified" : "Egutegi baten <strong>eginbeharra</strong> aldatu da", "Contact birthdays" : "Kontaktuen urtebetetzeak", "Death of %s" : "%s(r)en heriotza", "Calendar:" : "Egutegia:", @@ -155,6 +159,7 @@ OC.L10N.register( "Friday" : "Ostirala", "Saturday" : "Larunbata", "Sunday" : "Igandea", + "Automatically set user status to \"Do not disturb\" outside of availability to mute all notifications." : "Ezarri automatikoki erabiltzailearen egoera \"Ez molestatu\" moduan erabilgarritasunetik kanpo jakinarazpen guztiak isilarazteko.", "Save" : "Gorde", "Failed to load availability" : "Ezin izan da kargatu erabilgarritasuna", "Saved availability" : "Gordetako erabilgarritasuna", @@ -177,6 +182,18 @@ OC.L10N.register( "Tentative" : "Behin behinekoa", "Number of guests" : "Gonbidatu kopurua", "Comment" : "Iruzkindu", - "Your attendance was updated successfully." : "Zure parte-hartzea ondo eguneratu da." + "Your attendance was updated successfully." : "Zure parte-hartzea ondo eguneratu da.", + "Todos" : "Egitekoak", + "{actor} created todo {todo} in list {calendar}" : "{actor}-ek {calendar} zerrendan {todo} zeregina sortu du.", + "You created todo {todo} in list {calendar}" : "{calendar} zerrendan {todo} ekintza sortu duzu.", + "{actor} deleted todo {todo} from list {calendar}" : "{actor}-rek {calendar} zerrendan {todo} zeregina borratu du.", + "You deleted todo {todo} from list {calendar}" : " {calendar} zerrendan {todo} zeregina borratu duzu.", + "{actor} updated todo {todo} in list {calendar}" : "{actor}-rek {calendar} zerrendan {todo} zeregina eguneratu du.", + "You updated todo {todo} in list {calendar}" : "{calendar} zerrendan {todo} zeregina eguneratu duzu.", + "{actor} solved todo {todo} in list {calendar}" : "{actor}-rek {calendar} zerrendan {todo} zeregina bukatu du.", + "You solved todo {todo} in list {calendar}" : " {calendar} zerrendan {todo} zeregina bukatu duzu.", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} erabiltzaileak {calendar} zerrendan {todo} zeregina berrireki du.", + "You reopened todo {todo} in list {calendar}" : "{calendar} egutegian {todo} zeregina berrireki duzu. ", + "A calendar <strong>todo</strong> was modified" : "Egutegiaren zeregin bat aldatu da" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/dav/l10n/eu.json b/apps/dav/l10n/eu.json index bda903e0899..a8e79f76cf5 100644 --- a/apps/dav/l10n/eu.json +++ b/apps/dav/l10n/eu.json @@ -1,6 +1,6 @@ { "translations": { "Calendar" : "Egutegia", - "Todos" : "Egitekoak", + "To-dos" : "Eginbeharrak", "Personal" : "Pertsonala", "{actor} created calendar {calendar}" : "{actor}-k sortutako egutegia: {calendar}", "You created calendar {calendar}" : "{calendar} egutegia sortu duzu", @@ -30,23 +30,27 @@ "You deleted event {event} from calendar {calendar}" : "{event} gertaera ezabatu duzu {calendar} egutegitik ", "{actor} updated event {event} in calendar {calendar}" : "{actor}-(r)ek {event} gertaera eguneratu du {calendar} egutegian", "You updated event {event} in calendar {calendar}" : "{event} gertaera eguneratu duzu {calendar} egutegian ", + "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{actor}-(e)k {event} gertaera {sourceCalendar} egutegitik {targetCalendar} egutegira mugitu duzu", + "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{event} gertaera {sourceCalendar} egutegitik {targetCalendar} egutegira mugitu duzu", "{actor} restored event {event} of calendar {calendar}" : "{actor}-(e)k berrezarri du {calendar} egutegiko {event} gertaera ", "You restored event {event} of calendar {calendar}" : "Berrezarri duzu {calendar} egutegiko {event} gertaera ", "Busy" : "Lanpetua", - "{actor} created todo {todo} in list {calendar}" : "{actor}-ek {calendar} zerrendan {todo} zeregina sortu du.", - "You created todo {todo} in list {calendar}" : "{calendar} zerrendan {todo} ekintza sortu duzu.", - "{actor} deleted todo {todo} from list {calendar}" : "{actor}-rek {calendar} zerrendan {todo} zeregina borratu du.", - "You deleted todo {todo} from list {calendar}" : " {calendar} zerrendan {todo} zeregina borratu duzu.", - "{actor} updated todo {todo} in list {calendar}" : "{actor}-rek {calendar} zerrendan {todo} zeregina eguneratu du.", - "You updated todo {todo} in list {calendar}" : "{calendar} zerrendan {todo} zeregina eguneratu duzu.", - "{actor} solved todo {todo} in list {calendar}" : "{actor}-rek {calendar} zerrendan {todo} zeregina bukatu du.", - "You solved todo {todo} in list {calendar}" : " {calendar} zerrendan {todo} zeregina bukatu duzu.", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} erabiltzaileak {calendar} zerrendan {todo} zeregina berrireki du.", - "You reopened todo {todo} in list {calendar}" : "{calendar} egutegian {todo} zeregina berrireki duzu. ", + "{actor} created to-do {todo} in list {calendar}" : "{actor}-(e)k {calendar} zerrendan {todo} egitekoa sortu du", + "You created to-do {todo} in list {calendar}" : "{calendar} zerrendan {todo} egitekoa sortu duzu", + "{actor} deleted to-do {todo} from list {calendar}" : "{actor}-(e)k {calendar} zerrendan {todo} egitekoa ezabatu du", + "You deleted to-do {todo} from list {calendar}" : " {calendar} zerrendan {todo} egitekoa ezabatu duzu", + "{actor} updated to-do {todo} in list {calendar}" : "{actor}-(e)k {calendar} zerrendan {todo} egitekoa eguneratu du", + "You updated to-do {todo} in list {calendar}" : "{calendar} zerrendan {todo} egitekoa eguneratu duzu", + "{actor} solved to-do {todo} in list {calendar}" : "{actor}-(e)k {calendar} zerrendan {todo} egitekoa bukatu du.", + "You solved to-do {todo} in list {calendar}" : " {calendar} zerrendan {todo} egitekoa bukatu duzu", + "{actor} reopened to-do {todo} in list {calendar}" : "{actor}-(e)k {calendar} zerrendan {todo} egitekoa berrireki du", + "You reopened to-do {todo} in list {calendar}" : "{calendar} zerrendan {todo} egitekoa berrireki duzu", + "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor}-(e)k {todo} egitekoa {sourceCalendar} zerrendatik {targetCalendar} zerrendara mugitu du", + "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{todo} egitekoa {sourceCalendar} zerrendatik {targetCalendar} zerrendara mugitu duzu", "Calendar, contacts and tasks" : "Egutegia, kontaktuak eta atazak", "A <strong>calendar</strong> was modified" : "Egutegia aldatu da", "A calendar <strong>event</strong> was modified" : "Egutegiaren <strong>gertaera</strong> bat aldatu da", - "A calendar <strong>todo</strong> was modified" : "Egutegiaren zeregin bat aldatu da", + "A calendar <strong>to-do</strong> was modified" : "Egutegi baten <strong>eginbeharra</strong> aldatu da", "Contact birthdays" : "Kontaktuen urtebetetzeak", "Death of %s" : "%s(r)en heriotza", "Calendar:" : "Egutegia:", @@ -153,6 +157,7 @@ "Friday" : "Ostirala", "Saturday" : "Larunbata", "Sunday" : "Igandea", + "Automatically set user status to \"Do not disturb\" outside of availability to mute all notifications." : "Ezarri automatikoki erabiltzailearen egoera \"Ez molestatu\" moduan erabilgarritasunetik kanpo jakinarazpen guztiak isilarazteko.", "Save" : "Gorde", "Failed to load availability" : "Ezin izan da kargatu erabilgarritasuna", "Saved availability" : "Gordetako erabilgarritasuna", @@ -175,6 +180,18 @@ "Tentative" : "Behin behinekoa", "Number of guests" : "Gonbidatu kopurua", "Comment" : "Iruzkindu", - "Your attendance was updated successfully." : "Zure parte-hartzea ondo eguneratu da." + "Your attendance was updated successfully." : "Zure parte-hartzea ondo eguneratu da.", + "Todos" : "Egitekoak", + "{actor} created todo {todo} in list {calendar}" : "{actor}-ek {calendar} zerrendan {todo} zeregina sortu du.", + "You created todo {todo} in list {calendar}" : "{calendar} zerrendan {todo} ekintza sortu duzu.", + "{actor} deleted todo {todo} from list {calendar}" : "{actor}-rek {calendar} zerrendan {todo} zeregina borratu du.", + "You deleted todo {todo} from list {calendar}" : " {calendar} zerrendan {todo} zeregina borratu duzu.", + "{actor} updated todo {todo} in list {calendar}" : "{actor}-rek {calendar} zerrendan {todo} zeregina eguneratu du.", + "You updated todo {todo} in list {calendar}" : "{calendar} zerrendan {todo} zeregina eguneratu duzu.", + "{actor} solved todo {todo} in list {calendar}" : "{actor}-rek {calendar} zerrendan {todo} zeregina bukatu du.", + "You solved todo {todo} in list {calendar}" : " {calendar} zerrendan {todo} zeregina bukatu duzu.", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} erabiltzaileak {calendar} zerrendan {todo} zeregina berrireki du.", + "You reopened todo {todo} in list {calendar}" : "{calendar} egutegian {todo} zeregina berrireki duzu. ", + "A calendar <strong>todo</strong> was modified" : "Egutegiaren zeregin bat aldatu da" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/dav/l10n/fi.js b/apps/dav/l10n/fi.js index 07a8eb95b8d..ac1dc646a9b 100644 --- a/apps/dav/l10n/fi.js +++ b/apps/dav/l10n/fi.js @@ -2,7 +2,6 @@ OC.L10N.register( "dav", { "Calendar" : "Kalenteri", - "Todos" : "Tehtävät", "Personal" : "Henkilökohtainen", "{actor} created calendar {calendar}" : "{actor} loi kalenterin {calendar}", "You created calendar {calendar}" : "Loit kalenterin {calendar}", @@ -33,20 +32,9 @@ OC.L10N.register( "{actor} updated event {event} in calendar {calendar}" : "{actor} päivitti tapahtuman {event} kalenteriin {calendar}", "You updated event {event} in calendar {calendar}" : "Päivitit tapahtuman {event} kalenteriin {calendar}", "Busy" : "Varattu", - "{actor} created todo {todo} in list {calendar}" : "{actor} loi tehtävän {todo} listaan {calendar}", - "You created todo {todo} in list {calendar}" : "Loit tehtävän {todo} listaan {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} poisti tehtävän {todo} listasta {calendar}", - "You deleted todo {todo} from list {calendar}" : "Poistit tehtävän {todo} listasta {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} päivitti tehtävän {todo} listassa {calendar}", - "You updated todo {todo} in list {calendar}" : "Päivitit tehtävän {todo} listassa {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} suoritti tehtävän {todo} listasta {calendar}", - "You solved todo {todo} in list {calendar}" : "Suoritit tehtävän {todo} listasta {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} avasi uudelleen tehtävän {todo} listassa {calendar}", - "You reopened todo {todo} in list {calendar}" : "Avasit uudelleen tehtävän {todo} listassa {calendar}", "Calendar, contacts and tasks" : "Kalenteri, yhteystiedot ja tehtävät", "A <strong>calendar</strong> was modified" : "<strong>Kalenteria</strong> on muokattu", "A calendar <strong>event</strong> was modified" : "Kalenterin <strong>tapahtumaa</strong> on muokattu", - "A calendar <strong>todo</strong> was modified" : "Kalenterin <strong>tehtävää</strong> on muokattu", "Contact birthdays" : "Yhteystietojen syntymäpäivät", "Death of %s" : "%s kuolema", "Calendar:" : "Kalenteri:", @@ -100,6 +88,8 @@ OC.L10N.register( "File is not updatable: %1$s" : "Tiedosto ei ole päivitettävissä: %1$s", "_%n byte_::_%n bytes_" : ["%n tavu","%n tavua"], "Could not open file" : "Tiedoston avaaminen ei onnistunut", + "Encryption not ready: %1$s" : "Salaus ei ole valmis: %1$s", + "Failed to open file: %1$s" : "Tiedoston avaaminen epäonnistui: %1$s", "File not found: %1$s" : "Tiedostoa ei löydy: %1$s", "System is in maintenance mode." : "Järjestelmä on huoltotilassa", "Upgrade needed" : "Päivitys tarvitaan", @@ -126,6 +116,7 @@ OC.L10N.register( "Saturday" : "Lauantai", "Sunday" : "Sunnuntai", "Save" : "Tallenna", + "Failed to load availability" : "Saatavuuden lataaminen epäonnistui", "Calendar server" : "Kalenteripalvelin", "Send invitations to attendees" : "Lähetä kutsut osallistujille", "Automatically generate a birthday calendar" : "Luo syntymäpäiväkalenteri automaattisesti", @@ -140,6 +131,18 @@ OC.L10N.register( "Tentative" : "Alustava", "Number of guests" : "Vieraiden määrä", "Comment" : "Kommentti", - "Your attendance was updated successfully." : "Osallistumisesi päivitettiin onnistuneesti." + "Your attendance was updated successfully." : "Osallistumisesi päivitettiin onnistuneesti.", + "Todos" : "Tehtävät", + "{actor} created todo {todo} in list {calendar}" : "{actor} loi tehtävän {todo} listaan {calendar}", + "You created todo {todo} in list {calendar}" : "Loit tehtävän {todo} listaan {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} poisti tehtävän {todo} listasta {calendar}", + "You deleted todo {todo} from list {calendar}" : "Poistit tehtävän {todo} listasta {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} päivitti tehtävän {todo} listassa {calendar}", + "You updated todo {todo} in list {calendar}" : "Päivitit tehtävän {todo} listassa {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} suoritti tehtävän {todo} listasta {calendar}", + "You solved todo {todo} in list {calendar}" : "Suoritit tehtävän {todo} listasta {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} avasi uudelleen tehtävän {todo} listassa {calendar}", + "You reopened todo {todo} in list {calendar}" : "Avasit uudelleen tehtävän {todo} listassa {calendar}", + "A calendar <strong>todo</strong> was modified" : "Kalenterin <strong>tehtävää</strong> on muokattu" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/dav/l10n/fi.json b/apps/dav/l10n/fi.json index 5398895b76f..2f3691370ea 100644 --- a/apps/dav/l10n/fi.json +++ b/apps/dav/l10n/fi.json @@ -1,6 +1,5 @@ { "translations": { "Calendar" : "Kalenteri", - "Todos" : "Tehtävät", "Personal" : "Henkilökohtainen", "{actor} created calendar {calendar}" : "{actor} loi kalenterin {calendar}", "You created calendar {calendar}" : "Loit kalenterin {calendar}", @@ -31,20 +30,9 @@ "{actor} updated event {event} in calendar {calendar}" : "{actor} päivitti tapahtuman {event} kalenteriin {calendar}", "You updated event {event} in calendar {calendar}" : "Päivitit tapahtuman {event} kalenteriin {calendar}", "Busy" : "Varattu", - "{actor} created todo {todo} in list {calendar}" : "{actor} loi tehtävän {todo} listaan {calendar}", - "You created todo {todo} in list {calendar}" : "Loit tehtävän {todo} listaan {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} poisti tehtävän {todo} listasta {calendar}", - "You deleted todo {todo} from list {calendar}" : "Poistit tehtävän {todo} listasta {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} päivitti tehtävän {todo} listassa {calendar}", - "You updated todo {todo} in list {calendar}" : "Päivitit tehtävän {todo} listassa {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} suoritti tehtävän {todo} listasta {calendar}", - "You solved todo {todo} in list {calendar}" : "Suoritit tehtävän {todo} listasta {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} avasi uudelleen tehtävän {todo} listassa {calendar}", - "You reopened todo {todo} in list {calendar}" : "Avasit uudelleen tehtävän {todo} listassa {calendar}", "Calendar, contacts and tasks" : "Kalenteri, yhteystiedot ja tehtävät", "A <strong>calendar</strong> was modified" : "<strong>Kalenteria</strong> on muokattu", "A calendar <strong>event</strong> was modified" : "Kalenterin <strong>tapahtumaa</strong> on muokattu", - "A calendar <strong>todo</strong> was modified" : "Kalenterin <strong>tehtävää</strong> on muokattu", "Contact birthdays" : "Yhteystietojen syntymäpäivät", "Death of %s" : "%s kuolema", "Calendar:" : "Kalenteri:", @@ -98,6 +86,8 @@ "File is not updatable: %1$s" : "Tiedosto ei ole päivitettävissä: %1$s", "_%n byte_::_%n bytes_" : ["%n tavu","%n tavua"], "Could not open file" : "Tiedoston avaaminen ei onnistunut", + "Encryption not ready: %1$s" : "Salaus ei ole valmis: %1$s", + "Failed to open file: %1$s" : "Tiedoston avaaminen epäonnistui: %1$s", "File not found: %1$s" : "Tiedostoa ei löydy: %1$s", "System is in maintenance mode." : "Järjestelmä on huoltotilassa", "Upgrade needed" : "Päivitys tarvitaan", @@ -124,6 +114,7 @@ "Saturday" : "Lauantai", "Sunday" : "Sunnuntai", "Save" : "Tallenna", + "Failed to load availability" : "Saatavuuden lataaminen epäonnistui", "Calendar server" : "Kalenteripalvelin", "Send invitations to attendees" : "Lähetä kutsut osallistujille", "Automatically generate a birthday calendar" : "Luo syntymäpäiväkalenteri automaattisesti", @@ -138,6 +129,18 @@ "Tentative" : "Alustava", "Number of guests" : "Vieraiden määrä", "Comment" : "Kommentti", - "Your attendance was updated successfully." : "Osallistumisesi päivitettiin onnistuneesti." + "Your attendance was updated successfully." : "Osallistumisesi päivitettiin onnistuneesti.", + "Todos" : "Tehtävät", + "{actor} created todo {todo} in list {calendar}" : "{actor} loi tehtävän {todo} listaan {calendar}", + "You created todo {todo} in list {calendar}" : "Loit tehtävän {todo} listaan {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} poisti tehtävän {todo} listasta {calendar}", + "You deleted todo {todo} from list {calendar}" : "Poistit tehtävän {todo} listasta {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} päivitti tehtävän {todo} listassa {calendar}", + "You updated todo {todo} in list {calendar}" : "Päivitit tehtävän {todo} listassa {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} suoritti tehtävän {todo} listasta {calendar}", + "You solved todo {todo} in list {calendar}" : "Suoritit tehtävän {todo} listasta {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} avasi uudelleen tehtävän {todo} listassa {calendar}", + "You reopened todo {todo} in list {calendar}" : "Avasit uudelleen tehtävän {todo} listassa {calendar}", + "A calendar <strong>todo</strong> was modified" : "Kalenterin <strong>tehtävää</strong> on muokattu" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/dav/l10n/fr.js b/apps/dav/l10n/fr.js index 3d9caf69ef0..95b8395b659 100644 --- a/apps/dav/l10n/fr.js +++ b/apps/dav/l10n/fr.js @@ -2,7 +2,6 @@ OC.L10N.register( "dav", { "Calendar" : "Agenda", - "Todos" : "Tâches", "Personal" : "Personnel", "{actor} created calendar {calendar}" : "{actor} a créé l'agenda {calendar}", "You created calendar {calendar}" : "Vous avez créé l'agenda {calendar}", @@ -35,20 +34,9 @@ OC.L10N.register( "{actor} restored event {event} of calendar {calendar}" : "{actor} a restauré l'événement {event} dans l'agenda {calendar}", "You restored event {event} of calendar {calendar}" : "Vous avez restauré l'événement {event} dans l'agenda {calendar}", "Busy" : "Occupé", - "{actor} created todo {todo} in list {calendar}" : "{actor} a créé la tâche {todo} dans la liste {calendar}", - "You created todo {todo} in list {calendar}" : "Vous avez créé la tâche {todo} dans la liste {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} a supprimé la tâche {todo} de la liste {calendar}", - "You deleted todo {todo} from list {calendar}" : "Vous avez supprimé la tâche {todo} de la liste {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} a mis à jour la tâche {todo} dans la liste {calendar}", - "You updated todo {todo} in list {calendar}" : "Vous avez mis à jour la tâche {todo} dans la liste {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} a terminé la tâche {todo} de la liste {calendar}", - "You solved todo {todo} in list {calendar}" : "Vous avez terminé la tâche {todo} de la liste {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} a réouvert la tâche {todo} dans la liste {calendar}", - "You reopened todo {todo} in list {calendar}" : "Vous avez réouvert la tâche {todo} dans la liste {calendar}", "Calendar, contacts and tasks" : "Agenda, contacts et tâches", "A <strong>calendar</strong> was modified" : "Un <strong>agenda</strong> a été modifié", "A calendar <strong>event</strong> was modified" : "Un <strong>événement</strong> de l'agenda a été modifié", - "A calendar <strong>todo</strong> was modified" : "Une <strong>liste de tâches</strong> de l'agenda a été modifiée", "Contact birthdays" : "Anniversaires des contacts", "Death of %s" : "Mort de %s", "Calendar:" : "Agenda:", @@ -173,6 +161,18 @@ OC.L10N.register( "Tentative" : "Provisoire", "Number of guests" : "Nombre d'invités", "Comment" : "Commentaire", - "Your attendance was updated successfully." : "Votre présence a été mise à jour avec succès." + "Your attendance was updated successfully." : "Votre présence a été mise à jour avec succès.", + "Todos" : "Tâches", + "{actor} created todo {todo} in list {calendar}" : "{actor} a créé la tâche {todo} dans la liste {calendar}", + "You created todo {todo} in list {calendar}" : "Vous avez créé la tâche {todo} dans la liste {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} a supprimé la tâche {todo} de la liste {calendar}", + "You deleted todo {todo} from list {calendar}" : "Vous avez supprimé la tâche {todo} de la liste {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} a mis à jour la tâche {todo} dans la liste {calendar}", + "You updated todo {todo} in list {calendar}" : "Vous avez mis à jour la tâche {todo} dans la liste {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} a terminé la tâche {todo} de la liste {calendar}", + "You solved todo {todo} in list {calendar}" : "Vous avez terminé la tâche {todo} de la liste {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} a réouvert la tâche {todo} dans la liste {calendar}", + "You reopened todo {todo} in list {calendar}" : "Vous avez réouvert la tâche {todo} dans la liste {calendar}", + "A calendar <strong>todo</strong> was modified" : "Une <strong>liste de tâches</strong> de l'agenda a été modifiée" }, "nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/apps/dav/l10n/fr.json b/apps/dav/l10n/fr.json index 7134ea75384..b52b5d11d3e 100644 --- a/apps/dav/l10n/fr.json +++ b/apps/dav/l10n/fr.json @@ -1,6 +1,5 @@ { "translations": { "Calendar" : "Agenda", - "Todos" : "Tâches", "Personal" : "Personnel", "{actor} created calendar {calendar}" : "{actor} a créé l'agenda {calendar}", "You created calendar {calendar}" : "Vous avez créé l'agenda {calendar}", @@ -33,20 +32,9 @@ "{actor} restored event {event} of calendar {calendar}" : "{actor} a restauré l'événement {event} dans l'agenda {calendar}", "You restored event {event} of calendar {calendar}" : "Vous avez restauré l'événement {event} dans l'agenda {calendar}", "Busy" : "Occupé", - "{actor} created todo {todo} in list {calendar}" : "{actor} a créé la tâche {todo} dans la liste {calendar}", - "You created todo {todo} in list {calendar}" : "Vous avez créé la tâche {todo} dans la liste {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} a supprimé la tâche {todo} de la liste {calendar}", - "You deleted todo {todo} from list {calendar}" : "Vous avez supprimé la tâche {todo} de la liste {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} a mis à jour la tâche {todo} dans la liste {calendar}", - "You updated todo {todo} in list {calendar}" : "Vous avez mis à jour la tâche {todo} dans la liste {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} a terminé la tâche {todo} de la liste {calendar}", - "You solved todo {todo} in list {calendar}" : "Vous avez terminé la tâche {todo} de la liste {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} a réouvert la tâche {todo} dans la liste {calendar}", - "You reopened todo {todo} in list {calendar}" : "Vous avez réouvert la tâche {todo} dans la liste {calendar}", "Calendar, contacts and tasks" : "Agenda, contacts et tâches", "A <strong>calendar</strong> was modified" : "Un <strong>agenda</strong> a été modifié", "A calendar <strong>event</strong> was modified" : "Un <strong>événement</strong> de l'agenda a été modifié", - "A calendar <strong>todo</strong> was modified" : "Une <strong>liste de tâches</strong> de l'agenda a été modifiée", "Contact birthdays" : "Anniversaires des contacts", "Death of %s" : "Mort de %s", "Calendar:" : "Agenda:", @@ -171,6 +159,18 @@ "Tentative" : "Provisoire", "Number of guests" : "Nombre d'invités", "Comment" : "Commentaire", - "Your attendance was updated successfully." : "Votre présence a été mise à jour avec succès." + "Your attendance was updated successfully." : "Votre présence a été mise à jour avec succès.", + "Todos" : "Tâches", + "{actor} created todo {todo} in list {calendar}" : "{actor} a créé la tâche {todo} dans la liste {calendar}", + "You created todo {todo} in list {calendar}" : "Vous avez créé la tâche {todo} dans la liste {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} a supprimé la tâche {todo} de la liste {calendar}", + "You deleted todo {todo} from list {calendar}" : "Vous avez supprimé la tâche {todo} de la liste {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} a mis à jour la tâche {todo} dans la liste {calendar}", + "You updated todo {todo} in list {calendar}" : "Vous avez mis à jour la tâche {todo} dans la liste {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} a terminé la tâche {todo} de la liste {calendar}", + "You solved todo {todo} in list {calendar}" : "Vous avez terminé la tâche {todo} de la liste {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} a réouvert la tâche {todo} dans la liste {calendar}", + "You reopened todo {todo} in list {calendar}" : "Vous avez réouvert la tâche {todo} dans la liste {calendar}", + "A calendar <strong>todo</strong> was modified" : "Une <strong>liste de tâches</strong> de l'agenda a été modifiée" },"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/apps/dav/l10n/gl.js b/apps/dav/l10n/gl.js index cdc03edca59..6159f311993 100644 --- a/apps/dav/l10n/gl.js +++ b/apps/dav/l10n/gl.js @@ -2,7 +2,6 @@ OC.L10N.register( "dav", { "Calendar" : "Calendario", - "Todos" : "Asuntos pendentes", "Personal" : "Persoal", "{actor} created calendar {calendar}" : "{actor} creou o calendario {calendar}", "You created calendar {calendar}" : "Vostede creou o calendario {calendar}", @@ -31,19 +30,8 @@ OC.L10N.register( "{actor} updated event {event} in calendar {calendar}" : "{actor} actualizou o evento {event} no calendario {calendar}", "You updated event {event} in calendar {calendar}" : "Vostede actualizou o evento {event} no calendario {calendar}", "Busy" : "Ocupado", - "{actor} created todo {todo} in list {calendar}" : "{actor} creou os asuntos pendentes {todo} na lista {calendar}", - "You created todo {todo} in list {calendar}" : "Vostede creou os asuntos pendentes {todo} na lista {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} eliminou os asuntos pendentes {todo} da lista {calendar}", - "You deleted todo {todo} from list {calendar}" : "Vostede eliminou os asuntos pendentes {todo} da lista {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} actualizou os asuntos pendentes {todo} na lista {calendar}", - "You updated todo {todo} in list {calendar}" : "Vostede actualizou os asuntos pendentes {todo} na lista {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} resolveu os asuntos pendentes {todo} na lista {calendar}", - "You solved todo {todo} in list {calendar}" : "Vostede resolveu os asuntos pendentes {todo} na lista {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} volveu abrir os asuntos pendentes {todo} na lista {calendar}", - "You reopened todo {todo} in list {calendar}" : "Vostede volveu abrir os asuntos pendentes {todo} na lista {calendar}", "A <strong>calendar</strong> was modified" : "Foi modificado un <strong>calendario</strong>", "A calendar <strong>event</strong> was modified" : "Foi modificado un <strong>evento</strong> do calendario", - "A calendar <strong>todo</strong> was modified" : "Foi modificado un <strong>asunto pendente</strong> do calendario", "Contact birthdays" : "Aniversario do contacto", "Death of %s" : "Falecemento de %s", "Calendar:" : "Calendario:", @@ -113,6 +101,18 @@ OC.L10N.register( "Are you accepting the invitation?" : "Acepta vostede o convite?", "Tentative" : "Tentativa", "Comment" : "Comentario", - "Your attendance was updated successfully." : "A súa asistencia foi actualizada satisfactoriamente." + "Your attendance was updated successfully." : "A súa asistencia foi actualizada satisfactoriamente.", + "Todos" : "Asuntos pendentes", + "{actor} created todo {todo} in list {calendar}" : "{actor} creou os asuntos pendentes {todo} na lista {calendar}", + "You created todo {todo} in list {calendar}" : "Vostede creou os asuntos pendentes {todo} na lista {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} eliminou os asuntos pendentes {todo} da lista {calendar}", + "You deleted todo {todo} from list {calendar}" : "Vostede eliminou os asuntos pendentes {todo} da lista {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} actualizou os asuntos pendentes {todo} na lista {calendar}", + "You updated todo {todo} in list {calendar}" : "Vostede actualizou os asuntos pendentes {todo} na lista {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} resolveu os asuntos pendentes {todo} na lista {calendar}", + "You solved todo {todo} in list {calendar}" : "Vostede resolveu os asuntos pendentes {todo} na lista {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} volveu abrir os asuntos pendentes {todo} na lista {calendar}", + "You reopened todo {todo} in list {calendar}" : "Vostede volveu abrir os asuntos pendentes {todo} na lista {calendar}", + "A calendar <strong>todo</strong> was modified" : "Foi modificado un <strong>asunto pendente</strong> do calendario" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/dav/l10n/gl.json b/apps/dav/l10n/gl.json index f00a9f4e7ae..bb11ce4a5d6 100644 --- a/apps/dav/l10n/gl.json +++ b/apps/dav/l10n/gl.json @@ -1,6 +1,5 @@ { "translations": { "Calendar" : "Calendario", - "Todos" : "Asuntos pendentes", "Personal" : "Persoal", "{actor} created calendar {calendar}" : "{actor} creou o calendario {calendar}", "You created calendar {calendar}" : "Vostede creou o calendario {calendar}", @@ -29,19 +28,8 @@ "{actor} updated event {event} in calendar {calendar}" : "{actor} actualizou o evento {event} no calendario {calendar}", "You updated event {event} in calendar {calendar}" : "Vostede actualizou o evento {event} no calendario {calendar}", "Busy" : "Ocupado", - "{actor} created todo {todo} in list {calendar}" : "{actor} creou os asuntos pendentes {todo} na lista {calendar}", - "You created todo {todo} in list {calendar}" : "Vostede creou os asuntos pendentes {todo} na lista {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} eliminou os asuntos pendentes {todo} da lista {calendar}", - "You deleted todo {todo} from list {calendar}" : "Vostede eliminou os asuntos pendentes {todo} da lista {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} actualizou os asuntos pendentes {todo} na lista {calendar}", - "You updated todo {todo} in list {calendar}" : "Vostede actualizou os asuntos pendentes {todo} na lista {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} resolveu os asuntos pendentes {todo} na lista {calendar}", - "You solved todo {todo} in list {calendar}" : "Vostede resolveu os asuntos pendentes {todo} na lista {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} volveu abrir os asuntos pendentes {todo} na lista {calendar}", - "You reopened todo {todo} in list {calendar}" : "Vostede volveu abrir os asuntos pendentes {todo} na lista {calendar}", "A <strong>calendar</strong> was modified" : "Foi modificado un <strong>calendario</strong>", "A calendar <strong>event</strong> was modified" : "Foi modificado un <strong>evento</strong> do calendario", - "A calendar <strong>todo</strong> was modified" : "Foi modificado un <strong>asunto pendente</strong> do calendario", "Contact birthdays" : "Aniversario do contacto", "Death of %s" : "Falecemento de %s", "Calendar:" : "Calendario:", @@ -111,6 +99,18 @@ "Are you accepting the invitation?" : "Acepta vostede o convite?", "Tentative" : "Tentativa", "Comment" : "Comentario", - "Your attendance was updated successfully." : "A súa asistencia foi actualizada satisfactoriamente." + "Your attendance was updated successfully." : "A súa asistencia foi actualizada satisfactoriamente.", + "Todos" : "Asuntos pendentes", + "{actor} created todo {todo} in list {calendar}" : "{actor} creou os asuntos pendentes {todo} na lista {calendar}", + "You created todo {todo} in list {calendar}" : "Vostede creou os asuntos pendentes {todo} na lista {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} eliminou os asuntos pendentes {todo} da lista {calendar}", + "You deleted todo {todo} from list {calendar}" : "Vostede eliminou os asuntos pendentes {todo} da lista {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} actualizou os asuntos pendentes {todo} na lista {calendar}", + "You updated todo {todo} in list {calendar}" : "Vostede actualizou os asuntos pendentes {todo} na lista {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} resolveu os asuntos pendentes {todo} na lista {calendar}", + "You solved todo {todo} in list {calendar}" : "Vostede resolveu os asuntos pendentes {todo} na lista {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} volveu abrir os asuntos pendentes {todo} na lista {calendar}", + "You reopened todo {todo} in list {calendar}" : "Vostede volveu abrir os asuntos pendentes {todo} na lista {calendar}", + "A calendar <strong>todo</strong> was modified" : "Foi modificado un <strong>asunto pendente</strong> do calendario" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/dav/l10n/he.js b/apps/dav/l10n/he.js index 1e15402036f..00b31765b85 100644 --- a/apps/dav/l10n/he.js +++ b/apps/dav/l10n/he.js @@ -2,7 +2,6 @@ OC.L10N.register( "dav", { "Calendar" : "יומן", - "Todos" : "משימות מטלות", "Personal" : "אישי", "{actor} created calendar {calendar}" : "היומן {calendar} נוצר על ידי {actor}", "You created calendar {calendar}" : "מחקת את היומן {calendar}", @@ -31,19 +30,8 @@ OC.L10N.register( "{actor} updated event {event} in calendar {calendar}" : "האירוע {event} עודכן בלוח השנה {calendar} על ידי {actor}", "You updated event {event} in calendar {calendar}" : "עדכנת את האירוע {event} בלוח השנה {calendar}", "Busy" : "עסוק", - "{actor} created todo {todo} in list {calendar}" : "המשימה לביצוע {todo} ברשימה {calendar} נוצרה על ידי {actor}", - "You created todo {todo} in list {calendar}" : "יצרת את המשימה לביצוע {todo} ברשימה {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "המשימה לביצוע {todo} מהרשימה {calendar} נמחקה על ידי {actor}", - "You deleted todo {todo} from list {calendar}" : "מחקת את המשימה לביצוע {todo} מהרשימה {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "המשימה לביצוע {todo} ברשימה {calendar} עודכנה על ידי {actor}", - "You updated todo {todo} in list {calendar}" : "עדכנת את המשימה לביצוע {todo} ברשימה {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "המשימה לביצוע {todo} ברשימה {calendar} נפתרה על ידי {actor}", - "You solved todo {todo} in list {calendar}" : "פתרת משימה לביצוע {todo} ברשימה {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "המשימה לביצוע {todo} ברשימה {calendar} נפתחה מחדש על ידי {actor}", - "You reopened todo {todo} in list {calendar}" : "פתחת מחדש את המשימה לביצוע {todo} ברשימה {calendar}", "A <strong>calendar</strong> was modified" : " <strong>יומן</strong> נערך", "A calendar <strong>event</strong> was modified" : "<strong>אירוע</strong> ביומן נערך", - "A calendar <strong>todo</strong> was modified" : "נערכה <strong>מטלה</strong> בלוח שנה", "Contact birthdays" : "ימי הולדת של אנשי קשר", "Death of %s" : "הפטירה של %s", "Calendar:" : "לוח שנה:", @@ -111,6 +99,18 @@ OC.L10N.register( "Are you accepting the invitation?" : "האם להיענות להזמנה?", "Tentative" : "טנטטיבית", "Comment" : "הערה", - "Your attendance was updated successfully." : "ההשתתפות שלך עודכנה בהצלחה." + "Your attendance was updated successfully." : "ההשתתפות שלך עודכנה בהצלחה.", + "Todos" : "משימות מטלות", + "{actor} created todo {todo} in list {calendar}" : "המשימה לביצוע {todo} ברשימה {calendar} נוצרה על ידי {actor}", + "You created todo {todo} in list {calendar}" : "יצרת את המשימה לביצוע {todo} ברשימה {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "המשימה לביצוע {todo} מהרשימה {calendar} נמחקה על ידי {actor}", + "You deleted todo {todo} from list {calendar}" : "מחקת את המשימה לביצוע {todo} מהרשימה {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "המשימה לביצוע {todo} ברשימה {calendar} עודכנה על ידי {actor}", + "You updated todo {todo} in list {calendar}" : "עדכנת את המשימה לביצוע {todo} ברשימה {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "המשימה לביצוע {todo} ברשימה {calendar} נפתרה על ידי {actor}", + "You solved todo {todo} in list {calendar}" : "פתרת משימה לביצוע {todo} ברשימה {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "המשימה לביצוע {todo} ברשימה {calendar} נפתחה מחדש על ידי {actor}", + "You reopened todo {todo} in list {calendar}" : "פתחת מחדש את המשימה לביצוע {todo} ברשימה {calendar}", + "A calendar <strong>todo</strong> was modified" : "נערכה <strong>מטלה</strong> בלוח שנה" }, "nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % 1 == 0) ? 1: (n % 10 == 0 && n % 1 == 0 && n > 10) ? 2 : 3;"); diff --git a/apps/dav/l10n/he.json b/apps/dav/l10n/he.json index f344047fa78..46bd17eac40 100644 --- a/apps/dav/l10n/he.json +++ b/apps/dav/l10n/he.json @@ -1,6 +1,5 @@ { "translations": { "Calendar" : "יומן", - "Todos" : "משימות מטלות", "Personal" : "אישי", "{actor} created calendar {calendar}" : "היומן {calendar} נוצר על ידי {actor}", "You created calendar {calendar}" : "מחקת את היומן {calendar}", @@ -29,19 +28,8 @@ "{actor} updated event {event} in calendar {calendar}" : "האירוע {event} עודכן בלוח השנה {calendar} על ידי {actor}", "You updated event {event} in calendar {calendar}" : "עדכנת את האירוע {event} בלוח השנה {calendar}", "Busy" : "עסוק", - "{actor} created todo {todo} in list {calendar}" : "המשימה לביצוע {todo} ברשימה {calendar} נוצרה על ידי {actor}", - "You created todo {todo} in list {calendar}" : "יצרת את המשימה לביצוע {todo} ברשימה {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "המשימה לביצוע {todo} מהרשימה {calendar} נמחקה על ידי {actor}", - "You deleted todo {todo} from list {calendar}" : "מחקת את המשימה לביצוע {todo} מהרשימה {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "המשימה לביצוע {todo} ברשימה {calendar} עודכנה על ידי {actor}", - "You updated todo {todo} in list {calendar}" : "עדכנת את המשימה לביצוע {todo} ברשימה {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "המשימה לביצוע {todo} ברשימה {calendar} נפתרה על ידי {actor}", - "You solved todo {todo} in list {calendar}" : "פתרת משימה לביצוע {todo} ברשימה {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "המשימה לביצוע {todo} ברשימה {calendar} נפתחה מחדש על ידי {actor}", - "You reopened todo {todo} in list {calendar}" : "פתחת מחדש את המשימה לביצוע {todo} ברשימה {calendar}", "A <strong>calendar</strong> was modified" : " <strong>יומן</strong> נערך", "A calendar <strong>event</strong> was modified" : "<strong>אירוע</strong> ביומן נערך", - "A calendar <strong>todo</strong> was modified" : "נערכה <strong>מטלה</strong> בלוח שנה", "Contact birthdays" : "ימי הולדת של אנשי קשר", "Death of %s" : "הפטירה של %s", "Calendar:" : "לוח שנה:", @@ -109,6 +97,18 @@ "Are you accepting the invitation?" : "האם להיענות להזמנה?", "Tentative" : "טנטטיבית", "Comment" : "הערה", - "Your attendance was updated successfully." : "ההשתתפות שלך עודכנה בהצלחה." + "Your attendance was updated successfully." : "ההשתתפות שלך עודכנה בהצלחה.", + "Todos" : "משימות מטלות", + "{actor} created todo {todo} in list {calendar}" : "המשימה לביצוע {todo} ברשימה {calendar} נוצרה על ידי {actor}", + "You created todo {todo} in list {calendar}" : "יצרת את המשימה לביצוע {todo} ברשימה {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "המשימה לביצוע {todo} מהרשימה {calendar} נמחקה על ידי {actor}", + "You deleted todo {todo} from list {calendar}" : "מחקת את המשימה לביצוע {todo} מהרשימה {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "המשימה לביצוע {todo} ברשימה {calendar} עודכנה על ידי {actor}", + "You updated todo {todo} in list {calendar}" : "עדכנת את המשימה לביצוע {todo} ברשימה {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "המשימה לביצוע {todo} ברשימה {calendar} נפתרה על ידי {actor}", + "You solved todo {todo} in list {calendar}" : "פתרת משימה לביצוע {todo} ברשימה {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "המשימה לביצוע {todo} ברשימה {calendar} נפתחה מחדש על ידי {actor}", + "You reopened todo {todo} in list {calendar}" : "פתחת מחדש את המשימה לביצוע {todo} ברשימה {calendar}", + "A calendar <strong>todo</strong> was modified" : "נערכה <strong>מטלה</strong> בלוח שנה" },"pluralForm" :"nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % 1 == 0) ? 1: (n % 10 == 0 && n % 1 == 0 && n > 10) ? 2 : 3;" }
\ No newline at end of file diff --git a/apps/dav/l10n/hr.js b/apps/dav/l10n/hr.js index fcb376918ff..8a47e10ae50 100644 --- a/apps/dav/l10n/hr.js +++ b/apps/dav/l10n/hr.js @@ -2,7 +2,6 @@ OC.L10N.register( "dav", { "Calendar" : "Kalendar", - "Todos" : "Zadaci", "Personal" : "Osobno", "{actor} created calendar {calendar}" : "{actor} je stvorio kalendar {calendar}", "You created calendar {calendar}" : "Stvorili ste kalendar {calendar}", @@ -35,20 +34,9 @@ OC.L10N.register( "{actor} restored event {event} of calendar {calendar}" : "{actor} je vratio događaj {event} kalendara {calendar}", "You restored event {event} of calendar {calendar}" : "Vratili ste događaj {event} kalendara {calendar}", "Busy" : "Zauzeto", - "{actor} created todo {todo} in list {calendar}" : "{actor} je stvorio zadatak {todo} u popisu {calendar}", - "You created todo {todo} in list {calendar}" : "Stvorili ste zadatak {todo} u popisu {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} je izbrisao zadatak {todo} s popisa {calendar}", - "You deleted todo {todo} from list {calendar}" : "Izbrisali ste zadatak {todo} s popisa {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} je ažurirao zadatak {todo} u popisu {calendar}", - "You updated todo {todo} in list {calendar}" : "Ažurirali ste zadatak {todo} u popisu {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} je izvršio zadatak {todo} u popisu {calendar}", - "You solved todo {todo} in list {calendar}" : "Izvršili ste zadatak {todo} u popisu {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} je ponovno otvorio zadatak {todo} u popisu {calendar}", - "You reopened todo {todo} in list {calendar}" : "Ponovno ste otvorili zadatak {todo} u popisu {calendar}", "Calendar, contacts and tasks" : "Kalendar, kontakti i zadaci", "A <strong>calendar</strong> was modified" : "Izmijenjen je <strong>kalendar</strong>", "A calendar <strong>event</strong> was modified" : "Izmijenjen je <strong>događaj</strong> u kalendaru", - "A calendar <strong>todo</strong> was modified" : "Izmijenjen je <strong>zadatak</strong> u kalendaru", "Contact birthdays" : "Rođendani kontakata", "Death of %s" : "Smrt %s", "Calendar:" : "Kalendar:", @@ -151,6 +139,18 @@ OC.L10N.register( "Tentative" : "Uvjetno", "Number of guests" : "Broj gostiju", "Comment" : "Komentar", - "Your attendance was updated successfully." : "Vaša je prisutnost uspješno ažurirana." + "Your attendance was updated successfully." : "Vaša je prisutnost uspješno ažurirana.", + "Todos" : "Zadaci", + "{actor} created todo {todo} in list {calendar}" : "{actor} je stvorio zadatak {todo} u popisu {calendar}", + "You created todo {todo} in list {calendar}" : "Stvorili ste zadatak {todo} u popisu {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} je izbrisao zadatak {todo} s popisa {calendar}", + "You deleted todo {todo} from list {calendar}" : "Izbrisali ste zadatak {todo} s popisa {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} je ažurirao zadatak {todo} u popisu {calendar}", + "You updated todo {todo} in list {calendar}" : "Ažurirali ste zadatak {todo} u popisu {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} je izvršio zadatak {todo} u popisu {calendar}", + "You solved todo {todo} in list {calendar}" : "Izvršili ste zadatak {todo} u popisu {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} je ponovno otvorio zadatak {todo} u popisu {calendar}", + "You reopened todo {todo} in list {calendar}" : "Ponovno ste otvorili zadatak {todo} u popisu {calendar}", + "A calendar <strong>todo</strong> was modified" : "Izmijenjen je <strong>zadatak</strong> u kalendaru" }, "nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;"); diff --git a/apps/dav/l10n/hr.json b/apps/dav/l10n/hr.json index 0956dcb6afb..51da26b10bc 100644 --- a/apps/dav/l10n/hr.json +++ b/apps/dav/l10n/hr.json @@ -1,6 +1,5 @@ { "translations": { "Calendar" : "Kalendar", - "Todos" : "Zadaci", "Personal" : "Osobno", "{actor} created calendar {calendar}" : "{actor} je stvorio kalendar {calendar}", "You created calendar {calendar}" : "Stvorili ste kalendar {calendar}", @@ -33,20 +32,9 @@ "{actor} restored event {event} of calendar {calendar}" : "{actor} je vratio događaj {event} kalendara {calendar}", "You restored event {event} of calendar {calendar}" : "Vratili ste događaj {event} kalendara {calendar}", "Busy" : "Zauzeto", - "{actor} created todo {todo} in list {calendar}" : "{actor} je stvorio zadatak {todo} u popisu {calendar}", - "You created todo {todo} in list {calendar}" : "Stvorili ste zadatak {todo} u popisu {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} je izbrisao zadatak {todo} s popisa {calendar}", - "You deleted todo {todo} from list {calendar}" : "Izbrisali ste zadatak {todo} s popisa {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} je ažurirao zadatak {todo} u popisu {calendar}", - "You updated todo {todo} in list {calendar}" : "Ažurirali ste zadatak {todo} u popisu {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} je izvršio zadatak {todo} u popisu {calendar}", - "You solved todo {todo} in list {calendar}" : "Izvršili ste zadatak {todo} u popisu {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} je ponovno otvorio zadatak {todo} u popisu {calendar}", - "You reopened todo {todo} in list {calendar}" : "Ponovno ste otvorili zadatak {todo} u popisu {calendar}", "Calendar, contacts and tasks" : "Kalendar, kontakti i zadaci", "A <strong>calendar</strong> was modified" : "Izmijenjen je <strong>kalendar</strong>", "A calendar <strong>event</strong> was modified" : "Izmijenjen je <strong>događaj</strong> u kalendaru", - "A calendar <strong>todo</strong> was modified" : "Izmijenjen je <strong>zadatak</strong> u kalendaru", "Contact birthdays" : "Rođendani kontakata", "Death of %s" : "Smrt %s", "Calendar:" : "Kalendar:", @@ -149,6 +137,18 @@ "Tentative" : "Uvjetno", "Number of guests" : "Broj gostiju", "Comment" : "Komentar", - "Your attendance was updated successfully." : "Vaša je prisutnost uspješno ažurirana." + "Your attendance was updated successfully." : "Vaša je prisutnost uspješno ažurirana.", + "Todos" : "Zadaci", + "{actor} created todo {todo} in list {calendar}" : "{actor} je stvorio zadatak {todo} u popisu {calendar}", + "You created todo {todo} in list {calendar}" : "Stvorili ste zadatak {todo} u popisu {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} je izbrisao zadatak {todo} s popisa {calendar}", + "You deleted todo {todo} from list {calendar}" : "Izbrisali ste zadatak {todo} s popisa {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} je ažurirao zadatak {todo} u popisu {calendar}", + "You updated todo {todo} in list {calendar}" : "Ažurirali ste zadatak {todo} u popisu {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} je izvršio zadatak {todo} u popisu {calendar}", + "You solved todo {todo} in list {calendar}" : "Izvršili ste zadatak {todo} u popisu {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} je ponovno otvorio zadatak {todo} u popisu {calendar}", + "You reopened todo {todo} in list {calendar}" : "Ponovno ste otvorili zadatak {todo} u popisu {calendar}", + "A calendar <strong>todo</strong> was modified" : "Izmijenjen je <strong>zadatak</strong> u kalendaru" },"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/apps/dav/l10n/hu.js b/apps/dav/l10n/hu.js index 6ef5eeebe67..df447038dd8 100644 --- a/apps/dav/l10n/hu.js +++ b/apps/dav/l10n/hu.js @@ -2,7 +2,7 @@ OC.L10N.register( "dav", { "Calendar" : "Naptár", - "Todos" : "Teendők", + "To-dos" : "Teendők", "Personal" : "Személyes", "{actor} created calendar {calendar}" : "{actor} létrehozta a naptárt: {calendar}", "You created calendar {calendar}" : "Létrehozta a naptárt: {calendar}", @@ -32,23 +32,27 @@ OC.L10N.register( "You deleted event {event} from calendar {calendar}" : "Törölte a(z) {event} eseményt a következő naptárból: {calendar}", "{actor} updated event {event} in calendar {calendar}" : "{actor} frissítette a(z) {event} eseményt a következő naptárban: {calendar}", "You updated event {event} in calendar {calendar}" : "Frissítette a(z) {event} eseményt a következő naptárban: {calendar}", + "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{actor} áthelyezte a(z) {event} eseményt a(z) {sourceCalendar} naptárból a(z) {targetCalendar} naptárba", + "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "Áthelyezte a(z) {event} eseményt a(z) {sourceCalendar} naptárból a(z) {targetCalendar} naptárba", "{actor} restored event {event} of calendar {calendar}" : "{actor} helyreállította a(z) {calendar} naptár következő eseményét: {event}", "You restored event {event} of calendar {calendar}" : "Helyreállította a(z) {calendar} naptár következő eseményét: {event}", "Busy" : "Foglalt", - "{actor} created todo {todo} in list {calendar}" : "{actor} létrehozta a(z) {todo} teendőt a következő listában: {calendar}", - "You created todo {todo} in list {calendar}" : "Létrehozta a(z) {todo} teendőt a következő listában: {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} törölte a(z) {todo} teendőt a következő listából: {calendar}", - "You deleted todo {todo} from list {calendar}" : "Törölte a(z) {todo} teendőt a következő listából: {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} frissítette a(z) {todo} teendőt a következő listában: {calendar}", - "You updated todo {todo} in list {calendar}" : "Frissítette a(z) {todo} teendőt a következő listában: {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} elintézte a(z) {todo} teendőt a következő listában: {calendar}", - "You solved todo {todo} in list {calendar}" : "Elintézte a(z) {todo} teendőt a következő listában: {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} újranyitotta a(z) {todo} teendőt a következő listában: {calendar}", - "You reopened todo {todo} in list {calendar}" : "Újranyitotta a(z) {todo} teendőt a következő listában: {calendar}", + "{actor} created to-do {todo} in list {calendar}" : "{actor} létrehozta a(z) {todo} teendőt a következő listában: {calendar}", + "You created to-do {todo} in list {calendar}" : "Létrehozta a(z) {todo} teendőt a következő listában: {calendar}", + "{actor} deleted to-do {todo} from list {calendar}" : "{actor} törölte a(z) {todo} teendőt a következő listából: {calendar}", + "You deleted to-do {todo} from list {calendar}" : "Törölte a(z) {todo} teendőt a következő listából: {calendar}", + "{actor} updated to-do {todo} in list {calendar}" : "{actor} frissítette a(z) {todo} teendőt a következő listában: {calendar}", + "You updated to-do {todo} in list {calendar}" : "Frissítette a(z) {todo} teendőt a következő listában: {calendar}", + "{actor} solved to-do {todo} in list {calendar}" : "{actor} elintézte a(z) {todo} teendőt a következő listában: {calendar}", + "You solved to-do {todo} in list {calendar}" : "Elintézte a(z) {todo} teendőt a következő listában: {calendar}", + "{actor} reopened to-do {todo} in list {calendar}" : "{actor} újranyitotta a(z) {todo} teendőt a következő listában: {calendar}", + "You reopened to-do {todo} in list {calendar}" : "Újranyitotta a(z) {todo} teendőt a következő listában: {calendar}", + "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor} áthelyezte a(z) {todo} teendőt a(z) {sourceCalendar} listából a(z) {targetCalendar} listába", + "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "Áthelyezte a(z) {todo} teendőt a(z) {sourceCalendar} listából a(z) {targetCalendar} listába", "Calendar, contacts and tasks" : "Naptár, címjegyzék és feladatok", "A <strong>calendar</strong> was modified" : "Egy <strong>naptár</strong> megváltozott", "A calendar <strong>event</strong> was modified" : "Egy <strong>naptáresemény</strong> megváltozott", - "A calendar <strong>todo</strong> was modified" : "Egy <strong>naptárteendő</strong> megváltozott", + "A calendar <strong>to-do</strong> was modified" : "Egy <strong>naptárteendő</strong> megváltozott", "Contact birthdays" : "Névjegyek születésnapjai", "Death of %s" : "%s halála", "Calendar:" : "Naptár:", @@ -155,6 +159,7 @@ OC.L10N.register( "Friday" : "Péntek", "Saturday" : "Szombat", "Sunday" : "Vasárnap", + "Automatically set user status to \"Do not disturb\" outside of availability to mute all notifications." : "Az elérhetőségi időn túl, a felhasználói állapot automatikus beállítása „Ne zavarjanak” módba az összes értesítés némításához.", "Save" : "Mentés", "Failed to load availability" : "Az elérhetőség betöltése sikertelen", "Saved availability" : "Elérhetőség mentve", @@ -177,6 +182,18 @@ OC.L10N.register( "Tentative" : "Feltételes", "Number of guests" : "Vendégek száma", "Comment" : "Megjegyzés", - "Your attendance was updated successfully." : "A részvétele frissítése sikeres." + "Your attendance was updated successfully." : "A részvétele frissítése sikeres.", + "Todos" : "Teendők", + "{actor} created todo {todo} in list {calendar}" : "{actor} létrehozta a(z) {todo} teendőt a következő listában: {calendar}", + "You created todo {todo} in list {calendar}" : "Létrehozta a(z) {todo} teendőt a következő listában: {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} törölte a(z) {todo} teendőt a következő listából: {calendar}", + "You deleted todo {todo} from list {calendar}" : "Törölte a(z) {todo} teendőt a következő listából: {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} frissítette a(z) {todo} teendőt a következő listában: {calendar}", + "You updated todo {todo} in list {calendar}" : "Frissítette a(z) {todo} teendőt a következő listában: {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} elintézte a(z) {todo} teendőt a következő listában: {calendar}", + "You solved todo {todo} in list {calendar}" : "Elintézte a(z) {todo} teendőt a következő listában: {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} újranyitotta a(z) {todo} teendőt a következő listában: {calendar}", + "You reopened todo {todo} in list {calendar}" : "Újranyitotta a(z) {todo} teendőt a következő listában: {calendar}", + "A calendar <strong>todo</strong> was modified" : "Egy <strong>naptárteendő</strong> megváltozott" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/dav/l10n/hu.json b/apps/dav/l10n/hu.json index b6907f61630..7b4b1e63c4e 100644 --- a/apps/dav/l10n/hu.json +++ b/apps/dav/l10n/hu.json @@ -1,6 +1,6 @@ { "translations": { "Calendar" : "Naptár", - "Todos" : "Teendők", + "To-dos" : "Teendők", "Personal" : "Személyes", "{actor} created calendar {calendar}" : "{actor} létrehozta a naptárt: {calendar}", "You created calendar {calendar}" : "Létrehozta a naptárt: {calendar}", @@ -30,23 +30,27 @@ "You deleted event {event} from calendar {calendar}" : "Törölte a(z) {event} eseményt a következő naptárból: {calendar}", "{actor} updated event {event} in calendar {calendar}" : "{actor} frissítette a(z) {event} eseményt a következő naptárban: {calendar}", "You updated event {event} in calendar {calendar}" : "Frissítette a(z) {event} eseményt a következő naptárban: {calendar}", + "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{actor} áthelyezte a(z) {event} eseményt a(z) {sourceCalendar} naptárból a(z) {targetCalendar} naptárba", + "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "Áthelyezte a(z) {event} eseményt a(z) {sourceCalendar} naptárból a(z) {targetCalendar} naptárba", "{actor} restored event {event} of calendar {calendar}" : "{actor} helyreállította a(z) {calendar} naptár következő eseményét: {event}", "You restored event {event} of calendar {calendar}" : "Helyreállította a(z) {calendar} naptár következő eseményét: {event}", "Busy" : "Foglalt", - "{actor} created todo {todo} in list {calendar}" : "{actor} létrehozta a(z) {todo} teendőt a következő listában: {calendar}", - "You created todo {todo} in list {calendar}" : "Létrehozta a(z) {todo} teendőt a következő listában: {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} törölte a(z) {todo} teendőt a következő listából: {calendar}", - "You deleted todo {todo} from list {calendar}" : "Törölte a(z) {todo} teendőt a következő listából: {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} frissítette a(z) {todo} teendőt a következő listában: {calendar}", - "You updated todo {todo} in list {calendar}" : "Frissítette a(z) {todo} teendőt a következő listában: {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} elintézte a(z) {todo} teendőt a következő listában: {calendar}", - "You solved todo {todo} in list {calendar}" : "Elintézte a(z) {todo} teendőt a következő listában: {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} újranyitotta a(z) {todo} teendőt a következő listában: {calendar}", - "You reopened todo {todo} in list {calendar}" : "Újranyitotta a(z) {todo} teendőt a következő listában: {calendar}", + "{actor} created to-do {todo} in list {calendar}" : "{actor} létrehozta a(z) {todo} teendőt a következő listában: {calendar}", + "You created to-do {todo} in list {calendar}" : "Létrehozta a(z) {todo} teendőt a következő listában: {calendar}", + "{actor} deleted to-do {todo} from list {calendar}" : "{actor} törölte a(z) {todo} teendőt a következő listából: {calendar}", + "You deleted to-do {todo} from list {calendar}" : "Törölte a(z) {todo} teendőt a következő listából: {calendar}", + "{actor} updated to-do {todo} in list {calendar}" : "{actor} frissítette a(z) {todo} teendőt a következő listában: {calendar}", + "You updated to-do {todo} in list {calendar}" : "Frissítette a(z) {todo} teendőt a következő listában: {calendar}", + "{actor} solved to-do {todo} in list {calendar}" : "{actor} elintézte a(z) {todo} teendőt a következő listában: {calendar}", + "You solved to-do {todo} in list {calendar}" : "Elintézte a(z) {todo} teendőt a következő listában: {calendar}", + "{actor} reopened to-do {todo} in list {calendar}" : "{actor} újranyitotta a(z) {todo} teendőt a következő listában: {calendar}", + "You reopened to-do {todo} in list {calendar}" : "Újranyitotta a(z) {todo} teendőt a következő listában: {calendar}", + "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor} áthelyezte a(z) {todo} teendőt a(z) {sourceCalendar} listából a(z) {targetCalendar} listába", + "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "Áthelyezte a(z) {todo} teendőt a(z) {sourceCalendar} listából a(z) {targetCalendar} listába", "Calendar, contacts and tasks" : "Naptár, címjegyzék és feladatok", "A <strong>calendar</strong> was modified" : "Egy <strong>naptár</strong> megváltozott", "A calendar <strong>event</strong> was modified" : "Egy <strong>naptáresemény</strong> megváltozott", - "A calendar <strong>todo</strong> was modified" : "Egy <strong>naptárteendő</strong> megváltozott", + "A calendar <strong>to-do</strong> was modified" : "Egy <strong>naptárteendő</strong> megváltozott", "Contact birthdays" : "Névjegyek születésnapjai", "Death of %s" : "%s halála", "Calendar:" : "Naptár:", @@ -153,6 +157,7 @@ "Friday" : "Péntek", "Saturday" : "Szombat", "Sunday" : "Vasárnap", + "Automatically set user status to \"Do not disturb\" outside of availability to mute all notifications." : "Az elérhetőségi időn túl, a felhasználói állapot automatikus beállítása „Ne zavarjanak” módba az összes értesítés némításához.", "Save" : "Mentés", "Failed to load availability" : "Az elérhetőség betöltése sikertelen", "Saved availability" : "Elérhetőség mentve", @@ -175,6 +180,18 @@ "Tentative" : "Feltételes", "Number of guests" : "Vendégek száma", "Comment" : "Megjegyzés", - "Your attendance was updated successfully." : "A részvétele frissítése sikeres." + "Your attendance was updated successfully." : "A részvétele frissítése sikeres.", + "Todos" : "Teendők", + "{actor} created todo {todo} in list {calendar}" : "{actor} létrehozta a(z) {todo} teendőt a következő listában: {calendar}", + "You created todo {todo} in list {calendar}" : "Létrehozta a(z) {todo} teendőt a következő listában: {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} törölte a(z) {todo} teendőt a következő listából: {calendar}", + "You deleted todo {todo} from list {calendar}" : "Törölte a(z) {todo} teendőt a következő listából: {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} frissítette a(z) {todo} teendőt a következő listában: {calendar}", + "You updated todo {todo} in list {calendar}" : "Frissítette a(z) {todo} teendőt a következő listában: {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} elintézte a(z) {todo} teendőt a következő listában: {calendar}", + "You solved todo {todo} in list {calendar}" : "Elintézte a(z) {todo} teendőt a következő listában: {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} újranyitotta a(z) {todo} teendőt a következő listában: {calendar}", + "You reopened todo {todo} in list {calendar}" : "Újranyitotta a(z) {todo} teendőt a következő listában: {calendar}", + "A calendar <strong>todo</strong> was modified" : "Egy <strong>naptárteendő</strong> megváltozott" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/dav/l10n/is.js b/apps/dav/l10n/is.js index 6e03824ae14..676b58c83ee 100644 --- a/apps/dav/l10n/is.js +++ b/apps/dav/l10n/is.js @@ -2,7 +2,6 @@ OC.L10N.register( "dav", { "Calendar" : "Dagatal", - "Todos" : "Verkþættir", "Personal" : "Einka", "{actor} created calendar {calendar}" : "{actor} bjó til dagatalið {calendar}", "You created calendar {calendar}" : "Þú bjóst til dagatalið {calendar}", @@ -31,19 +30,8 @@ OC.L10N.register( "{actor} updated event {event} in calendar {calendar}" : "{actor} uppfærði atburðinn {event} í dagatalinu {calendar}", "You updated event {event} in calendar {calendar}" : "Þú uppfærðir atburðinn {event} í dagatalinu {calendar}", "Busy" : "Upptekið", - "{actor} created todo {todo} in list {calendar}" : "{actor} bjó til verkefnið {todo} á listanum {calendar}", - "You created todo {todo} in list {calendar}" : "Þú bjóst til verkefnið {todo} á listanum {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} eyddi verkefninu {todo} af listanum {calendar}", - "You deleted todo {todo} from list {calendar}" : "Þú eyddir verkefninu {todo} af listanum {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} uppfærði verkefnið {todo} á listanum {calendar}", - "You updated todo {todo} in list {calendar}" : "Þú uppfærðir verkefnið {todo} á listanum {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} leysti verkefnið {todo} á listanum {calendar}", - "You solved todo {todo} in list {calendar}" : "Þú leystir verkefnið {todo} á listanum {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} opnaði aftur verkefnið {todo} á listanum {calendar}", - "You reopened todo {todo} in list {calendar}" : "Þú opnaðir aftur verkefnið {todo} á listanum {calendar}", "A <strong>calendar</strong> was modified" : "<strong>Dagatali</strong> var breytt", "A calendar <strong>event</strong> was modified" : "<strong>Atburði</strong> dagatals var breytt", - "A calendar <strong>todo</strong> was modified" : "<strong>Verkefnalista</strong> dagatals var breytt", "Contact birthdays" : "Afmælisdagar tengiliðar", "Calendar:" : "Dagatal:", "Date:" : "Dagsetning:", @@ -63,6 +51,7 @@ OC.L10N.register( "%1$s via %2$s" : "%1$s með %2$s", "Invitation canceled" : "Hætt við boð", "Invitation updated" : "Boð uppfært", + "Time:" : "Tími:", "Location:" : "Staðsetning:", "Link:" : "Tengill:", "Accept" : "Samþykkja", @@ -78,6 +67,7 @@ OC.L10N.register( "WebDAV" : "WebDAV", "WebDAV endpoint" : "WebDAV-endapunktur", "to" : "til", + "Delete slot" : "Eyða tímahólfi", "Monday" : "Mánudagur", "Tuesday" : "Þriðjudagur", "Wednesday" : "Miðvikudagur", @@ -98,6 +88,18 @@ OC.L10N.register( "Are you accepting the invitation?" : "Ætlar þú að samþykkja boðið?", "Tentative" : "Bráðabirgða", "Comment" : "Athugasemd", - "Your attendance was updated successfully." : "Mætingarstaða þín var uppfærð." + "Your attendance was updated successfully." : "Mætingarstaða þín var uppfærð.", + "Todos" : "Verkþættir", + "{actor} created todo {todo} in list {calendar}" : "{actor} bjó til verkefnið {todo} á listanum {calendar}", + "You created todo {todo} in list {calendar}" : "Þú bjóst til verkefnið {todo} á listanum {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} eyddi verkefninu {todo} af listanum {calendar}", + "You deleted todo {todo} from list {calendar}" : "Þú eyddir verkefninu {todo} af listanum {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} uppfærði verkefnið {todo} á listanum {calendar}", + "You updated todo {todo} in list {calendar}" : "Þú uppfærðir verkefnið {todo} á listanum {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} leysti verkefnið {todo} á listanum {calendar}", + "You solved todo {todo} in list {calendar}" : "Þú leystir verkefnið {todo} á listanum {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} opnaði aftur verkefnið {todo} á listanum {calendar}", + "You reopened todo {todo} in list {calendar}" : "Þú opnaðir aftur verkefnið {todo} á listanum {calendar}", + "A calendar <strong>todo</strong> was modified" : "<strong>Verkefnalista</strong> dagatals var breytt" }, "nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);"); diff --git a/apps/dav/l10n/is.json b/apps/dav/l10n/is.json index d7b6bda37f6..a5a5ac796a4 100644 --- a/apps/dav/l10n/is.json +++ b/apps/dav/l10n/is.json @@ -1,6 +1,5 @@ { "translations": { "Calendar" : "Dagatal", - "Todos" : "Verkþættir", "Personal" : "Einka", "{actor} created calendar {calendar}" : "{actor} bjó til dagatalið {calendar}", "You created calendar {calendar}" : "Þú bjóst til dagatalið {calendar}", @@ -29,19 +28,8 @@ "{actor} updated event {event} in calendar {calendar}" : "{actor} uppfærði atburðinn {event} í dagatalinu {calendar}", "You updated event {event} in calendar {calendar}" : "Þú uppfærðir atburðinn {event} í dagatalinu {calendar}", "Busy" : "Upptekið", - "{actor} created todo {todo} in list {calendar}" : "{actor} bjó til verkefnið {todo} á listanum {calendar}", - "You created todo {todo} in list {calendar}" : "Þú bjóst til verkefnið {todo} á listanum {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} eyddi verkefninu {todo} af listanum {calendar}", - "You deleted todo {todo} from list {calendar}" : "Þú eyddir verkefninu {todo} af listanum {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} uppfærði verkefnið {todo} á listanum {calendar}", - "You updated todo {todo} in list {calendar}" : "Þú uppfærðir verkefnið {todo} á listanum {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} leysti verkefnið {todo} á listanum {calendar}", - "You solved todo {todo} in list {calendar}" : "Þú leystir verkefnið {todo} á listanum {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} opnaði aftur verkefnið {todo} á listanum {calendar}", - "You reopened todo {todo} in list {calendar}" : "Þú opnaðir aftur verkefnið {todo} á listanum {calendar}", "A <strong>calendar</strong> was modified" : "<strong>Dagatali</strong> var breytt", "A calendar <strong>event</strong> was modified" : "<strong>Atburði</strong> dagatals var breytt", - "A calendar <strong>todo</strong> was modified" : "<strong>Verkefnalista</strong> dagatals var breytt", "Contact birthdays" : "Afmælisdagar tengiliðar", "Calendar:" : "Dagatal:", "Date:" : "Dagsetning:", @@ -61,6 +49,7 @@ "%1$s via %2$s" : "%1$s með %2$s", "Invitation canceled" : "Hætt við boð", "Invitation updated" : "Boð uppfært", + "Time:" : "Tími:", "Location:" : "Staðsetning:", "Link:" : "Tengill:", "Accept" : "Samþykkja", @@ -76,6 +65,7 @@ "WebDAV" : "WebDAV", "WebDAV endpoint" : "WebDAV-endapunktur", "to" : "til", + "Delete slot" : "Eyða tímahólfi", "Monday" : "Mánudagur", "Tuesday" : "Þriðjudagur", "Wednesday" : "Miðvikudagur", @@ -96,6 +86,18 @@ "Are you accepting the invitation?" : "Ætlar þú að samþykkja boðið?", "Tentative" : "Bráðabirgða", "Comment" : "Athugasemd", - "Your attendance was updated successfully." : "Mætingarstaða þín var uppfærð." + "Your attendance was updated successfully." : "Mætingarstaða þín var uppfærð.", + "Todos" : "Verkþættir", + "{actor} created todo {todo} in list {calendar}" : "{actor} bjó til verkefnið {todo} á listanum {calendar}", + "You created todo {todo} in list {calendar}" : "Þú bjóst til verkefnið {todo} á listanum {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} eyddi verkefninu {todo} af listanum {calendar}", + "You deleted todo {todo} from list {calendar}" : "Þú eyddir verkefninu {todo} af listanum {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} uppfærði verkefnið {todo} á listanum {calendar}", + "You updated todo {todo} in list {calendar}" : "Þú uppfærðir verkefnið {todo} á listanum {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} leysti verkefnið {todo} á listanum {calendar}", + "You solved todo {todo} in list {calendar}" : "Þú leystir verkefnið {todo} á listanum {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} opnaði aftur verkefnið {todo} á listanum {calendar}", + "You reopened todo {todo} in list {calendar}" : "Þú opnaðir aftur verkefnið {todo} á listanum {calendar}", + "A calendar <strong>todo</strong> was modified" : "<strong>Verkefnalista</strong> dagatals var breytt" },"pluralForm" :"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);" }
\ No newline at end of file diff --git a/apps/dav/l10n/it.js b/apps/dav/l10n/it.js index 1d90a506fe8..bdc929df478 100644 --- a/apps/dav/l10n/it.js +++ b/apps/dav/l10n/it.js @@ -2,7 +2,6 @@ OC.L10N.register( "dav", { "Calendar" : "Calendario", - "Todos" : "Cose da fare", "Personal" : "Personale", "{actor} created calendar {calendar}" : "{actor} ha creato il calendario {calendar}", "You created calendar {calendar}" : "Hai creato il calendario {calendar}", @@ -35,20 +34,9 @@ OC.L10N.register( "{actor} restored event {event} of calendar {calendar}" : "{actor} ha ripristinato l'evento {event} del calendario {calendar}", "You restored event {event} of calendar {calendar}" : "Hai ripristinato l'evento {event} del calendario {calendar}", "Busy" : "Occupato", - "{actor} created todo {todo} in list {calendar}" : "{actor} ha creato la cosa da fare {todo} nell'elenco {calendar}", - "You created todo {todo} in list {calendar}" : "Hai creato la cosa da fare {todo} nell'elenco {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} ha eliminato la cosa da fare {todo} dall'elenco {calendar}", - "You deleted todo {todo} from list {calendar}" : "Hai eliminato la cosa da fare {todo} dall'elenco {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} ha aggiornato la cosa da fare {todo} nell'elenco {calendar}", - "You updated todo {todo} in list {calendar}" : "Hai aggiornato la cosa da fare {todo} nell'elenco {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} ha risolto la cosa da fare {todo} nell'elenco {calendar}", - "You solved todo {todo} in list {calendar}" : "Hai risolto la cosa da fare {todo} nell'elenco {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} ha riaperto la cosa da fare {todo} nell'elenco {calendar}", - "You reopened todo {todo} in list {calendar}" : "Hai riaperto la cosa da fare {todo} nell'elenco {calendar}", "Calendar, contacts and tasks" : "Calendario, contatti e attività", "A <strong>calendar</strong> was modified" : "Un <strong>calendario</strong> è stato modificato", "A calendar <strong>event</strong> was modified" : "Un <strong>evento</strong> del calendario è stato modificato", - "A calendar <strong>todo</strong> was modified" : "Una <strong>cosa da fare</strong> del calendario è stata modificata", "Contact birthdays" : "Date di nascita dei contatti", "Death of %s" : "Morte di %s", "Calendar:" : "Calendario:", @@ -171,6 +159,18 @@ OC.L10N.register( "Tentative" : "Provvisorio", "Number of guests" : "Numero di ospiti", "Comment" : "Commento", - "Your attendance was updated successfully." : "La tua partecipazione è stata aggiornata correttamente." + "Your attendance was updated successfully." : "La tua partecipazione è stata aggiornata correttamente.", + "Todos" : "Cose da fare", + "{actor} created todo {todo} in list {calendar}" : "{actor} ha creato la cosa da fare {todo} nell'elenco {calendar}", + "You created todo {todo} in list {calendar}" : "Hai creato la cosa da fare {todo} nell'elenco {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} ha eliminato la cosa da fare {todo} dall'elenco {calendar}", + "You deleted todo {todo} from list {calendar}" : "Hai eliminato la cosa da fare {todo} dall'elenco {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} ha aggiornato la cosa da fare {todo} nell'elenco {calendar}", + "You updated todo {todo} in list {calendar}" : "Hai aggiornato la cosa da fare {todo} nell'elenco {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} ha risolto la cosa da fare {todo} nell'elenco {calendar}", + "You solved todo {todo} in list {calendar}" : "Hai risolto la cosa da fare {todo} nell'elenco {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} ha riaperto la cosa da fare {todo} nell'elenco {calendar}", + "You reopened todo {todo} in list {calendar}" : "Hai riaperto la cosa da fare {todo} nell'elenco {calendar}", + "A calendar <strong>todo</strong> was modified" : "Una <strong>cosa da fare</strong> del calendario è stata modificata" }, "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/apps/dav/l10n/it.json b/apps/dav/l10n/it.json index 5bbdb84d88f..c1d27701463 100644 --- a/apps/dav/l10n/it.json +++ b/apps/dav/l10n/it.json @@ -1,6 +1,5 @@ { "translations": { "Calendar" : "Calendario", - "Todos" : "Cose da fare", "Personal" : "Personale", "{actor} created calendar {calendar}" : "{actor} ha creato il calendario {calendar}", "You created calendar {calendar}" : "Hai creato il calendario {calendar}", @@ -33,20 +32,9 @@ "{actor} restored event {event} of calendar {calendar}" : "{actor} ha ripristinato l'evento {event} del calendario {calendar}", "You restored event {event} of calendar {calendar}" : "Hai ripristinato l'evento {event} del calendario {calendar}", "Busy" : "Occupato", - "{actor} created todo {todo} in list {calendar}" : "{actor} ha creato la cosa da fare {todo} nell'elenco {calendar}", - "You created todo {todo} in list {calendar}" : "Hai creato la cosa da fare {todo} nell'elenco {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} ha eliminato la cosa da fare {todo} dall'elenco {calendar}", - "You deleted todo {todo} from list {calendar}" : "Hai eliminato la cosa da fare {todo} dall'elenco {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} ha aggiornato la cosa da fare {todo} nell'elenco {calendar}", - "You updated todo {todo} in list {calendar}" : "Hai aggiornato la cosa da fare {todo} nell'elenco {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} ha risolto la cosa da fare {todo} nell'elenco {calendar}", - "You solved todo {todo} in list {calendar}" : "Hai risolto la cosa da fare {todo} nell'elenco {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} ha riaperto la cosa da fare {todo} nell'elenco {calendar}", - "You reopened todo {todo} in list {calendar}" : "Hai riaperto la cosa da fare {todo} nell'elenco {calendar}", "Calendar, contacts and tasks" : "Calendario, contatti e attività", "A <strong>calendar</strong> was modified" : "Un <strong>calendario</strong> è stato modificato", "A calendar <strong>event</strong> was modified" : "Un <strong>evento</strong> del calendario è stato modificato", - "A calendar <strong>todo</strong> was modified" : "Una <strong>cosa da fare</strong> del calendario è stata modificata", "Contact birthdays" : "Date di nascita dei contatti", "Death of %s" : "Morte di %s", "Calendar:" : "Calendario:", @@ -169,6 +157,18 @@ "Tentative" : "Provvisorio", "Number of guests" : "Numero di ospiti", "Comment" : "Commento", - "Your attendance was updated successfully." : "La tua partecipazione è stata aggiornata correttamente." + "Your attendance was updated successfully." : "La tua partecipazione è stata aggiornata correttamente.", + "Todos" : "Cose da fare", + "{actor} created todo {todo} in list {calendar}" : "{actor} ha creato la cosa da fare {todo} nell'elenco {calendar}", + "You created todo {todo} in list {calendar}" : "Hai creato la cosa da fare {todo} nell'elenco {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} ha eliminato la cosa da fare {todo} dall'elenco {calendar}", + "You deleted todo {todo} from list {calendar}" : "Hai eliminato la cosa da fare {todo} dall'elenco {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} ha aggiornato la cosa da fare {todo} nell'elenco {calendar}", + "You updated todo {todo} in list {calendar}" : "Hai aggiornato la cosa da fare {todo} nell'elenco {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} ha risolto la cosa da fare {todo} nell'elenco {calendar}", + "You solved todo {todo} in list {calendar}" : "Hai risolto la cosa da fare {todo} nell'elenco {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} ha riaperto la cosa da fare {todo} nell'elenco {calendar}", + "You reopened todo {todo} in list {calendar}" : "Hai riaperto la cosa da fare {todo} nell'elenco {calendar}", + "A calendar <strong>todo</strong> was modified" : "Una <strong>cosa da fare</strong> del calendario è stata modificata" },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/apps/dav/l10n/ja.js b/apps/dav/l10n/ja.js index 07c1086f404..a9cbf7e6b94 100644 --- a/apps/dav/l10n/ja.js +++ b/apps/dav/l10n/ja.js @@ -2,7 +2,6 @@ OC.L10N.register( "dav", { "Calendar" : "カレンダー", - "Todos" : "ToDo", "Personal" : "個人", "{actor} created calendar {calendar}" : "{actor}はカレンダー {calendar} を作成しました", "You created calendar {calendar}" : "カレンダー {calendar} を作成しました", @@ -35,20 +34,9 @@ OC.L10N.register( "{actor} restored event {event} of calendar {calendar}" : "{actor}はカレンダー {calendar}のイベント {event}を復元しました", "You restored event {event} of calendar {calendar}" : "カレンダー {calendar} のイベント {event}を復元しました", "Busy" : "ビジー", - "{actor} created todo {todo} in list {calendar}" : "{actor}はリスト{calendar}のtodo {todo}を作成しました", - "You created todo {todo} in list {calendar}" : "リスト {calendar} にtodo {todo} を作成しました", - "{actor} deleted todo {todo} from list {calendar}" : "{actor}リスト{カレンダー}からtodo {todo}を削除しました", - "You deleted todo {todo} from list {calendar}" : "あなたはtodo {todo}を{calendar}のリストから削除しました。", - "{actor} updated todo {todo} in list {calendar}" : "{actor}リスト{calendar}のtodo {todo}を更新しました", - "You updated todo {todo} in list {calendar}" : "リスト{calendar}のtodo {todo}を更新しました。", - "{actor} solved todo {todo} in list {calendar}" : "{actor}リスト{calendar}のtodo {todo}を解決しました", - "You solved todo {todo} in list {calendar}" : "リスト{calendar}のtodo {todo}を解決しました。", - "{actor} reopened todo {todo} in list {calendar}" : "{actor}リスト{calendar}のToDo {todo}を再開しました", - "You reopened todo {todo} in list {calendar}" : "リスト{calendar}のtodo {todo}を再開しました", "Calendar, contacts and tasks" : "カレンダー、連絡帳とタスク", "A <strong>calendar</strong> was modified" : "<strong>カレンダー</strong>が変更されたとき", "A calendar <strong>event</strong> was modified" : "カレンダーの<strong>イベント</strong>が変更されたとき", - "A calendar <strong>todo</strong> was modified" : "カレンダーの<strong>ToDo</strong>が変更されたとき", "Contact birthdays" : "誕生日", "Death of %s" : "%sの命日", "Calendar:" : "カレンダー:", @@ -112,7 +100,19 @@ OC.L10N.register( "Could not write to final file, canceled by hook" : "最終ファイルへの書き込みができなかったため、フックによりキャンセルされた", "Could not write file contents" : "ファイルの内容を書き込むことができませんでした", "_%n byte_::_%n bytes_" : ["%n bytes"], + "Error while copying file to target location (copied: %1$s, expected filesize: %2$s)" : "ファイルをコピー先へコピー中にエラーが発生しました (コピー済: %1$s, 想定ファイルサイズ: %2$s)", + "Expected filesize of %1$s but read (from Nextcloud client) and wrote (to Nextcloud storage) %2$s. Could either be a network problem on the sending side or a problem writing to the storage on the server side." : "Nextcloudクライアントからの想定ファイルサイズは、%1$s ですが、Nextcloudストレージへの書き込みファイルサイズは %2$s でした。送信側のネットワークの問題またはサーバー側のストレージへの書き込みに問題がある可能性があります。", + "Could not rename part file to final file, canceled by hook" : "最終ファイルの名前の変更が出来なかったため、フックによりキャンセルされました", + "Could not rename part file to final file" : "最終ファイルの名前の変更が出来ませんでした", + "Failed to check file size: %1$s" : "ファイルサイズの確認に失敗: %1$s", "Could not open file" : "ファイルを開くことができませんでした", + "Encryption not ready: %1$s" : "暗号化の準備が出来ていません: %1$s", + "Failed to open file: %1$s" : "ファイルを開くのに失敗: %1$s", + "Failed to unlink: %1$s" : "リンクの解除に失敗: %1$s", + "Invalid chunk name" : "無効なチャンク名", + "Could not rename part file assembled from chunks" : "チャンクから構成されている部分ファイルの名前の変更ができませんでした", + "Failed to write file contents: %1$s" : "ファイルの内容の書き込みに失敗: %1$s", + "File not found: %1$s" : "ファイルが見つかりません: %1$s", "System is in maintenance mode." : "システムはメンテナンスモードです。", "Upgrade needed" : "アップグレードが必要です", "Your %s needs to be configured to use HTTPS in order to use CalDAV and CardDAV with iOS/macOS." : "iOS / macOSでCalDAVおよびCardDAVを使用するには、%sにHTTPSを設定する必要があります。", @@ -124,6 +124,8 @@ OC.L10N.register( "Completed on %s" : "%sに完了", "Due on %s by %s" : "期限日%s が%sにより設定", "Due on %s" : "期限日:%s", + "Migrated calendar (%1$s)" : "カレンダーを移行しました (%1$s)", + "Calendars including events, details and attendees" : "カレンダーには、イベント、イベントの詳細及び出席者が含まれます", "Contacts and groups" : "連絡先とグループ", "WebDAV" : "WebDAV", "WebDAV endpoint" : "WebDAVエンドポイント", @@ -133,6 +135,7 @@ OC.L10N.register( "to" : "宛先", "Delete slot" : "スロットを削除", "No working hours set" : "勤務時間未設定", + "Add slot" : "スロットを追加", "Monday" : "月曜日", "Tuesday" : "火曜日", "Wednesday" : "水曜日", @@ -141,6 +144,9 @@ OC.L10N.register( "Saturday" : "土曜日", "Sunday" : "日曜日", "Save" : "保存", + "Failed to load availability" : "可用性の読み込みに失敗", + "Saved availability" : "可用性を保存しました", + "Failed to save availability" : "可用性を保存しました", "Calendar server" : "カレンダーサーバー", "Send invitations to attendees" : "参加者に招待状を送信する", "Automatically generate a birthday calendar" : "自動的に誕生日カレンダーを生成する", @@ -148,6 +154,8 @@ OC.L10N.register( "Hence they will not be available immediately after enabling but will show up after some time." : "したがって、有効にした直後は利用できませんが、しばらくしてから表示されます。", "Send notifications for events" : "イベントの通知を送信", "Notifications are sent via background jobs, so these must occur often enough." : "通知はバックグラウンドジョブを介して送信されるため、十分な頻度で発生します。", + "Send reminder notifications to calendar sharees as well" : "カレンダー共有にもリマインダー通知を送信する", + "Reminders are always sent to organizers and attendees." : "リマインダーを常に作成者と出席者に送信します。", "Enable notifications for events via push" : "イベントのプッシュ通知を有効にする", "Also install the {calendarappstoreopen}Calendar app{linkclose}, or {calendardocopen}connect your desktop & mobile for syncing ↗{linkclose}." : "{calendarappstoreopen}カレンダーアプリ{linkclose}、または{calendardocopen}を同期させるためにデスクトップとモバイルを接続する ↗{linkclose}もインストールしてください。", "Please make sure to properly set up {emailopen}the email server{linkclose}." : "{emailopen}メールサーバー{linkclose}を正しく設定してください。", @@ -155,7 +163,20 @@ OC.L10N.register( "Please contact the organizer directly." : "主催者に直接お問い合わせください。", "Are you accepting the invitation?" : "招待を受け入れていますか?", "Tentative" : "暫定的", + "Number of guests" : "ゲスト数", "Comment" : "コメント", - "Your attendance was updated successfully." : "出席は正常に更新されました。" + "Your attendance was updated successfully." : "出席は正常に更新されました。", + "Todos" : "ToDo", + "{actor} created todo {todo} in list {calendar}" : "{actor}はリスト{calendar}のtodo {todo}を作成しました", + "You created todo {todo} in list {calendar}" : "リスト {calendar} にtodo {todo} を作成しました", + "{actor} deleted todo {todo} from list {calendar}" : "{actor}リスト{カレンダー}からtodo {todo}を削除しました", + "You deleted todo {todo} from list {calendar}" : "あなたはtodo {todo}を{calendar}のリストから削除しました。", + "{actor} updated todo {todo} in list {calendar}" : "{actor}リスト{calendar}のtodo {todo}を更新しました", + "You updated todo {todo} in list {calendar}" : "リスト{calendar}のtodo {todo}を更新しました。", + "{actor} solved todo {todo} in list {calendar}" : "{actor}リスト{calendar}のtodo {todo}を解決しました", + "You solved todo {todo} in list {calendar}" : "リスト{calendar}のtodo {todo}を解決しました。", + "{actor} reopened todo {todo} in list {calendar}" : "{actor}リスト{calendar}のToDo {todo}を再開しました", + "You reopened todo {todo} in list {calendar}" : "リスト{calendar}のtodo {todo}を再開しました", + "A calendar <strong>todo</strong> was modified" : "カレンダーの<strong>ToDo</strong>が変更されたとき" }, "nplurals=1; plural=0;"); diff --git a/apps/dav/l10n/ja.json b/apps/dav/l10n/ja.json index 46748402cd9..e5ec8aeb504 100644 --- a/apps/dav/l10n/ja.json +++ b/apps/dav/l10n/ja.json @@ -1,6 +1,5 @@ { "translations": { "Calendar" : "カレンダー", - "Todos" : "ToDo", "Personal" : "個人", "{actor} created calendar {calendar}" : "{actor}はカレンダー {calendar} を作成しました", "You created calendar {calendar}" : "カレンダー {calendar} を作成しました", @@ -33,20 +32,9 @@ "{actor} restored event {event} of calendar {calendar}" : "{actor}はカレンダー {calendar}のイベント {event}を復元しました", "You restored event {event} of calendar {calendar}" : "カレンダー {calendar} のイベント {event}を復元しました", "Busy" : "ビジー", - "{actor} created todo {todo} in list {calendar}" : "{actor}はリスト{calendar}のtodo {todo}を作成しました", - "You created todo {todo} in list {calendar}" : "リスト {calendar} にtodo {todo} を作成しました", - "{actor} deleted todo {todo} from list {calendar}" : "{actor}リスト{カレンダー}からtodo {todo}を削除しました", - "You deleted todo {todo} from list {calendar}" : "あなたはtodo {todo}を{calendar}のリストから削除しました。", - "{actor} updated todo {todo} in list {calendar}" : "{actor}リスト{calendar}のtodo {todo}を更新しました", - "You updated todo {todo} in list {calendar}" : "リスト{calendar}のtodo {todo}を更新しました。", - "{actor} solved todo {todo} in list {calendar}" : "{actor}リスト{calendar}のtodo {todo}を解決しました", - "You solved todo {todo} in list {calendar}" : "リスト{calendar}のtodo {todo}を解決しました。", - "{actor} reopened todo {todo} in list {calendar}" : "{actor}リスト{calendar}のToDo {todo}を再開しました", - "You reopened todo {todo} in list {calendar}" : "リスト{calendar}のtodo {todo}を再開しました", "Calendar, contacts and tasks" : "カレンダー、連絡帳とタスク", "A <strong>calendar</strong> was modified" : "<strong>カレンダー</strong>が変更されたとき", "A calendar <strong>event</strong> was modified" : "カレンダーの<strong>イベント</strong>が変更されたとき", - "A calendar <strong>todo</strong> was modified" : "カレンダーの<strong>ToDo</strong>が変更されたとき", "Contact birthdays" : "誕生日", "Death of %s" : "%sの命日", "Calendar:" : "カレンダー:", @@ -110,7 +98,19 @@ "Could not write to final file, canceled by hook" : "最終ファイルへの書き込みができなかったため、フックによりキャンセルされた", "Could not write file contents" : "ファイルの内容を書き込むことができませんでした", "_%n byte_::_%n bytes_" : ["%n bytes"], + "Error while copying file to target location (copied: %1$s, expected filesize: %2$s)" : "ファイルをコピー先へコピー中にエラーが発生しました (コピー済: %1$s, 想定ファイルサイズ: %2$s)", + "Expected filesize of %1$s but read (from Nextcloud client) and wrote (to Nextcloud storage) %2$s. Could either be a network problem on the sending side or a problem writing to the storage on the server side." : "Nextcloudクライアントからの想定ファイルサイズは、%1$s ですが、Nextcloudストレージへの書き込みファイルサイズは %2$s でした。送信側のネットワークの問題またはサーバー側のストレージへの書き込みに問題がある可能性があります。", + "Could not rename part file to final file, canceled by hook" : "最終ファイルの名前の変更が出来なかったため、フックによりキャンセルされました", + "Could not rename part file to final file" : "最終ファイルの名前の変更が出来ませんでした", + "Failed to check file size: %1$s" : "ファイルサイズの確認に失敗: %1$s", "Could not open file" : "ファイルを開くことができませんでした", + "Encryption not ready: %1$s" : "暗号化の準備が出来ていません: %1$s", + "Failed to open file: %1$s" : "ファイルを開くのに失敗: %1$s", + "Failed to unlink: %1$s" : "リンクの解除に失敗: %1$s", + "Invalid chunk name" : "無効なチャンク名", + "Could not rename part file assembled from chunks" : "チャンクから構成されている部分ファイルの名前の変更ができませんでした", + "Failed to write file contents: %1$s" : "ファイルの内容の書き込みに失敗: %1$s", + "File not found: %1$s" : "ファイルが見つかりません: %1$s", "System is in maintenance mode." : "システムはメンテナンスモードです。", "Upgrade needed" : "アップグレードが必要です", "Your %s needs to be configured to use HTTPS in order to use CalDAV and CardDAV with iOS/macOS." : "iOS / macOSでCalDAVおよびCardDAVを使用するには、%sにHTTPSを設定する必要があります。", @@ -122,6 +122,8 @@ "Completed on %s" : "%sに完了", "Due on %s by %s" : "期限日%s が%sにより設定", "Due on %s" : "期限日:%s", + "Migrated calendar (%1$s)" : "カレンダーを移行しました (%1$s)", + "Calendars including events, details and attendees" : "カレンダーには、イベント、イベントの詳細及び出席者が含まれます", "Contacts and groups" : "連絡先とグループ", "WebDAV" : "WebDAV", "WebDAV endpoint" : "WebDAVエンドポイント", @@ -131,6 +133,7 @@ "to" : "宛先", "Delete slot" : "スロットを削除", "No working hours set" : "勤務時間未設定", + "Add slot" : "スロットを追加", "Monday" : "月曜日", "Tuesday" : "火曜日", "Wednesday" : "水曜日", @@ -139,6 +142,9 @@ "Saturday" : "土曜日", "Sunday" : "日曜日", "Save" : "保存", + "Failed to load availability" : "可用性の読み込みに失敗", + "Saved availability" : "可用性を保存しました", + "Failed to save availability" : "可用性を保存しました", "Calendar server" : "カレンダーサーバー", "Send invitations to attendees" : "参加者に招待状を送信する", "Automatically generate a birthday calendar" : "自動的に誕生日カレンダーを生成する", @@ -146,6 +152,8 @@ "Hence they will not be available immediately after enabling but will show up after some time." : "したがって、有効にした直後は利用できませんが、しばらくしてから表示されます。", "Send notifications for events" : "イベントの通知を送信", "Notifications are sent via background jobs, so these must occur often enough." : "通知はバックグラウンドジョブを介して送信されるため、十分な頻度で発生します。", + "Send reminder notifications to calendar sharees as well" : "カレンダー共有にもリマインダー通知を送信する", + "Reminders are always sent to organizers and attendees." : "リマインダーを常に作成者と出席者に送信します。", "Enable notifications for events via push" : "イベントのプッシュ通知を有効にする", "Also install the {calendarappstoreopen}Calendar app{linkclose}, or {calendardocopen}connect your desktop & mobile for syncing ↗{linkclose}." : "{calendarappstoreopen}カレンダーアプリ{linkclose}、または{calendardocopen}を同期させるためにデスクトップとモバイルを接続する ↗{linkclose}もインストールしてください。", "Please make sure to properly set up {emailopen}the email server{linkclose}." : "{emailopen}メールサーバー{linkclose}を正しく設定してください。", @@ -153,7 +161,20 @@ "Please contact the organizer directly." : "主催者に直接お問い合わせください。", "Are you accepting the invitation?" : "招待を受け入れていますか?", "Tentative" : "暫定的", + "Number of guests" : "ゲスト数", "Comment" : "コメント", - "Your attendance was updated successfully." : "出席は正常に更新されました。" + "Your attendance was updated successfully." : "出席は正常に更新されました。", + "Todos" : "ToDo", + "{actor} created todo {todo} in list {calendar}" : "{actor}はリスト{calendar}のtodo {todo}を作成しました", + "You created todo {todo} in list {calendar}" : "リスト {calendar} にtodo {todo} を作成しました", + "{actor} deleted todo {todo} from list {calendar}" : "{actor}リスト{カレンダー}からtodo {todo}を削除しました", + "You deleted todo {todo} from list {calendar}" : "あなたはtodo {todo}を{calendar}のリストから削除しました。", + "{actor} updated todo {todo} in list {calendar}" : "{actor}リスト{calendar}のtodo {todo}を更新しました", + "You updated todo {todo} in list {calendar}" : "リスト{calendar}のtodo {todo}を更新しました。", + "{actor} solved todo {todo} in list {calendar}" : "{actor}リスト{calendar}のtodo {todo}を解決しました", + "You solved todo {todo} in list {calendar}" : "リスト{calendar}のtodo {todo}を解決しました。", + "{actor} reopened todo {todo} in list {calendar}" : "{actor}リスト{calendar}のToDo {todo}を再開しました", + "You reopened todo {todo} in list {calendar}" : "リスト{calendar}のtodo {todo}を再開しました", + "A calendar <strong>todo</strong> was modified" : "カレンダーの<strong>ToDo</strong>が変更されたとき" },"pluralForm" :"nplurals=1; plural=0;" }
\ No newline at end of file diff --git a/apps/dav/l10n/ko.js b/apps/dav/l10n/ko.js index 9bb56bd1782..a5b398f33b2 100644 --- a/apps/dav/l10n/ko.js +++ b/apps/dav/l10n/ko.js @@ -2,7 +2,7 @@ OC.L10N.register( "dav", { "Calendar" : "달력", - "Todos" : "할 일", + "To-dos" : "할 일", "Personal" : "개인", "{actor} created calendar {calendar}" : "{actor} 님이 달력 {calendar}을(를) 생성함", "You created calendar {calendar}" : "달력 {calendar}을(를) 생성함", @@ -25,41 +25,45 @@ OC.L10N.register( "{actor} shared calendar {calendar} with group {group}" : "{actor} 님이 달력 {calendar}을(를) 그룹 {group}와(과) 공유함", "You unshared calendar {calendar} from group {group}" : "달력 {calendar}을(를) 그룹 {group}와(과) 공유하지 않음", "{actor} unshared calendar {calendar} from group {group}" : "{actor} 님이 달력 {calendar}을(를) 그룹 {group}와(과) 공유하지 않음", - "Untitled event" : "제목없는 이벤트", + "Untitled event" : "제목 없는 일정", "{actor} created event {event} in calendar {calendar}" : "{actor} 님이 행사 {event}을(를) 달력 {calendar}에 생성함", "You created event {event} in calendar {calendar}" : "행사 {event}을(를) 달력 {calendar}에 생성함", "{actor} deleted event {event} from calendar {calendar}" : "{actor} 님이 행사 {event}을(를) 달력 {calendar}에서 삭제함", "You deleted event {event} from calendar {calendar}" : "행사 {event}을(를) 달력 {calendar}에서 삭제함", "{actor} updated event {event} in calendar {calendar}" : "{actor} 님이 달력 {calendar}의 행사 {event}을(를) 업데이트함", "You updated event {event} in calendar {calendar}" : "달력 {calendar}의 행사 {event}을(를) 업데이트함", + "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{actor} 님이 행사 {event}을(를) 달력 {sourceCalendar}에서 달력 {targetCalendar}(으)로 옮김", + "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "행사 {event}을(를) 달력 {sourceCalendar}에서 달력 {targetCalendar}(으)로 옮김", "{actor} restored event {event} of calendar {calendar}" : "{actor} 님이 행사 {event}을(를) 달력 {calendar}에 복구함", "You restored event {event} of calendar {calendar}" : "행사 {event}을(를) 달력 {calendar}에 복구함", "Busy" : "바쁨", - "{actor} created todo {todo} in list {calendar}" : "{actor} 님이 목록 {calendar}에 할 일 {todo}을(를) 생성함", - "You created todo {todo} in list {calendar}" : "목록 {calendar}에 할 일 {todo}을(를) 생성함", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} 님이 목록 {calendar}에서 할 일 {todo}을(를) 삭제함", - "You deleted todo {todo} from list {calendar}" : "목록 {calendar}에서 할 일 {todo}을(를) 삭제함", - "{actor} updated todo {todo} in list {calendar}" : "{actor} 님이 목록 {calendar}의 할 일 {todo}을(를) 업데이트함", - "You updated todo {todo} in list {calendar}" : "목록 {calendar}의 할 일 {todo}을(를) 업데이트함", - "{actor} solved todo {todo} in list {calendar}" : "{actor} 님이 목록 {calendar}의 할 일 {todo}을(를) 끝냄", - "You solved todo {todo} in list {calendar}" : "목록 {calendar}의 할 일 {todo}을(를) 끝냄", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} 님이 목록 {calendar}의 할 일 {todo}을(를) 다시 염", - "You reopened todo {todo} in list {calendar}" : "목록 {calendar}의 할 일 {todo}을(를) 다시 염", + "{actor} created to-do {todo} in list {calendar}" : "{actor} 님이 목록 {calendar}에 할 일 {todo}을(를) 생성함", + "You created to-do {todo} in list {calendar}" : "목록 {calendar}에 할 일 {todo}을(를) 생성함", + "{actor} deleted to-do {todo} from list {calendar}" : "{actor} 님이 목록 {calendar}에서 할 일 {todo}을(를) 삭제함", + "You deleted to-do {todo} from list {calendar}" : "목록 {calendar}에서 할 일 {todo}을(를) 삭제함", + "{actor} updated to-do {todo} in list {calendar}" : "{actor} 님이 목록 {calendar}의 할 일 {todo}을(를) 업데이트함", + "You updated to-do {todo} in list {calendar}" : "목록 {calendar}의 할 일 {todo}을(를) 업데이트함", + "{actor} solved to-do {todo} in list {calendar}" : "{actor} 님이 목록 {calendar}의 할 일 {todo}을(를) 끝냄", + "You solved to-do {todo} in list {calendar}" : "목록 {calendar}의 할 일 {todo}을(를) 끝냄", + "{actor} reopened to-do {todo} in list {calendar}" : "{actor} 님이 목록 {calendar}의 할 일 {todo}을(를) 다시 엶", + "You reopened to-do {todo} in list {calendar}" : "목록 {calendar}의 할 일 {todo}을(를) 다시 엶", + "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor} 님이 할 일 {todo}을(를) 목록 {sourceCalendar}에서 목록 {targetCalendar}(으)로 옮김", + "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "할 일 {todo}을(를) 목록 {sourceCalendar}에서 목록 {targetCalendar}(으)로 옮김", "Calendar, contacts and tasks" : "달력, 연락처 및 작업", "A <strong>calendar</strong> was modified" : "<strong>달력</strong>이 수정됨", "A calendar <strong>event</strong> was modified" : "달력 <strong>행사</strong>가 수정됨", - "A calendar <strong>todo</strong> was modified" : "달력의 <strong>할 일</strong>이 수정됨", + "A calendar <strong>to-do</strong> was modified" : "달력 <strong>할 일</strong>이 수정됨", "Contact birthdays" : "연락처에 등록된 생일", - "Death of %s" : "%s의 사망", + "Death of %s" : "%s의 기일", "Calendar:" : "달력:", "Date:" : "날짜:", "Where:" : "장소:", "Description:" : "설명:", "_%n year_::_%n years_" : ["%n년"], - "_%n month_::_%n months_" : ["%d개월"], + "_%n month_::_%n months_" : ["%n개월"], "_%n day_::_%n days_" : ["%n일"], - "_%n hour_::_%n hours_" : ["%d시간"], - "_%n minute_::_%n minutes_" : ["%d분"], + "_%n hour_::_%n hours_" : ["%n시간"], + "_%n minute_::_%n minutes_" : ["%n분"], "%s (in %s)" : "%s(%s에)", "%s (%s ago)" : "%s(%s 전)", "Calendar: %s" : "달력: %s", @@ -93,13 +97,14 @@ OC.L10N.register( "{actor} shared address book {addressbook} with you" : "{actor} 님이 나와 주소록 {addressbook}을(를) 공유함", "You shared address book {addressbook} with {user}" : "{user} 님과 주소록 {addressbook}을(를) 공유함", "{actor} shared address book {addressbook} with {user}" : "{actor} 님이 {user} 님과 주소록 {addressbook}을(를) 공유함", - "{actor} unshared address book {addressbook} from you" : "{actor} 님이 주소록 {addressbook}을(를) 더이상 공유하지 않음", - "You unshared address book {addressbook} from {user}" : "{user} 님과 주소록 {addressbook}을(를) 더이상 공유하지 않음", - "{actor} unshared address book {addressbook} from {user}" : "{actor} 님이 {user} 님과 주소록 {addressbook}을(를) 더이상 공유하지 않음", + "{actor} unshared address book {addressbook} from you" : "{actor} 님이 주소록 {addressbook}의 공유를 해제함", + "You unshared address book {addressbook} from {user}" : "{user} 님과 주소록 {addressbook}의 공유를 해제함", + "{actor} unshared address book {addressbook} from {user}" : "{actor} 님이 {user} 님과 주소록 {addressbook}의 공유를 해제함", + "{actor} unshared address book {addressbook} from themselves" : "{actor} 님이 자신과 주소록 {addressbook}의 공유를 해제함", "You shared address book {addressbook} with group {group}" : "그룹 {group}과(와) 주소록 {addressbook}을(를) 공유함", "{actor} shared address book {addressbook} with group {group}" : "{actor} 님이 그룹 {group}과(와) 주소록 {addressbook}을(를) 공유함", - "You unshared address book {addressbook} from group {group}" : "그룹 {group}과(와) 주소록 {addressbook}을(를) 더이상 공유하지 않음", - "{actor} unshared address book {addressbook} from group {group}" : "{actor} 님이 그룹 {group}과(와) 주소록 {addressbook}을(를) 더이상 공유하지 않음", + "You unshared address book {addressbook} from group {group}" : "그룹 {group}과(와) 주소록 {addressbook}의 공유를 해제함", + "{actor} unshared address book {addressbook} from group {group}" : "{actor} 님이 그룹 {group}과(와) 주소록 {addressbook}의 공유를 해제함", "{actor} created contact {card} in address book {addressbook}" : "{actor} 님이 연락처 {card}을(를) 주소록 {addressbook}에 생성함", "You created contact {card} in address book {addressbook}" : "연락처 {card}을(를) 주소록 {addressbook}에 생성함", "{actor} deleted contact {card} from address book {addressbook}" : "{actor} 님이 연락처 {card}을(를) 주소록 {addressbook}에서 제거함", @@ -107,6 +112,23 @@ OC.L10N.register( "{actor} updated contact {card} in address book {addressbook}" : "{actor} 님이 주소록 {addressbook}의 연락처 {card}을(를) 갱신함", "You updated contact {card} in address book {addressbook}" : "주소록 {addressbook}의 연락처 {card}을(를) 갱신함", "A <strong>contact</strong> or <strong>address book</strong> was modified" : "<strong>연락처</strong> 또는 <strong>주소록</strong>이 변경됨", + "File is not updatable: %1$s" : "파일을 갱신할 수 없습니다: %1$s", + "Could not write to final file, canceled by hook" : "후크에 의해 취소되어 최종 파일에 쓸 수 없음", + "Could not write file contents" : "파일 내용을 쓸 수 없음", + "_%n byte_::_%n bytes_" : ["%n 바이트"], + "Error while copying file to target location (copied: %1$s, expected filesize: %2$s)" : "파일을 대상 위치로 복사하는 동안 오류 발생 (복사됨: %1$s, 예상 파일 크기: %2$s)", + "Expected filesize of %1$s but read (from Nextcloud client) and wrote (to Nextcloud storage) %2$s. Could either be a network problem on the sending side or a problem writing to the storage on the server side." : "예상 파일 크기는 %1$s이지만 읽고(Nextcloud 클라이언트에서) 및 쓴(Nextcloud 스토리지로) 크기는 %2$s입니다. 보내는 쪽의 네트워크 문제이거나 서버 쪽의 저장소에 쓰는 데 문제가 있을 수 있습니다.", + "Could not rename part file to final file, canceled by hook" : "후크에 의해 취소되어 부분 파일의 이름을 최종 파일로 바꿀 수 없음", + "Could not rename part file to final file" : "부분 파일의 이름을 최종 파일로 바꿀 수 없음", + "Failed to check file size: %1$s" : "파일 크기 확인 실패: %1$s", + "Could not open file" : "파일을 열 수 없음", + "Encryption not ready: %1$s" : "암호화가 준비되지 않음: %1$s", + "Failed to open file: %1$s" : "파일을 열 수 없음: %1$s", + "Failed to unlink: %1$s" : "파일을 삭제할 수 없음: %1$s", + "Invalid chunk name" : "잘못된 청크 이름", + "Could not rename part file assembled from chunks" : "청크에서 조합 된 부분 파일의 이름을 바꿀 수 없음", + "Failed to write file contents: %1$s" : "파일 내용을 쓸 수 없음: %1$s", + "File not found: %1$s" : "파일을 찾을 수 없음: %1$s", "System is in maintenance mode." : "시스템이 유지 관리 모드입니다.", "Upgrade needed" : "업그레이드 필요", "Your %s needs to be configured to use HTTPS in order to use CalDAV and CardDAV with iOS/macOS." : "iOS/macOS에서 CalDAV 및 CardDAV를 사용하려면 %s에서 HTTPS를 사용하도록 설정해야 합니다.", @@ -116,11 +138,20 @@ OC.L10N.register( "Tasks" : "작업", "Untitled task" : "제목없는 작업", "Completed on %s" : "%s에 완료됨", - "Due on %s" : "만료일: %s", + "Due on %s by %s" : "%s일 %s에 만료됨", + "Due on %s" : "%s에 만료됨", + "Migrated calendar (%1$s)" : "가져온 달력 (%1$s)", + "Calendars including events, details and attendees" : "이벤트, 세부 정보 및 참석자를 포함한 캘린더", "Contacts and groups" : "연락처 및 그룹", "WebDAV" : "WebDAV", "WebDAV endpoint" : "WebDAV 종단점", - "to" : "받는 사람", + "Availability" : "가능한 시간대", + "If you configure your working hours, other users will see when you are out of office when they book a meeting." : "업무 시간을 설정하면, 회의를 예약할 때 다른 사용자가 부재 중 시간을 볼 수 있습니다.", + "Time zone:" : "시간대:", + "to" : "에서", + "Delete slot" : "시간대 삭제", + "No working hours set" : "업무 시간이 설정되지 않음", + "Add slot" : "시간대 추가", "Monday" : "월요일", "Tuesday" : "화요일", "Wednesday" : "수요일", @@ -129,6 +160,9 @@ OC.L10N.register( "Saturday" : "토요일", "Sunday" : "일요일", "Save" : "저장", + "Failed to load availability" : "가능한 시간대 불러오기 실패", + "Saved availability" : "가능한 시간대를 저장함", + "Failed to save availability" : "가능한 시간대 저장 실패", "Calendar server" : "달력 서버", "Send invitations to attendees" : "참석자에게 초대장 보내기", "Automatically generate a birthday calendar" : "자동으로 생일 달력 생성", @@ -136,14 +170,29 @@ OC.L10N.register( "Hence they will not be available immediately after enabling but will show up after some time." : "생일 달력이 생성되는 데 시간이 걸릴 수도 있습니다.", "Send notifications for events" : "이벤트에 대한 알림을 전송", "Notifications are sent via background jobs, so these must occur often enough." : "알림은 배경 작업을 통해 전송되므로, 충분히 자주 표시됩니다.", + "Send reminder notifications to calendar sharees as well" : "캘린더 공유자에게도 미리 알림 보내기", + "Reminders are always sent to organizers and attendees." : "미리 알림은 주최자와 참석자에게 항상 전송됩니다.", "Enable notifications for events via push" : "이벤트에 대한 푸시 알림 활성화", "Also install the {calendarappstoreopen}Calendar app{linkclose}, or {calendardocopen}connect your desktop & mobile for syncing ↗{linkclose}." : "{calendarappstoreopen}달력 앱{linkclose}을 설치하거나 {calendardocopen}동기화할 데스크톱과 모바일 장치를 연결 ↗{linkclose}하십시오.", "Please make sure to properly set up {emailopen}the email server{linkclose}." : "{emailopen}이메일 서버{linkclose}가 올바르게 설치되어 있는지 확인하십시오..", "There was an error updating your attendance status." : "참석 상태를 업데이트하는 중 오류가 발생했습니다.", "Please contact the organizer directly." : "주최자에게 직접 연락하십시오.", "Are you accepting the invitation?" : "초대를 수락하시겠습니까?", - "Tentative" : "예정됨", + "Tentative" : "보류", + "Number of guests" : "손님의 수", "Comment" : "설명", - "Your attendance was updated successfully." : "참석 정보를 업데이트했습니다." + "Your attendance was updated successfully." : "참석 정보를 업데이트했습니다.", + "Todos" : "할 일", + "{actor} created todo {todo} in list {calendar}" : "{actor} 님이 목록 {calendar}에 할 일 {todo}을(를) 생성함", + "You created todo {todo} in list {calendar}" : "목록 {calendar}에 할 일 {todo}을(를) 생성함", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} 님이 목록 {calendar}에서 할 일 {todo}을(를) 삭제함", + "You deleted todo {todo} from list {calendar}" : "목록 {calendar}에서 할 일 {todo}을(를) 삭제함", + "{actor} updated todo {todo} in list {calendar}" : "{actor} 님이 목록 {calendar}의 할 일 {todo}을(를) 업데이트함", + "You updated todo {todo} in list {calendar}" : "목록 {calendar}의 할 일 {todo}을(를) 업데이트함", + "{actor} solved todo {todo} in list {calendar}" : "{actor} 님이 목록 {calendar}의 할 일 {todo}을(를) 끝냄", + "You solved todo {todo} in list {calendar}" : "목록 {calendar}의 할 일 {todo}을(를) 끝냄", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} 님이 목록 {calendar}의 할 일 {todo}을(를) 다시 염", + "You reopened todo {todo} in list {calendar}" : "목록 {calendar}의 할 일 {todo}을(를) 다시 염", + "A calendar <strong>todo</strong> was modified" : "달력의 <strong>할 일</strong>이 수정됨" }, "nplurals=1; plural=0;"); diff --git a/apps/dav/l10n/ko.json b/apps/dav/l10n/ko.json index e4ee28abcbc..cc9504f48cd 100644 --- a/apps/dav/l10n/ko.json +++ b/apps/dav/l10n/ko.json @@ -1,6 +1,6 @@ { "translations": { "Calendar" : "달력", - "Todos" : "할 일", + "To-dos" : "할 일", "Personal" : "개인", "{actor} created calendar {calendar}" : "{actor} 님이 달력 {calendar}을(를) 생성함", "You created calendar {calendar}" : "달력 {calendar}을(를) 생성함", @@ -23,41 +23,45 @@ "{actor} shared calendar {calendar} with group {group}" : "{actor} 님이 달력 {calendar}을(를) 그룹 {group}와(과) 공유함", "You unshared calendar {calendar} from group {group}" : "달력 {calendar}을(를) 그룹 {group}와(과) 공유하지 않음", "{actor} unshared calendar {calendar} from group {group}" : "{actor} 님이 달력 {calendar}을(를) 그룹 {group}와(과) 공유하지 않음", - "Untitled event" : "제목없는 이벤트", + "Untitled event" : "제목 없는 일정", "{actor} created event {event} in calendar {calendar}" : "{actor} 님이 행사 {event}을(를) 달력 {calendar}에 생성함", "You created event {event} in calendar {calendar}" : "행사 {event}을(를) 달력 {calendar}에 생성함", "{actor} deleted event {event} from calendar {calendar}" : "{actor} 님이 행사 {event}을(를) 달력 {calendar}에서 삭제함", "You deleted event {event} from calendar {calendar}" : "행사 {event}을(를) 달력 {calendar}에서 삭제함", "{actor} updated event {event} in calendar {calendar}" : "{actor} 님이 달력 {calendar}의 행사 {event}을(를) 업데이트함", "You updated event {event} in calendar {calendar}" : "달력 {calendar}의 행사 {event}을(를) 업데이트함", + "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{actor} 님이 행사 {event}을(를) 달력 {sourceCalendar}에서 달력 {targetCalendar}(으)로 옮김", + "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "행사 {event}을(를) 달력 {sourceCalendar}에서 달력 {targetCalendar}(으)로 옮김", "{actor} restored event {event} of calendar {calendar}" : "{actor} 님이 행사 {event}을(를) 달력 {calendar}에 복구함", "You restored event {event} of calendar {calendar}" : "행사 {event}을(를) 달력 {calendar}에 복구함", "Busy" : "바쁨", - "{actor} created todo {todo} in list {calendar}" : "{actor} 님이 목록 {calendar}에 할 일 {todo}을(를) 생성함", - "You created todo {todo} in list {calendar}" : "목록 {calendar}에 할 일 {todo}을(를) 생성함", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} 님이 목록 {calendar}에서 할 일 {todo}을(를) 삭제함", - "You deleted todo {todo} from list {calendar}" : "목록 {calendar}에서 할 일 {todo}을(를) 삭제함", - "{actor} updated todo {todo} in list {calendar}" : "{actor} 님이 목록 {calendar}의 할 일 {todo}을(를) 업데이트함", - "You updated todo {todo} in list {calendar}" : "목록 {calendar}의 할 일 {todo}을(를) 업데이트함", - "{actor} solved todo {todo} in list {calendar}" : "{actor} 님이 목록 {calendar}의 할 일 {todo}을(를) 끝냄", - "You solved todo {todo} in list {calendar}" : "목록 {calendar}의 할 일 {todo}을(를) 끝냄", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} 님이 목록 {calendar}의 할 일 {todo}을(를) 다시 염", - "You reopened todo {todo} in list {calendar}" : "목록 {calendar}의 할 일 {todo}을(를) 다시 염", + "{actor} created to-do {todo} in list {calendar}" : "{actor} 님이 목록 {calendar}에 할 일 {todo}을(를) 생성함", + "You created to-do {todo} in list {calendar}" : "목록 {calendar}에 할 일 {todo}을(를) 생성함", + "{actor} deleted to-do {todo} from list {calendar}" : "{actor} 님이 목록 {calendar}에서 할 일 {todo}을(를) 삭제함", + "You deleted to-do {todo} from list {calendar}" : "목록 {calendar}에서 할 일 {todo}을(를) 삭제함", + "{actor} updated to-do {todo} in list {calendar}" : "{actor} 님이 목록 {calendar}의 할 일 {todo}을(를) 업데이트함", + "You updated to-do {todo} in list {calendar}" : "목록 {calendar}의 할 일 {todo}을(를) 업데이트함", + "{actor} solved to-do {todo} in list {calendar}" : "{actor} 님이 목록 {calendar}의 할 일 {todo}을(를) 끝냄", + "You solved to-do {todo} in list {calendar}" : "목록 {calendar}의 할 일 {todo}을(를) 끝냄", + "{actor} reopened to-do {todo} in list {calendar}" : "{actor} 님이 목록 {calendar}의 할 일 {todo}을(를) 다시 엶", + "You reopened to-do {todo} in list {calendar}" : "목록 {calendar}의 할 일 {todo}을(를) 다시 엶", + "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor} 님이 할 일 {todo}을(를) 목록 {sourceCalendar}에서 목록 {targetCalendar}(으)로 옮김", + "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "할 일 {todo}을(를) 목록 {sourceCalendar}에서 목록 {targetCalendar}(으)로 옮김", "Calendar, contacts and tasks" : "달력, 연락처 및 작업", "A <strong>calendar</strong> was modified" : "<strong>달력</strong>이 수정됨", "A calendar <strong>event</strong> was modified" : "달력 <strong>행사</strong>가 수정됨", - "A calendar <strong>todo</strong> was modified" : "달력의 <strong>할 일</strong>이 수정됨", + "A calendar <strong>to-do</strong> was modified" : "달력 <strong>할 일</strong>이 수정됨", "Contact birthdays" : "연락처에 등록된 생일", - "Death of %s" : "%s의 사망", + "Death of %s" : "%s의 기일", "Calendar:" : "달력:", "Date:" : "날짜:", "Where:" : "장소:", "Description:" : "설명:", "_%n year_::_%n years_" : ["%n년"], - "_%n month_::_%n months_" : ["%d개월"], + "_%n month_::_%n months_" : ["%n개월"], "_%n day_::_%n days_" : ["%n일"], - "_%n hour_::_%n hours_" : ["%d시간"], - "_%n minute_::_%n minutes_" : ["%d분"], + "_%n hour_::_%n hours_" : ["%n시간"], + "_%n minute_::_%n minutes_" : ["%n분"], "%s (in %s)" : "%s(%s에)", "%s (%s ago)" : "%s(%s 전)", "Calendar: %s" : "달력: %s", @@ -91,13 +95,14 @@ "{actor} shared address book {addressbook} with you" : "{actor} 님이 나와 주소록 {addressbook}을(를) 공유함", "You shared address book {addressbook} with {user}" : "{user} 님과 주소록 {addressbook}을(를) 공유함", "{actor} shared address book {addressbook} with {user}" : "{actor} 님이 {user} 님과 주소록 {addressbook}을(를) 공유함", - "{actor} unshared address book {addressbook} from you" : "{actor} 님이 주소록 {addressbook}을(를) 더이상 공유하지 않음", - "You unshared address book {addressbook} from {user}" : "{user} 님과 주소록 {addressbook}을(를) 더이상 공유하지 않음", - "{actor} unshared address book {addressbook} from {user}" : "{actor} 님이 {user} 님과 주소록 {addressbook}을(를) 더이상 공유하지 않음", + "{actor} unshared address book {addressbook} from you" : "{actor} 님이 주소록 {addressbook}의 공유를 해제함", + "You unshared address book {addressbook} from {user}" : "{user} 님과 주소록 {addressbook}의 공유를 해제함", + "{actor} unshared address book {addressbook} from {user}" : "{actor} 님이 {user} 님과 주소록 {addressbook}의 공유를 해제함", + "{actor} unshared address book {addressbook} from themselves" : "{actor} 님이 자신과 주소록 {addressbook}의 공유를 해제함", "You shared address book {addressbook} with group {group}" : "그룹 {group}과(와) 주소록 {addressbook}을(를) 공유함", "{actor} shared address book {addressbook} with group {group}" : "{actor} 님이 그룹 {group}과(와) 주소록 {addressbook}을(를) 공유함", - "You unshared address book {addressbook} from group {group}" : "그룹 {group}과(와) 주소록 {addressbook}을(를) 더이상 공유하지 않음", - "{actor} unshared address book {addressbook} from group {group}" : "{actor} 님이 그룹 {group}과(와) 주소록 {addressbook}을(를) 더이상 공유하지 않음", + "You unshared address book {addressbook} from group {group}" : "그룹 {group}과(와) 주소록 {addressbook}의 공유를 해제함", + "{actor} unshared address book {addressbook} from group {group}" : "{actor} 님이 그룹 {group}과(와) 주소록 {addressbook}의 공유를 해제함", "{actor} created contact {card} in address book {addressbook}" : "{actor} 님이 연락처 {card}을(를) 주소록 {addressbook}에 생성함", "You created contact {card} in address book {addressbook}" : "연락처 {card}을(를) 주소록 {addressbook}에 생성함", "{actor} deleted contact {card} from address book {addressbook}" : "{actor} 님이 연락처 {card}을(를) 주소록 {addressbook}에서 제거함", @@ -105,6 +110,23 @@ "{actor} updated contact {card} in address book {addressbook}" : "{actor} 님이 주소록 {addressbook}의 연락처 {card}을(를) 갱신함", "You updated contact {card} in address book {addressbook}" : "주소록 {addressbook}의 연락처 {card}을(를) 갱신함", "A <strong>contact</strong> or <strong>address book</strong> was modified" : "<strong>연락처</strong> 또는 <strong>주소록</strong>이 변경됨", + "File is not updatable: %1$s" : "파일을 갱신할 수 없습니다: %1$s", + "Could not write to final file, canceled by hook" : "후크에 의해 취소되어 최종 파일에 쓸 수 없음", + "Could not write file contents" : "파일 내용을 쓸 수 없음", + "_%n byte_::_%n bytes_" : ["%n 바이트"], + "Error while copying file to target location (copied: %1$s, expected filesize: %2$s)" : "파일을 대상 위치로 복사하는 동안 오류 발생 (복사됨: %1$s, 예상 파일 크기: %2$s)", + "Expected filesize of %1$s but read (from Nextcloud client) and wrote (to Nextcloud storage) %2$s. Could either be a network problem on the sending side or a problem writing to the storage on the server side." : "예상 파일 크기는 %1$s이지만 읽고(Nextcloud 클라이언트에서) 및 쓴(Nextcloud 스토리지로) 크기는 %2$s입니다. 보내는 쪽의 네트워크 문제이거나 서버 쪽의 저장소에 쓰는 데 문제가 있을 수 있습니다.", + "Could not rename part file to final file, canceled by hook" : "후크에 의해 취소되어 부분 파일의 이름을 최종 파일로 바꿀 수 없음", + "Could not rename part file to final file" : "부분 파일의 이름을 최종 파일로 바꿀 수 없음", + "Failed to check file size: %1$s" : "파일 크기 확인 실패: %1$s", + "Could not open file" : "파일을 열 수 없음", + "Encryption not ready: %1$s" : "암호화가 준비되지 않음: %1$s", + "Failed to open file: %1$s" : "파일을 열 수 없음: %1$s", + "Failed to unlink: %1$s" : "파일을 삭제할 수 없음: %1$s", + "Invalid chunk name" : "잘못된 청크 이름", + "Could not rename part file assembled from chunks" : "청크에서 조합 된 부분 파일의 이름을 바꿀 수 없음", + "Failed to write file contents: %1$s" : "파일 내용을 쓸 수 없음: %1$s", + "File not found: %1$s" : "파일을 찾을 수 없음: %1$s", "System is in maintenance mode." : "시스템이 유지 관리 모드입니다.", "Upgrade needed" : "업그레이드 필요", "Your %s needs to be configured to use HTTPS in order to use CalDAV and CardDAV with iOS/macOS." : "iOS/macOS에서 CalDAV 및 CardDAV를 사용하려면 %s에서 HTTPS를 사용하도록 설정해야 합니다.", @@ -114,11 +136,20 @@ "Tasks" : "작업", "Untitled task" : "제목없는 작업", "Completed on %s" : "%s에 완료됨", - "Due on %s" : "만료일: %s", + "Due on %s by %s" : "%s일 %s에 만료됨", + "Due on %s" : "%s에 만료됨", + "Migrated calendar (%1$s)" : "가져온 달력 (%1$s)", + "Calendars including events, details and attendees" : "이벤트, 세부 정보 및 참석자를 포함한 캘린더", "Contacts and groups" : "연락처 및 그룹", "WebDAV" : "WebDAV", "WebDAV endpoint" : "WebDAV 종단점", - "to" : "받는 사람", + "Availability" : "가능한 시간대", + "If you configure your working hours, other users will see when you are out of office when they book a meeting." : "업무 시간을 설정하면, 회의를 예약할 때 다른 사용자가 부재 중 시간을 볼 수 있습니다.", + "Time zone:" : "시간대:", + "to" : "에서", + "Delete slot" : "시간대 삭제", + "No working hours set" : "업무 시간이 설정되지 않음", + "Add slot" : "시간대 추가", "Monday" : "월요일", "Tuesday" : "화요일", "Wednesday" : "수요일", @@ -127,6 +158,9 @@ "Saturday" : "토요일", "Sunday" : "일요일", "Save" : "저장", + "Failed to load availability" : "가능한 시간대 불러오기 실패", + "Saved availability" : "가능한 시간대를 저장함", + "Failed to save availability" : "가능한 시간대 저장 실패", "Calendar server" : "달력 서버", "Send invitations to attendees" : "참석자에게 초대장 보내기", "Automatically generate a birthday calendar" : "자동으로 생일 달력 생성", @@ -134,14 +168,29 @@ "Hence they will not be available immediately after enabling but will show up after some time." : "생일 달력이 생성되는 데 시간이 걸릴 수도 있습니다.", "Send notifications for events" : "이벤트에 대한 알림을 전송", "Notifications are sent via background jobs, so these must occur often enough." : "알림은 배경 작업을 통해 전송되므로, 충분히 자주 표시됩니다.", + "Send reminder notifications to calendar sharees as well" : "캘린더 공유자에게도 미리 알림 보내기", + "Reminders are always sent to organizers and attendees." : "미리 알림은 주최자와 참석자에게 항상 전송됩니다.", "Enable notifications for events via push" : "이벤트에 대한 푸시 알림 활성화", "Also install the {calendarappstoreopen}Calendar app{linkclose}, or {calendardocopen}connect your desktop & mobile for syncing ↗{linkclose}." : "{calendarappstoreopen}달력 앱{linkclose}을 설치하거나 {calendardocopen}동기화할 데스크톱과 모바일 장치를 연결 ↗{linkclose}하십시오.", "Please make sure to properly set up {emailopen}the email server{linkclose}." : "{emailopen}이메일 서버{linkclose}가 올바르게 설치되어 있는지 확인하십시오..", "There was an error updating your attendance status." : "참석 상태를 업데이트하는 중 오류가 발생했습니다.", "Please contact the organizer directly." : "주최자에게 직접 연락하십시오.", "Are you accepting the invitation?" : "초대를 수락하시겠습니까?", - "Tentative" : "예정됨", + "Tentative" : "보류", + "Number of guests" : "손님의 수", "Comment" : "설명", - "Your attendance was updated successfully." : "참석 정보를 업데이트했습니다." + "Your attendance was updated successfully." : "참석 정보를 업데이트했습니다.", + "Todos" : "할 일", + "{actor} created todo {todo} in list {calendar}" : "{actor} 님이 목록 {calendar}에 할 일 {todo}을(를) 생성함", + "You created todo {todo} in list {calendar}" : "목록 {calendar}에 할 일 {todo}을(를) 생성함", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} 님이 목록 {calendar}에서 할 일 {todo}을(를) 삭제함", + "You deleted todo {todo} from list {calendar}" : "목록 {calendar}에서 할 일 {todo}을(를) 삭제함", + "{actor} updated todo {todo} in list {calendar}" : "{actor} 님이 목록 {calendar}의 할 일 {todo}을(를) 업데이트함", + "You updated todo {todo} in list {calendar}" : "목록 {calendar}의 할 일 {todo}을(를) 업데이트함", + "{actor} solved todo {todo} in list {calendar}" : "{actor} 님이 목록 {calendar}의 할 일 {todo}을(를) 끝냄", + "You solved todo {todo} in list {calendar}" : "목록 {calendar}의 할 일 {todo}을(를) 끝냄", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} 님이 목록 {calendar}의 할 일 {todo}을(를) 다시 염", + "You reopened todo {todo} in list {calendar}" : "목록 {calendar}의 할 일 {todo}을(를) 다시 염", + "A calendar <strong>todo</strong> was modified" : "달력의 <strong>할 일</strong>이 수정됨" },"pluralForm" :"nplurals=1; plural=0;" }
\ No newline at end of file diff --git a/apps/dav/l10n/lt_LT.js b/apps/dav/l10n/lt_LT.js index 1b060dbd492..f1462487e40 100644 --- a/apps/dav/l10n/lt_LT.js +++ b/apps/dav/l10n/lt_LT.js @@ -2,7 +2,6 @@ OC.L10N.register( "dav", { "Calendar" : "Kalendorius", - "Todos" : "Užduotys", "Personal" : "Asmeniniai", "{actor} created calendar {calendar}" : "{actor} sukūrė kalendorių {calendar}", "You created calendar {calendar}" : "Jūs sukūrėte kalendorių {calendar}", @@ -35,20 +34,9 @@ OC.L10N.register( "{actor} restored event {event} of calendar {calendar}" : "{actor} kalendoriuje {calendar} atkūrė įvykį {event}", "You restored event {event} of calendar {calendar}" : "Jūs kalendoriuje {calendar} atkūrėte įvykį {event}", "Busy" : "Užimtas laikas", - "{actor} created todo {todo} in list {calendar}" : "{actor} sąraše {calendar} sukūrė užduotį {todo}", - "You created todo {todo} in list {calendar}" : "Jūs sąraše {calendar} sukūrėte užduotį {todo}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} iš sąrašo {calendar} ištrynė užduotį {todo}", - "You deleted todo {todo} from list {calendar}" : "Jūs iš sąrašo {calendar} ištrynėte užduotį {todo}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} sąraše {calendar} atnaujino užduotį {todo}", - "You updated todo {todo} in list {calendar}" : "Jūs sąraše {calendar} atnaujinote užduotį {todo}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} sąraše {calendar} išsprendė užduotį {todo}", - "You solved todo {todo} in list {calendar}" : "Jūs sąraše {calendar} išsprendėte užduotį {todo}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} sąraše {calendar} vėl pradėjo užduotį {todo}", - "You reopened todo {todo} in list {calendar}" : "Jūs sąraše {calendar} vėl pradėjote užduotį {todo}", "Calendar, contacts and tasks" : "Kalendorius, adresatai ir užduotys", "A <strong>calendar</strong> was modified" : "<strong>Kalendorius</strong> buvo modifikuotas", "A calendar <strong>event</strong> was modified" : "Kalendoriaus <strong>įvykis</strong> buvo modifikuotas", - "A calendar <strong>todo</strong> was modified" : "Kalendoriaus <strong>užduotis</strong> buvo modifikuota", "Contact birthdays" : "Adresatų gimtadieniai", "Calendar:" : "Kalendorius:", "Date:" : "Data:", @@ -121,6 +109,18 @@ OC.L10N.register( "Are you accepting the invitation?" : "Ar priimate pakvietimą?", "Tentative" : "Preliminarus", "Number of guests" : "Svečių skaičius", - "Comment" : "Komentaras" + "Comment" : "Komentaras", + "Todos" : "Užduotys", + "{actor} created todo {todo} in list {calendar}" : "{actor} sąraše {calendar} sukūrė užduotį {todo}", + "You created todo {todo} in list {calendar}" : "Jūs sąraše {calendar} sukūrėte užduotį {todo}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} iš sąrašo {calendar} ištrynė užduotį {todo}", + "You deleted todo {todo} from list {calendar}" : "Jūs iš sąrašo {calendar} ištrynėte užduotį {todo}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} sąraše {calendar} atnaujino užduotį {todo}", + "You updated todo {todo} in list {calendar}" : "Jūs sąraše {calendar} atnaujinote užduotį {todo}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} sąraše {calendar} išsprendė užduotį {todo}", + "You solved todo {todo} in list {calendar}" : "Jūs sąraše {calendar} išsprendėte užduotį {todo}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} sąraše {calendar} vėl pradėjo užduotį {todo}", + "You reopened todo {todo} in list {calendar}" : "Jūs sąraše {calendar} vėl pradėjote užduotį {todo}", + "A calendar <strong>todo</strong> was modified" : "Kalendoriaus <strong>užduotis</strong> buvo modifikuota" }, "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/apps/dav/l10n/lt_LT.json b/apps/dav/l10n/lt_LT.json index 0b6d8f25c1c..0407e342c5c 100644 --- a/apps/dav/l10n/lt_LT.json +++ b/apps/dav/l10n/lt_LT.json @@ -1,6 +1,5 @@ { "translations": { "Calendar" : "Kalendorius", - "Todos" : "Užduotys", "Personal" : "Asmeniniai", "{actor} created calendar {calendar}" : "{actor} sukūrė kalendorių {calendar}", "You created calendar {calendar}" : "Jūs sukūrėte kalendorių {calendar}", @@ -33,20 +32,9 @@ "{actor} restored event {event} of calendar {calendar}" : "{actor} kalendoriuje {calendar} atkūrė įvykį {event}", "You restored event {event} of calendar {calendar}" : "Jūs kalendoriuje {calendar} atkūrėte įvykį {event}", "Busy" : "Užimtas laikas", - "{actor} created todo {todo} in list {calendar}" : "{actor} sąraše {calendar} sukūrė užduotį {todo}", - "You created todo {todo} in list {calendar}" : "Jūs sąraše {calendar} sukūrėte užduotį {todo}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} iš sąrašo {calendar} ištrynė užduotį {todo}", - "You deleted todo {todo} from list {calendar}" : "Jūs iš sąrašo {calendar} ištrynėte užduotį {todo}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} sąraše {calendar} atnaujino užduotį {todo}", - "You updated todo {todo} in list {calendar}" : "Jūs sąraše {calendar} atnaujinote užduotį {todo}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} sąraše {calendar} išsprendė užduotį {todo}", - "You solved todo {todo} in list {calendar}" : "Jūs sąraše {calendar} išsprendėte užduotį {todo}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} sąraše {calendar} vėl pradėjo užduotį {todo}", - "You reopened todo {todo} in list {calendar}" : "Jūs sąraše {calendar} vėl pradėjote užduotį {todo}", "Calendar, contacts and tasks" : "Kalendorius, adresatai ir užduotys", "A <strong>calendar</strong> was modified" : "<strong>Kalendorius</strong> buvo modifikuotas", "A calendar <strong>event</strong> was modified" : "Kalendoriaus <strong>įvykis</strong> buvo modifikuotas", - "A calendar <strong>todo</strong> was modified" : "Kalendoriaus <strong>užduotis</strong> buvo modifikuota", "Contact birthdays" : "Adresatų gimtadieniai", "Calendar:" : "Kalendorius:", "Date:" : "Data:", @@ -119,6 +107,18 @@ "Are you accepting the invitation?" : "Ar priimate pakvietimą?", "Tentative" : "Preliminarus", "Number of guests" : "Svečių skaičius", - "Comment" : "Komentaras" + "Comment" : "Komentaras", + "Todos" : "Užduotys", + "{actor} created todo {todo} in list {calendar}" : "{actor} sąraše {calendar} sukūrė užduotį {todo}", + "You created todo {todo} in list {calendar}" : "Jūs sąraše {calendar} sukūrėte užduotį {todo}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} iš sąrašo {calendar} ištrynė užduotį {todo}", + "You deleted todo {todo} from list {calendar}" : "Jūs iš sąrašo {calendar} ištrynėte užduotį {todo}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} sąraše {calendar} atnaujino užduotį {todo}", + "You updated todo {todo} in list {calendar}" : "Jūs sąraše {calendar} atnaujinote užduotį {todo}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} sąraše {calendar} išsprendė užduotį {todo}", + "You solved todo {todo} in list {calendar}" : "Jūs sąraše {calendar} išsprendėte užduotį {todo}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} sąraše {calendar} vėl pradėjo užduotį {todo}", + "You reopened todo {todo} in list {calendar}" : "Jūs sąraše {calendar} vėl pradėjote užduotį {todo}", + "A calendar <strong>todo</strong> was modified" : "Kalendoriaus <strong>užduotis</strong> buvo modifikuota" },"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/apps/dav/l10n/mk.js b/apps/dav/l10n/mk.js index d7f9310f519..fe16669120e 100644 --- a/apps/dav/l10n/mk.js +++ b/apps/dav/l10n/mk.js @@ -2,7 +2,6 @@ OC.L10N.register( "dav", { "Calendar" : "Календар", - "Todos" : "Задачи", "Personal" : "Лично", "{actor} created calendar {calendar}" : "{actor} креираше календар {calendar}", "You created calendar {calendar}" : "Креиравте календар {calendar}", @@ -10,6 +9,8 @@ OC.L10N.register( "You deleted calendar {calendar}" : "Избришавте календар {calendar}", "{actor} updated calendar {calendar}" : "{actor} ажурираше календар {calendar}", "You updated calendar {calendar}" : "Ажуриравте календар {calendar}", + "{actor} restored calendar {calendar}" : "{actor} врати календар {calendar}", + "You restored calendar {calendar}" : "Вративте календар {calendar}", "You shared calendar {calendar} as public link" : "Споделивте календар {calendar} како јавен линк", "You removed public link for calendar {calendar}" : "Отстранивте јавен линк за календар {calendar}", "{actor} shared calendar {calendar} with you" : "{actor} сподели календар {calendar} со вас", @@ -30,23 +31,27 @@ OC.L10N.register( "You deleted event {event} from calendar {calendar}" : "Избришавте настан {event} од календар {calendar}", "{actor} updated event {event} in calendar {calendar}" : "{actor} ажурираше настан {event} во календар {calendar}", "You updated event {event} in calendar {calendar}" : "Ажуриравте настан {event} во календар {calendar}", + "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{actor} премести настан {event} од календар {sourceCalendar} во календар {targetCalendar}", + "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "Преместивте настан {event} од календар {sourceCalendar} во календар {targetCalendar}", "{actor} restored event {event} of calendar {calendar}" : "{actor} врати настан {event} во календарот {calendar}", "You restored event {event} of calendar {calendar}" : "Вративте настан {event} во календарот {calendar}", "Busy" : "Зафатен", - "{actor} created todo {todo} in list {calendar}" : "{actor} креираше задолжение {todo} во листата {calendar}", - "You created todo {todo} in list {calendar}" : "Креиравте задолжение {todo} во листата {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} избриша задолжение {todo} од листата {calendar}", - "You deleted todo {todo} from list {calendar}" : "Избришавте задолжение {todo} од листата {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} ажурираше задолжение {todo} во листата {calendar}", - "You updated todo {todo} in list {calendar}" : "Ажуриравте задолжение {todo} во листата {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} го реши задолжението {todo} во листата {calendar}", - "You solved todo {todo} in list {calendar}" : "Го решивте задолжението {todo} во листата {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} повторно го отвори задолжението {todo} во листата {calendar}", - "You reopened todo {todo} in list {calendar}" : "Повторно го отворивте задолжението {todo} во листата {calendar}", + "{actor} created to-do {todo} in list {calendar}" : "{actor} креираше задолжение {todo} во листата {calendar}", + "You created to-do {todo} in list {calendar}" : "Креиравте задолжение {todo} во листата {calendar}", + "{actor} deleted to-do {todo} from list {calendar}" : "{actor} избриша задолжение {todo} од листата {calendar}", + "You deleted to-do {todo} from list {calendar}" : "Избришавте задолжение {todo} од листата {calendar}", + "{actor} updated to-do {todo} in list {calendar}" : "{actor} ажурираше задолжение {todo} во листата {calendar}", + "You updated to-do {todo} in list {calendar}" : "Ажуриравте задолжение {todo} во листата {calendar}", + "{actor} solved to-do {todo} in list {calendar}" : "{actor} го заврши задолжението {todo} во листата {calendar}", + "You solved to-do {todo} in list {calendar}" : "Го завршивте задолжението {todo} во листата {calendar}", + "{actor} reopened to-do {todo} in list {calendar}" : "{actor} повторно го отвори задолжението {todo} во листата {calendar}", + "You reopened to-do {todo} in list {calendar}" : "Повторно го отворивте задолжението {todo} во листата {calendar}", + "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor} премести задолжение {todo} од листа {sourceCalendar} во листа {targetCalendar}", + "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "Преместивте задолжение {todo} од листа {sourceCalendar} во листа {targetCalendar}", "Calendar, contacts and tasks" : "Календар, контакти и задачи", "A <strong>calendar</strong> was modified" : "<strong>Календарот</strong> е променет", "A calendar <strong>event</strong> was modified" : "Изменет е <strong>настан</strong> во календарот", - "A calendar <strong>todo</strong> was modified" : "Изменета е <strong>задача</strong> во календарот", + "A calendar <strong>to-do</strong> was modified" : "Изменета е <strong>задача</strong> во календарот", "Contact birthdays" : "Родендени на контактите", "Death of %s" : "Смрт на %s", "Calendar:" : "Календар:", @@ -82,6 +87,22 @@ OC.L10N.register( "More options …" : "Повеќе опции ...", "More options at %s" : "Повеќе опции на %s", "Contacts" : "Контакти", + "{actor} created address book {addressbook}" : "{actor} креираше адресар {addressbook}", + "You created address book {addressbook}" : "Креиравте адресар {addressbook}", + "{actor} deleted address book {addressbook}" : "{actor} избриша адресар {addressbook}", + "You deleted address book {addressbook}" : "Избришавте адресар {addressbook}", + "{actor} updated address book {addressbook}" : "{actor} ажурирање адресар {addressbook}", + "You updated address book {addressbook}" : "Ажуриравте {addressbook}", + "{actor} shared address book {addressbook} with you" : "{actor} сподели адресар {addressbook} со вас", + "You shared address book {addressbook} with {user}" : "Споделивте адресар {addressbook} со {user}", + "{actor} shared address book {addressbook} with {user}" : "{actor} сподели адресар {addressbook} со {user}", + "{actor} unshared address book {addressbook} from you" : "{actor} не го споделува адресар {addressbook} со вас", + "You unshared address book {addressbook} from {user}" : "Не го споделиувате адресар {addressbook} со {user}", + "{actor} unshared address book {addressbook} from {user}" : "{actor} не го споделува адресар {addressbook} со {user}", + "{actor} unshared address book {addressbook} from themselves" : "{actor} не го споделува адресар {addressbook} со себе", + "A <strong>contact</strong> or <strong>address book</strong> was modified" : "<strong>Контракт</strong> или <strong>адресар</strong> е променет", + "_%n byte_::_%n bytes_" : ["%n бајт","%n бајти"], + "File not found: %1$s" : "Датотеката не е пронајдена: %1$s", "System is in maintenance mode." : "Системот е во мод за одржување.", "Upgrade needed" : "Потребна е надградба", "Your %s needs to be configured to use HTTPS in order to use CalDAV and CardDAV with iOS/macOS." : "Вашиот %s треба да биде конфигуриран за да користи HTTPS за да може да се користи CalDAV и CardDAV на iOS/macOS.", @@ -97,8 +118,11 @@ OC.L10N.register( "WebDAV" : "WebDAV", "WebDAV endpoint" : "WebDAV крајна точка", "Availability" : "Достапност", + "If you configure your working hours, other users will see when you are out of office when they book a meeting." : "Ако ги поставите работните часови, другите корисници ќе можат да видат кога сте слободни за да можат да закажат состанок.", + "Time zone:" : "Временска зона:", "to" : "до", "Delete slot" : "Избриши слот", + "No working hours set" : "Не се поставени работни часови", "Add slot" : "Додади слот", "Monday" : "Понеделник", "Tuesday" : "Вторник", @@ -124,6 +148,18 @@ OC.L10N.register( "Tentative" : "Прелиминарно", "Number of guests" : "Број на гости", "Comment" : "Коментар", - "Your attendance was updated successfully." : "Вашето присуство е успешно ажурирано." + "Your attendance was updated successfully." : "Вашето присуство е успешно ажурирано.", + "Todos" : "Задачи", + "{actor} created todo {todo} in list {calendar}" : "{actor} креираше задолжение {todo} во листата {calendar}", + "You created todo {todo} in list {calendar}" : "Креиравте задолжение {todo} во листата {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} избриша задолжение {todo} од листата {calendar}", + "You deleted todo {todo} from list {calendar}" : "Избришавте задолжение {todo} од листата {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} ажурираше задолжение {todo} во листата {calendar}", + "You updated todo {todo} in list {calendar}" : "Ажуриравте задолжение {todo} во листата {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} го реши задолжението {todo} во листата {calendar}", + "You solved todo {todo} in list {calendar}" : "Го решивте задолжението {todo} во листата {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} повторно го отвори задолжението {todo} во листата {calendar}", + "You reopened todo {todo} in list {calendar}" : "Повторно го отворивте задолжението {todo} во листата {calendar}", + "A calendar <strong>todo</strong> was modified" : "Изменета е <strong>задача</strong> во календарот" }, "nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;"); diff --git a/apps/dav/l10n/mk.json b/apps/dav/l10n/mk.json index f37a3724984..7a179fab5a7 100644 --- a/apps/dav/l10n/mk.json +++ b/apps/dav/l10n/mk.json @@ -1,6 +1,5 @@ { "translations": { "Calendar" : "Календар", - "Todos" : "Задачи", "Personal" : "Лично", "{actor} created calendar {calendar}" : "{actor} креираше календар {calendar}", "You created calendar {calendar}" : "Креиравте календар {calendar}", @@ -8,6 +7,8 @@ "You deleted calendar {calendar}" : "Избришавте календар {calendar}", "{actor} updated calendar {calendar}" : "{actor} ажурираше календар {calendar}", "You updated calendar {calendar}" : "Ажуриравте календар {calendar}", + "{actor} restored calendar {calendar}" : "{actor} врати календар {calendar}", + "You restored calendar {calendar}" : "Вративте календар {calendar}", "You shared calendar {calendar} as public link" : "Споделивте календар {calendar} како јавен линк", "You removed public link for calendar {calendar}" : "Отстранивте јавен линк за календар {calendar}", "{actor} shared calendar {calendar} with you" : "{actor} сподели календар {calendar} со вас", @@ -28,23 +29,27 @@ "You deleted event {event} from calendar {calendar}" : "Избришавте настан {event} од календар {calendar}", "{actor} updated event {event} in calendar {calendar}" : "{actor} ажурираше настан {event} во календар {calendar}", "You updated event {event} in calendar {calendar}" : "Ажуриравте настан {event} во календар {calendar}", + "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{actor} премести настан {event} од календар {sourceCalendar} во календар {targetCalendar}", + "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "Преместивте настан {event} од календар {sourceCalendar} во календар {targetCalendar}", "{actor} restored event {event} of calendar {calendar}" : "{actor} врати настан {event} во календарот {calendar}", "You restored event {event} of calendar {calendar}" : "Вративте настан {event} во календарот {calendar}", "Busy" : "Зафатен", - "{actor} created todo {todo} in list {calendar}" : "{actor} креираше задолжение {todo} во листата {calendar}", - "You created todo {todo} in list {calendar}" : "Креиравте задолжение {todo} во листата {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} избриша задолжение {todo} од листата {calendar}", - "You deleted todo {todo} from list {calendar}" : "Избришавте задолжение {todo} од листата {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} ажурираше задолжение {todo} во листата {calendar}", - "You updated todo {todo} in list {calendar}" : "Ажуриравте задолжение {todo} во листата {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} го реши задолжението {todo} во листата {calendar}", - "You solved todo {todo} in list {calendar}" : "Го решивте задолжението {todo} во листата {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} повторно го отвори задолжението {todo} во листата {calendar}", - "You reopened todo {todo} in list {calendar}" : "Повторно го отворивте задолжението {todo} во листата {calendar}", + "{actor} created to-do {todo} in list {calendar}" : "{actor} креираше задолжение {todo} во листата {calendar}", + "You created to-do {todo} in list {calendar}" : "Креиравте задолжение {todo} во листата {calendar}", + "{actor} deleted to-do {todo} from list {calendar}" : "{actor} избриша задолжение {todo} од листата {calendar}", + "You deleted to-do {todo} from list {calendar}" : "Избришавте задолжение {todo} од листата {calendar}", + "{actor} updated to-do {todo} in list {calendar}" : "{actor} ажурираше задолжение {todo} во листата {calendar}", + "You updated to-do {todo} in list {calendar}" : "Ажуриравте задолжение {todo} во листата {calendar}", + "{actor} solved to-do {todo} in list {calendar}" : "{actor} го заврши задолжението {todo} во листата {calendar}", + "You solved to-do {todo} in list {calendar}" : "Го завршивте задолжението {todo} во листата {calendar}", + "{actor} reopened to-do {todo} in list {calendar}" : "{actor} повторно го отвори задолжението {todo} во листата {calendar}", + "You reopened to-do {todo} in list {calendar}" : "Повторно го отворивте задолжението {todo} во листата {calendar}", + "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor} премести задолжение {todo} од листа {sourceCalendar} во листа {targetCalendar}", + "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "Преместивте задолжение {todo} од листа {sourceCalendar} во листа {targetCalendar}", "Calendar, contacts and tasks" : "Календар, контакти и задачи", "A <strong>calendar</strong> was modified" : "<strong>Календарот</strong> е променет", "A calendar <strong>event</strong> was modified" : "Изменет е <strong>настан</strong> во календарот", - "A calendar <strong>todo</strong> was modified" : "Изменета е <strong>задача</strong> во календарот", + "A calendar <strong>to-do</strong> was modified" : "Изменета е <strong>задача</strong> во календарот", "Contact birthdays" : "Родендени на контактите", "Death of %s" : "Смрт на %s", "Calendar:" : "Календар:", @@ -80,6 +85,22 @@ "More options …" : "Повеќе опции ...", "More options at %s" : "Повеќе опции на %s", "Contacts" : "Контакти", + "{actor} created address book {addressbook}" : "{actor} креираше адресар {addressbook}", + "You created address book {addressbook}" : "Креиравте адресар {addressbook}", + "{actor} deleted address book {addressbook}" : "{actor} избриша адресар {addressbook}", + "You deleted address book {addressbook}" : "Избришавте адресар {addressbook}", + "{actor} updated address book {addressbook}" : "{actor} ажурирање адресар {addressbook}", + "You updated address book {addressbook}" : "Ажуриравте {addressbook}", + "{actor} shared address book {addressbook} with you" : "{actor} сподели адресар {addressbook} со вас", + "You shared address book {addressbook} with {user}" : "Споделивте адресар {addressbook} со {user}", + "{actor} shared address book {addressbook} with {user}" : "{actor} сподели адресар {addressbook} со {user}", + "{actor} unshared address book {addressbook} from you" : "{actor} не го споделува адресар {addressbook} со вас", + "You unshared address book {addressbook} from {user}" : "Не го споделиувате адресар {addressbook} со {user}", + "{actor} unshared address book {addressbook} from {user}" : "{actor} не го споделува адресар {addressbook} со {user}", + "{actor} unshared address book {addressbook} from themselves" : "{actor} не го споделува адресар {addressbook} со себе", + "A <strong>contact</strong> or <strong>address book</strong> was modified" : "<strong>Контракт</strong> или <strong>адресар</strong> е променет", + "_%n byte_::_%n bytes_" : ["%n бајт","%n бајти"], + "File not found: %1$s" : "Датотеката не е пронајдена: %1$s", "System is in maintenance mode." : "Системот е во мод за одржување.", "Upgrade needed" : "Потребна е надградба", "Your %s needs to be configured to use HTTPS in order to use CalDAV and CardDAV with iOS/macOS." : "Вашиот %s треба да биде конфигуриран за да користи HTTPS за да може да се користи CalDAV и CardDAV на iOS/macOS.", @@ -95,8 +116,11 @@ "WebDAV" : "WebDAV", "WebDAV endpoint" : "WebDAV крајна точка", "Availability" : "Достапност", + "If you configure your working hours, other users will see when you are out of office when they book a meeting." : "Ако ги поставите работните часови, другите корисници ќе можат да видат кога сте слободни за да можат да закажат состанок.", + "Time zone:" : "Временска зона:", "to" : "до", "Delete slot" : "Избриши слот", + "No working hours set" : "Не се поставени работни часови", "Add slot" : "Додади слот", "Monday" : "Понеделник", "Tuesday" : "Вторник", @@ -122,6 +146,18 @@ "Tentative" : "Прелиминарно", "Number of guests" : "Број на гости", "Comment" : "Коментар", - "Your attendance was updated successfully." : "Вашето присуство е успешно ажурирано." + "Your attendance was updated successfully." : "Вашето присуство е успешно ажурирано.", + "Todos" : "Задачи", + "{actor} created todo {todo} in list {calendar}" : "{actor} креираше задолжение {todo} во листата {calendar}", + "You created todo {todo} in list {calendar}" : "Креиравте задолжение {todo} во листата {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} избриша задолжение {todo} од листата {calendar}", + "You deleted todo {todo} from list {calendar}" : "Избришавте задолжение {todo} од листата {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} ажурираше задолжение {todo} во листата {calendar}", + "You updated todo {todo} in list {calendar}" : "Ажуриравте задолжение {todo} во листата {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} го реши задолжението {todo} во листата {calendar}", + "You solved todo {todo} in list {calendar}" : "Го решивте задолжението {todo} во листата {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} повторно го отвори задолжението {todo} во листата {calendar}", + "You reopened todo {todo} in list {calendar}" : "Повторно го отворивте задолжението {todo} во листата {calendar}", + "A calendar <strong>todo</strong> was modified" : "Изменета е <strong>задача</strong> во календарот" },"pluralForm" :"nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;" }
\ No newline at end of file diff --git a/apps/dav/l10n/nb.js b/apps/dav/l10n/nb.js index b2169406345..c0a92521f9a 100644 --- a/apps/dav/l10n/nb.js +++ b/apps/dav/l10n/nb.js @@ -2,7 +2,6 @@ OC.L10N.register( "dav", { "Calendar" : "Kalender", - "Todos" : "Gjøremål", "Personal" : "Personlig", "{actor} created calendar {calendar}" : "{actor} opprettet kalenderen {calendar}", "You created calendar {calendar}" : "Du opprettet kalenderen {calendar}", @@ -31,19 +30,8 @@ OC.L10N.register( "{actor} updated event {event} in calendar {calendar}" : "{actor} oppdaterte hendelsen {event} i kalenderen {calendar}", "You updated event {event} in calendar {calendar}" : "Du oppdaterte hendelsen {event} i kalenderen {calendar}", "Busy" : "Opptatt", - "{actor} created todo {todo} in list {calendar}" : "{actor} opprettet en oppgaven {todo} i listen {calendar}", - "You created todo {todo} in list {calendar}" : "Du opprettet en oppgave {todo} i listen {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} slettet gjøremålet {todo} fra listen {calendar}", - "You deleted todo {todo} from list {calendar}" : "Du slettet gjøremålet {todo} fra listen {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} oppdaterte gjøremålet {todo} i listen {calendar}", - "You updated todo {todo} in list {calendar}" : "Du oppdaterte gjøremålet {todo} i listen {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} ferdigstilte gjøremålet {todo} i listen {calendar}", - "You solved todo {todo} in list {calendar}" : "Du ferdigstilte gjøremålet {todo} i listen {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} gjenåpnet gjøremålet {todo} i listen {calendar}", - "You reopened todo {todo} in list {calendar}" : "Du gjenåpnet oppgaven {todo} i listen {calendar}", "A <strong>calendar</strong> was modified" : "En <strong>kalender</strong> ble endret", "A calendar <strong>event</strong> was modified" : "En kalender <strong>hendelse</strong> ble endret", - "A calendar <strong>todo</strong> was modified" : "En kalende <strong>gjøremål</strong> ble endret", "Contact birthdays" : "Kontakters fødelsdag", "Death of %s" : "Død av %s", "Calendar:" : "Kalender:", @@ -89,6 +77,7 @@ OC.L10N.register( "WebDAV" : "WebDAV", "WebDAV endpoint" : "WebDAV endepunkt", "to" : "til", + "Delete slot" : "Slett tidsluke", "Monday" : "Mandag", "Tuesday" : "Tirsdag", "Wednesday" : "Onsdag", @@ -112,6 +101,18 @@ OC.L10N.register( "Are you accepting the invitation?" : "Aksepterer du invitasjonen?", "Tentative" : "Foreløpig", "Comment" : "Kommentar", - "Your attendance was updated successfully." : "Deltakelsen din ble oppdatert." + "Your attendance was updated successfully." : "Deltakelsen din ble oppdatert.", + "Todos" : "Gjøremål", + "{actor} created todo {todo} in list {calendar}" : "{actor} opprettet en oppgaven {todo} i listen {calendar}", + "You created todo {todo} in list {calendar}" : "Du opprettet en oppgave {todo} i listen {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} slettet gjøremålet {todo} fra listen {calendar}", + "You deleted todo {todo} from list {calendar}" : "Du slettet gjøremålet {todo} fra listen {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} oppdaterte gjøremålet {todo} i listen {calendar}", + "You updated todo {todo} in list {calendar}" : "Du oppdaterte gjøremålet {todo} i listen {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} ferdigstilte gjøremålet {todo} i listen {calendar}", + "You solved todo {todo} in list {calendar}" : "Du ferdigstilte gjøremålet {todo} i listen {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} gjenåpnet gjøremålet {todo} i listen {calendar}", + "You reopened todo {todo} in list {calendar}" : "Du gjenåpnet oppgaven {todo} i listen {calendar}", + "A calendar <strong>todo</strong> was modified" : "En kalende <strong>gjøremål</strong> ble endret" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/dav/l10n/nb.json b/apps/dav/l10n/nb.json index 9998d2be238..d60fa424bd7 100644 --- a/apps/dav/l10n/nb.json +++ b/apps/dav/l10n/nb.json @@ -1,6 +1,5 @@ { "translations": { "Calendar" : "Kalender", - "Todos" : "Gjøremål", "Personal" : "Personlig", "{actor} created calendar {calendar}" : "{actor} opprettet kalenderen {calendar}", "You created calendar {calendar}" : "Du opprettet kalenderen {calendar}", @@ -29,19 +28,8 @@ "{actor} updated event {event} in calendar {calendar}" : "{actor} oppdaterte hendelsen {event} i kalenderen {calendar}", "You updated event {event} in calendar {calendar}" : "Du oppdaterte hendelsen {event} i kalenderen {calendar}", "Busy" : "Opptatt", - "{actor} created todo {todo} in list {calendar}" : "{actor} opprettet en oppgaven {todo} i listen {calendar}", - "You created todo {todo} in list {calendar}" : "Du opprettet en oppgave {todo} i listen {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} slettet gjøremålet {todo} fra listen {calendar}", - "You deleted todo {todo} from list {calendar}" : "Du slettet gjøremålet {todo} fra listen {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} oppdaterte gjøremålet {todo} i listen {calendar}", - "You updated todo {todo} in list {calendar}" : "Du oppdaterte gjøremålet {todo} i listen {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} ferdigstilte gjøremålet {todo} i listen {calendar}", - "You solved todo {todo} in list {calendar}" : "Du ferdigstilte gjøremålet {todo} i listen {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} gjenåpnet gjøremålet {todo} i listen {calendar}", - "You reopened todo {todo} in list {calendar}" : "Du gjenåpnet oppgaven {todo} i listen {calendar}", "A <strong>calendar</strong> was modified" : "En <strong>kalender</strong> ble endret", "A calendar <strong>event</strong> was modified" : "En kalender <strong>hendelse</strong> ble endret", - "A calendar <strong>todo</strong> was modified" : "En kalende <strong>gjøremål</strong> ble endret", "Contact birthdays" : "Kontakters fødelsdag", "Death of %s" : "Død av %s", "Calendar:" : "Kalender:", @@ -87,6 +75,7 @@ "WebDAV" : "WebDAV", "WebDAV endpoint" : "WebDAV endepunkt", "to" : "til", + "Delete slot" : "Slett tidsluke", "Monday" : "Mandag", "Tuesday" : "Tirsdag", "Wednesday" : "Onsdag", @@ -110,6 +99,18 @@ "Are you accepting the invitation?" : "Aksepterer du invitasjonen?", "Tentative" : "Foreløpig", "Comment" : "Kommentar", - "Your attendance was updated successfully." : "Deltakelsen din ble oppdatert." + "Your attendance was updated successfully." : "Deltakelsen din ble oppdatert.", + "Todos" : "Gjøremål", + "{actor} created todo {todo} in list {calendar}" : "{actor} opprettet en oppgaven {todo} i listen {calendar}", + "You created todo {todo} in list {calendar}" : "Du opprettet en oppgave {todo} i listen {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} slettet gjøremålet {todo} fra listen {calendar}", + "You deleted todo {todo} from list {calendar}" : "Du slettet gjøremålet {todo} fra listen {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} oppdaterte gjøremålet {todo} i listen {calendar}", + "You updated todo {todo} in list {calendar}" : "Du oppdaterte gjøremålet {todo} i listen {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} ferdigstilte gjøremålet {todo} i listen {calendar}", + "You solved todo {todo} in list {calendar}" : "Du ferdigstilte gjøremålet {todo} i listen {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} gjenåpnet gjøremålet {todo} i listen {calendar}", + "You reopened todo {todo} in list {calendar}" : "Du gjenåpnet oppgaven {todo} i listen {calendar}", + "A calendar <strong>todo</strong> was modified" : "En kalende <strong>gjøremål</strong> ble endret" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/dav/l10n/nl.js b/apps/dav/l10n/nl.js index 6a1f9ee6efd..3ebb608547f 100644 --- a/apps/dav/l10n/nl.js +++ b/apps/dav/l10n/nl.js @@ -2,7 +2,7 @@ OC.L10N.register( "dav", { "Calendar" : "Agenda", - "Todos" : "Te doen", + "To-dos" : "Taken", "Personal" : "Persoonlijk", "{actor} created calendar {calendar}" : "{actor} creëerde agenda {calendar}", "You created calendar {calendar}" : "Jij creëerde agenda {calendar}", @@ -35,20 +35,17 @@ OC.L10N.register( "{actor} restored event {event} of calendar {calendar}" : "{actor} herstelde afspraak {event} in agenda {calendar}", "You restored event {event} of calendar {calendar}" : "Je herstelde afspraak {event} in agenda {calendar}", "Busy" : "Bezig", - "{actor} created todo {todo} in list {calendar}" : "{actor} creëerde taak {todo} in lijst {calendar}", - "You created todo {todo} in list {calendar}" : "Jij creëerde taak {todo} in lijst {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} heeft de taak {todo} uit lijst {calendar} verwijderd", - "You deleted todo {todo} from list {calendar}" : "Je verwijderde taak {todo} uit lijst {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} heeft taak {todo} bijgewerkt in lijst {calendar}", - "You updated todo {todo} in list {calendar}" : "Je hebt taak {todo} bijgewerkt in lijst {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} heeft taak {todo} in lijst {calendar} afgewerkt", - "You solved todo {todo} in list {calendar}" : "Je hebt taak {todo} in lijst {calendar} afgewerkt", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} heropende taak {todo} in lijst {calendar}", - "You reopened todo {todo} in list {calendar}" : "Je heropende taak {todo} in lijst {calendar}", + "{actor} created to-do {todo} in list {calendar}" : "{actor} voegde de taak {todo} to aan de lijst {calendar}", + "You created to-do {todo} in list {calendar}" : "Je voegde de taak {todo} toe aan de lijst {calendar}", + "{actor} deleted to-do {todo} from list {calendar}" : "{actor} verwijderde de taak {todo} van de lijst {calendar}", + "You deleted to-do {todo} from list {calendar}" : "Jij verwijderde de taak {todo} van de lijst {calendar}", + "{actor} updated to-do {todo} in list {calendar}" : "{actor} paste de taak {todo} in de lijst {calendar} aan", + "You updated to-do {todo} in list {calendar}" : "Jij paste de taak {todo} in de lijst {calendar} aan", + "{actor} solved to-do {todo} in list {calendar}" : "{actor} voltooide de taak {todo} in de lijst {calendar}", + "You solved to-do {todo} in list {calendar}" : "Jij voltooide de taak {todo} in de lijst {calendar}", "Calendar, contacts and tasks" : "Agenda, contactpersonen en taken", "A <strong>calendar</strong> was modified" : "Een <strong>agenda</strong> is aangepast", "A calendar <strong>event</strong> was modified" : "Een agenda <strong>gebeurtenis</strong> is aangepast", - "A calendar <strong>todo</strong> was modified" : "Een agenda <strong>Te doen</strong> was aangepast", "Contact birthdays" : "Verjaardagen", "Death of %s" : "Sterfdatum van %s", "Calendar:" : "Agenda", @@ -85,7 +82,7 @@ OC.L10N.register( "More options at %s" : "Meer opties op %s", "Contacts" : "Contactpersonen", "{actor} created address book {addressbook}" : "{actor} creëerde adresboek {addressbook}", - "You created address book {addressbook}" : "Je creëere adresboek {addressbook}", + "You created address book {addressbook}" : "Je creëerde adresboek {addressbook}", "{actor} deleted address book {addressbook}" : "{actor} verwijdede adresboek {addressbook}", "You deleted address book {addressbook}" : "Je verwijderde adresboek {addressbook}", "{actor} updated address book {addressbook}" : "{actor} wijzigde adresboek {addressbook}", @@ -157,6 +154,18 @@ OC.L10N.register( "Tentative" : "Onder voorbehoud", "Number of guests" : "Aantal gasten", "Comment" : "Notitie", - "Your attendance was updated successfully." : "Je deelname is succesvol bijgewerkt." + "Your attendance was updated successfully." : "Je deelname is succesvol bijgewerkt.", + "Todos" : "Te doen", + "{actor} created todo {todo} in list {calendar}" : "{actor} creëerde taak {todo} in lijst {calendar}", + "You created todo {todo} in list {calendar}" : "Jij creëerde taak {todo} in lijst {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} heeft de taak {todo} uit lijst {calendar} verwijderd", + "You deleted todo {todo} from list {calendar}" : "Je verwijderde taak {todo} uit lijst {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} heeft taak {todo} bijgewerkt in lijst {calendar}", + "You updated todo {todo} in list {calendar}" : "Je hebt taak {todo} bijgewerkt in lijst {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} heeft taak {todo} in lijst {calendar} afgewerkt", + "You solved todo {todo} in list {calendar}" : "Je hebt taak {todo} in lijst {calendar} afgewerkt", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} heropende taak {todo} in lijst {calendar}", + "You reopened todo {todo} in list {calendar}" : "Je heropende taak {todo} in lijst {calendar}", + "A calendar <strong>todo</strong> was modified" : "Een agenda <strong>Te doen</strong> was aangepast" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/dav/l10n/nl.json b/apps/dav/l10n/nl.json index 6ef31be82d9..74d32b8ea8b 100644 --- a/apps/dav/l10n/nl.json +++ b/apps/dav/l10n/nl.json @@ -1,6 +1,6 @@ { "translations": { "Calendar" : "Agenda", - "Todos" : "Te doen", + "To-dos" : "Taken", "Personal" : "Persoonlijk", "{actor} created calendar {calendar}" : "{actor} creëerde agenda {calendar}", "You created calendar {calendar}" : "Jij creëerde agenda {calendar}", @@ -33,20 +33,17 @@ "{actor} restored event {event} of calendar {calendar}" : "{actor} herstelde afspraak {event} in agenda {calendar}", "You restored event {event} of calendar {calendar}" : "Je herstelde afspraak {event} in agenda {calendar}", "Busy" : "Bezig", - "{actor} created todo {todo} in list {calendar}" : "{actor} creëerde taak {todo} in lijst {calendar}", - "You created todo {todo} in list {calendar}" : "Jij creëerde taak {todo} in lijst {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} heeft de taak {todo} uit lijst {calendar} verwijderd", - "You deleted todo {todo} from list {calendar}" : "Je verwijderde taak {todo} uit lijst {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} heeft taak {todo} bijgewerkt in lijst {calendar}", - "You updated todo {todo} in list {calendar}" : "Je hebt taak {todo} bijgewerkt in lijst {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} heeft taak {todo} in lijst {calendar} afgewerkt", - "You solved todo {todo} in list {calendar}" : "Je hebt taak {todo} in lijst {calendar} afgewerkt", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} heropende taak {todo} in lijst {calendar}", - "You reopened todo {todo} in list {calendar}" : "Je heropende taak {todo} in lijst {calendar}", + "{actor} created to-do {todo} in list {calendar}" : "{actor} voegde de taak {todo} to aan de lijst {calendar}", + "You created to-do {todo} in list {calendar}" : "Je voegde de taak {todo} toe aan de lijst {calendar}", + "{actor} deleted to-do {todo} from list {calendar}" : "{actor} verwijderde de taak {todo} van de lijst {calendar}", + "You deleted to-do {todo} from list {calendar}" : "Jij verwijderde de taak {todo} van de lijst {calendar}", + "{actor} updated to-do {todo} in list {calendar}" : "{actor} paste de taak {todo} in de lijst {calendar} aan", + "You updated to-do {todo} in list {calendar}" : "Jij paste de taak {todo} in de lijst {calendar} aan", + "{actor} solved to-do {todo} in list {calendar}" : "{actor} voltooide de taak {todo} in de lijst {calendar}", + "You solved to-do {todo} in list {calendar}" : "Jij voltooide de taak {todo} in de lijst {calendar}", "Calendar, contacts and tasks" : "Agenda, contactpersonen en taken", "A <strong>calendar</strong> was modified" : "Een <strong>agenda</strong> is aangepast", "A calendar <strong>event</strong> was modified" : "Een agenda <strong>gebeurtenis</strong> is aangepast", - "A calendar <strong>todo</strong> was modified" : "Een agenda <strong>Te doen</strong> was aangepast", "Contact birthdays" : "Verjaardagen", "Death of %s" : "Sterfdatum van %s", "Calendar:" : "Agenda", @@ -83,7 +80,7 @@ "More options at %s" : "Meer opties op %s", "Contacts" : "Contactpersonen", "{actor} created address book {addressbook}" : "{actor} creëerde adresboek {addressbook}", - "You created address book {addressbook}" : "Je creëere adresboek {addressbook}", + "You created address book {addressbook}" : "Je creëerde adresboek {addressbook}", "{actor} deleted address book {addressbook}" : "{actor} verwijdede adresboek {addressbook}", "You deleted address book {addressbook}" : "Je verwijderde adresboek {addressbook}", "{actor} updated address book {addressbook}" : "{actor} wijzigde adresboek {addressbook}", @@ -155,6 +152,18 @@ "Tentative" : "Onder voorbehoud", "Number of guests" : "Aantal gasten", "Comment" : "Notitie", - "Your attendance was updated successfully." : "Je deelname is succesvol bijgewerkt." + "Your attendance was updated successfully." : "Je deelname is succesvol bijgewerkt.", + "Todos" : "Te doen", + "{actor} created todo {todo} in list {calendar}" : "{actor} creëerde taak {todo} in lijst {calendar}", + "You created todo {todo} in list {calendar}" : "Jij creëerde taak {todo} in lijst {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} heeft de taak {todo} uit lijst {calendar} verwijderd", + "You deleted todo {todo} from list {calendar}" : "Je verwijderde taak {todo} uit lijst {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} heeft taak {todo} bijgewerkt in lijst {calendar}", + "You updated todo {todo} in list {calendar}" : "Je hebt taak {todo} bijgewerkt in lijst {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} heeft taak {todo} in lijst {calendar} afgewerkt", + "You solved todo {todo} in list {calendar}" : "Je hebt taak {todo} in lijst {calendar} afgewerkt", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} heropende taak {todo} in lijst {calendar}", + "You reopened todo {todo} in list {calendar}" : "Je heropende taak {todo} in lijst {calendar}", + "A calendar <strong>todo</strong> was modified" : "Een agenda <strong>Te doen</strong> was aangepast" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/dav/l10n/pl.js b/apps/dav/l10n/pl.js index a66f5a394da..4a6e63a27d6 100644 --- a/apps/dav/l10n/pl.js +++ b/apps/dav/l10n/pl.js @@ -2,7 +2,7 @@ OC.L10N.register( "dav", { "Calendar" : "Kalendarz", - "Todos" : "Zadania", + "To-dos" : "Do zrobienia", "Personal" : "Osobiste", "{actor} created calendar {calendar}" : "{actor} utworzył kalendarz {calendar}", "You created calendar {calendar}" : "Utworzyłeś kalendarz {calendar}", @@ -32,23 +32,27 @@ OC.L10N.register( "You deleted event {event} from calendar {calendar}" : "Usunąłeś wydarzenie {event} z kalendarza {calendar}", "{actor} updated event {event} in calendar {calendar}" : "{actor} zaktualizował wydarzenie {event} z kalendarza {calendar}", "You updated event {event} in calendar {calendar}" : "Zaktualizowałeś wydarzenie {event} w kalendarzu {calendar}", + "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{actor} przeniósł wydarzenie {event} z kalendarza {sourceCalendar} do kalendarza {targetCalendar}", + "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "Przeniosłeś wydarzenie {event} z kalendarza {sourceCalendar} do kalendarza {targetCalendar}", "{actor} restored event {event} of calendar {calendar}" : "{actor} przywrócił wydarzenie {event} z kalendarza {calendar}", "You restored event {event} of calendar {calendar}" : "Przywróciłeś wydarzenie {event} z kalendarza {calendar}", "Busy" : "Czekaj", - "{actor} created todo {todo} in list {calendar}" : "{actor} utworzył zadanie {todo} na liście {calendar}", - "You created todo {todo} in list {calendar}" : "Utworzyłeś zadanie {todo} na liście {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} usunął zadanie {todo} z listy {calendar}", - "You deleted todo {todo} from list {calendar}" : "Usunąłeś zadanie {todo} z listy {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} zaktualizował zadanie {todo} na liście {calendar}", - "You updated todo {todo} in list {calendar}" : "Zaktualizowałeś zadanie {todo} na liście {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} zakończył zadanie {todo} na liście {calendar}", - "You solved todo {todo} in list {calendar}" : "Zakończyłeś zadanie {todo} na liście {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} otworzył ponownie zadanie {todo} na liście {calendar}", - "You reopened todo {todo} in list {calendar}" : "Otworzyłeś ponownie zadanie {todo} na liście {calendar}", + "{actor} created to-do {todo} in list {calendar}" : "{actor} utworzył zadanie {todo} na liście {calendar}", + "You created to-do {todo} in list {calendar}" : "Utworzyłeś zadanie {todo} na liście {calendar}", + "{actor} deleted to-do {todo} from list {calendar}" : "{actor} usunął zadanie {todo} z listy {calendar}", + "You deleted to-do {todo} from list {calendar}" : "Usunąłeś zadanie {todo} z listy {calendar}", + "{actor} updated to-do {todo} in list {calendar}" : "{actor} zaktualizował zadanie {todo} na liście {calendar}", + "You updated to-do {todo} in list {calendar}" : "Zaktualizowałeś zadanie {todo} na liście {calendar}", + "{actor} solved to-do {todo} in list {calendar}" : "{actor} zakończył zadanie {todo} na liście {calendar}", + "You solved to-do {todo} in list {calendar}" : "Zakończyłeś zadanie {todo} na liście {calendar}", + "{actor} reopened to-do {todo} in list {calendar}" : "{actor} otworzył ponownie zadanie {todo} na liście {calendar}", + "You reopened to-do {todo} in list {calendar}" : "Otworzyłeś ponownie zadanie {todo} na liście {calendar}", + "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor} przeniósł zadanie {todo} z listy {sourceCalendar} na listę {targetCalendar}", + "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "Przeniosłeś zadanie {todo} z listy {sourceCalendar} na listę {targetCalendar}", "Calendar, contacts and tasks" : "Kalendarz, kontakty i zadania", "A <strong>calendar</strong> was modified" : "<strong>Kalendarz</strong> został zmodyfikowany", "A calendar <strong>event</strong> was modified" : "<strong>Zdarzenie</strong> kalendarza zostało zmodyfikowane", - "A calendar <strong>todo</strong> was modified" : "Kalendarz <strong>zadań</strong> został zmieniony", + "A calendar <strong>to-do</strong> was modified" : "Kalendarz <strong>zadań</strong> został zmieniony", "Contact birthdays" : "Urodziny kontaktu", "Death of %s" : "Śmierć %s", "Calendar:" : "Kalendarz:", @@ -155,6 +159,7 @@ OC.L10N.register( "Friday" : "Piątek", "Saturday" : "Sobota", "Sunday" : "Niedziela", + "Automatically set user status to \"Do not disturb\" outside of availability to mute all notifications." : "Automatycznie ustaw status użytkownika na \"Nie przeszkadzać\" poza dostępnością, aby wyciszyć wszystkie powiadomienia.", "Save" : "Zapisz", "Failed to load availability" : "Nie udało się wczytać dostępności", "Saved availability" : "Zapisana dostępność", @@ -177,6 +182,18 @@ OC.L10N.register( "Tentative" : "Niepewne", "Number of guests" : "Liczba gości", "Comment" : "Komentarz", - "Your attendance was updated successfully." : "Twoja obecność została pomyślnie zaktualizowana." + "Your attendance was updated successfully." : "Twoja obecność została pomyślnie zaktualizowana.", + "Todos" : "Zadania", + "{actor} created todo {todo} in list {calendar}" : "{actor} utworzył zadanie {todo} na liście {calendar}", + "You created todo {todo} in list {calendar}" : "Utworzyłeś zadanie {todo} na liście {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} usunął zadanie {todo} z listy {calendar}", + "You deleted todo {todo} from list {calendar}" : "Usunąłeś zadanie {todo} z listy {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} zaktualizował zadanie {todo} na liście {calendar}", + "You updated todo {todo} in list {calendar}" : "Zaktualizowałeś zadanie {todo} na liście {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} zakończył zadanie {todo} na liście {calendar}", + "You solved todo {todo} in list {calendar}" : "Zakończyłeś zadanie {todo} na liście {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} otworzył ponownie zadanie {todo} na liście {calendar}", + "You reopened todo {todo} in list {calendar}" : "Otworzyłeś ponownie zadanie {todo} na liście {calendar}", + "A calendar <strong>todo</strong> was modified" : "Kalendarz <strong>zadań</strong> został zmieniony" }, "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/apps/dav/l10n/pl.json b/apps/dav/l10n/pl.json index c6096000fad..ec85fe58081 100644 --- a/apps/dav/l10n/pl.json +++ b/apps/dav/l10n/pl.json @@ -1,6 +1,6 @@ { "translations": { "Calendar" : "Kalendarz", - "Todos" : "Zadania", + "To-dos" : "Do zrobienia", "Personal" : "Osobiste", "{actor} created calendar {calendar}" : "{actor} utworzył kalendarz {calendar}", "You created calendar {calendar}" : "Utworzyłeś kalendarz {calendar}", @@ -30,23 +30,27 @@ "You deleted event {event} from calendar {calendar}" : "Usunąłeś wydarzenie {event} z kalendarza {calendar}", "{actor} updated event {event} in calendar {calendar}" : "{actor} zaktualizował wydarzenie {event} z kalendarza {calendar}", "You updated event {event} in calendar {calendar}" : "Zaktualizowałeś wydarzenie {event} w kalendarzu {calendar}", + "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{actor} przeniósł wydarzenie {event} z kalendarza {sourceCalendar} do kalendarza {targetCalendar}", + "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "Przeniosłeś wydarzenie {event} z kalendarza {sourceCalendar} do kalendarza {targetCalendar}", "{actor} restored event {event} of calendar {calendar}" : "{actor} przywrócił wydarzenie {event} z kalendarza {calendar}", "You restored event {event} of calendar {calendar}" : "Przywróciłeś wydarzenie {event} z kalendarza {calendar}", "Busy" : "Czekaj", - "{actor} created todo {todo} in list {calendar}" : "{actor} utworzył zadanie {todo} na liście {calendar}", - "You created todo {todo} in list {calendar}" : "Utworzyłeś zadanie {todo} na liście {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} usunął zadanie {todo} z listy {calendar}", - "You deleted todo {todo} from list {calendar}" : "Usunąłeś zadanie {todo} z listy {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} zaktualizował zadanie {todo} na liście {calendar}", - "You updated todo {todo} in list {calendar}" : "Zaktualizowałeś zadanie {todo} na liście {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} zakończył zadanie {todo} na liście {calendar}", - "You solved todo {todo} in list {calendar}" : "Zakończyłeś zadanie {todo} na liście {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} otworzył ponownie zadanie {todo} na liście {calendar}", - "You reopened todo {todo} in list {calendar}" : "Otworzyłeś ponownie zadanie {todo} na liście {calendar}", + "{actor} created to-do {todo} in list {calendar}" : "{actor} utworzył zadanie {todo} na liście {calendar}", + "You created to-do {todo} in list {calendar}" : "Utworzyłeś zadanie {todo} na liście {calendar}", + "{actor} deleted to-do {todo} from list {calendar}" : "{actor} usunął zadanie {todo} z listy {calendar}", + "You deleted to-do {todo} from list {calendar}" : "Usunąłeś zadanie {todo} z listy {calendar}", + "{actor} updated to-do {todo} in list {calendar}" : "{actor} zaktualizował zadanie {todo} na liście {calendar}", + "You updated to-do {todo} in list {calendar}" : "Zaktualizowałeś zadanie {todo} na liście {calendar}", + "{actor} solved to-do {todo} in list {calendar}" : "{actor} zakończył zadanie {todo} na liście {calendar}", + "You solved to-do {todo} in list {calendar}" : "Zakończyłeś zadanie {todo} na liście {calendar}", + "{actor} reopened to-do {todo} in list {calendar}" : "{actor} otworzył ponownie zadanie {todo} na liście {calendar}", + "You reopened to-do {todo} in list {calendar}" : "Otworzyłeś ponownie zadanie {todo} na liście {calendar}", + "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor} przeniósł zadanie {todo} z listy {sourceCalendar} na listę {targetCalendar}", + "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "Przeniosłeś zadanie {todo} z listy {sourceCalendar} na listę {targetCalendar}", "Calendar, contacts and tasks" : "Kalendarz, kontakty i zadania", "A <strong>calendar</strong> was modified" : "<strong>Kalendarz</strong> został zmodyfikowany", "A calendar <strong>event</strong> was modified" : "<strong>Zdarzenie</strong> kalendarza zostało zmodyfikowane", - "A calendar <strong>todo</strong> was modified" : "Kalendarz <strong>zadań</strong> został zmieniony", + "A calendar <strong>to-do</strong> was modified" : "Kalendarz <strong>zadań</strong> został zmieniony", "Contact birthdays" : "Urodziny kontaktu", "Death of %s" : "Śmierć %s", "Calendar:" : "Kalendarz:", @@ -153,6 +157,7 @@ "Friday" : "Piątek", "Saturday" : "Sobota", "Sunday" : "Niedziela", + "Automatically set user status to \"Do not disturb\" outside of availability to mute all notifications." : "Automatycznie ustaw status użytkownika na \"Nie przeszkadzać\" poza dostępnością, aby wyciszyć wszystkie powiadomienia.", "Save" : "Zapisz", "Failed to load availability" : "Nie udało się wczytać dostępności", "Saved availability" : "Zapisana dostępność", @@ -175,6 +180,18 @@ "Tentative" : "Niepewne", "Number of guests" : "Liczba gości", "Comment" : "Komentarz", - "Your attendance was updated successfully." : "Twoja obecność została pomyślnie zaktualizowana." + "Your attendance was updated successfully." : "Twoja obecność została pomyślnie zaktualizowana.", + "Todos" : "Zadania", + "{actor} created todo {todo} in list {calendar}" : "{actor} utworzył zadanie {todo} na liście {calendar}", + "You created todo {todo} in list {calendar}" : "Utworzyłeś zadanie {todo} na liście {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} usunął zadanie {todo} z listy {calendar}", + "You deleted todo {todo} from list {calendar}" : "Usunąłeś zadanie {todo} z listy {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} zaktualizował zadanie {todo} na liście {calendar}", + "You updated todo {todo} in list {calendar}" : "Zaktualizowałeś zadanie {todo} na liście {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} zakończył zadanie {todo} na liście {calendar}", + "You solved todo {todo} in list {calendar}" : "Zakończyłeś zadanie {todo} na liście {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} otworzył ponownie zadanie {todo} na liście {calendar}", + "You reopened todo {todo} in list {calendar}" : "Otworzyłeś ponownie zadanie {todo} na liście {calendar}", + "A calendar <strong>todo</strong> was modified" : "Kalendarz <strong>zadań</strong> został zmieniony" },"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/apps/dav/l10n/pt_BR.js b/apps/dav/l10n/pt_BR.js index 8c56afa1708..4136835a80a 100644 --- a/apps/dav/l10n/pt_BR.js +++ b/apps/dav/l10n/pt_BR.js @@ -2,7 +2,7 @@ OC.L10N.register( "dav", { "Calendar" : "Calendário", - "Todos" : "Tarefas", + "To-dos" : "Tarefas", "Personal" : "Pessoal", "{actor} created calendar {calendar}" : "{actor} criou o calendário {calendar}", "You created calendar {calendar}" : "Você criou o calendário {calendar}", @@ -32,23 +32,27 @@ OC.L10N.register( "You deleted event {event} from calendar {calendar}" : "Você excluiu o evento {event} do calendário {calendar}", "{actor} updated event {event} in calendar {calendar}" : "{actor} atualizou o evento {event} no calendário {calendar}", "You updated event {event} in calendar {calendar}" : "Você atualizou o evento {event} no calendário {calendar}", + "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{actor} moveu o evento {event} do calendario {sourceCalendar} para o calendario {targetCalendar}", + "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "Você moveu o evento {event} do calendario {sourceCalendar} para o calendario {targetCalendar}", "{actor} restored event {event} of calendar {calendar}" : "{actor} restaurou o evento {event} do calendário {calendar}", "You restored event {event} of calendar {calendar}" : "Você restaurou o evento {event} do calendário {calendar}", "Busy" : "Ocupado", - "{actor} created todo {todo} in list {calendar}" : "{actor} criou a tarefa {todo} na lista {calendar}", - "You created todo {todo} in list {calendar}" : "Você criou a tarefa {todo} na lista {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} excluiu a tarefa {todo} da lista {calendar}", - "You deleted todo {todo} from list {calendar}" : "Você excluiu a tarefa {todo} da lista {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} atualizou a tarefa {todo} na lista {calendar}", - "You updated todo {todo} in list {calendar}" : "Você atualizou a tarefa {todo} na lista {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} tarefa resolvida {todo} na lista {calendar}", - "You solved todo {todo} in list {calendar}" : "Você terminou a tarefa {todo} na lista {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} reabriu tarefa {todo} na lista {calendar}", - "You reopened todo {todo} in list {calendar}" : "Você reabriu a terefa {todo} na lista {calendar}", + "{actor} created to-do {todo} in list {calendar}" : "{actor} criou tarefa {todo} na lista {calendar}", + "You created to-do {todo} in list {calendar}" : "Você criou a tarefa {todo} na lista {calendar}", + "{actor} deleted to-do {todo} from list {calendar}" : "{actor} excluiu a tarefa {todo} da lista {calendar}", + "You deleted to-do {todo} from list {calendar}" : "Você excluiu a tarefa {todo} da lista {calendar}", + "{actor} updated to-do {todo} in list {calendar}" : "{actor} atualizou a tarefa {todo} na lista {calendar}", + "You updated to-do {todo} in list {calendar}" : "Você atualizou a tarefa {todo} na lista {calendar}", + "{actor} solved to-do {todo} in list {calendar}" : "{actor} resolveu a tarefa {todo} na lista {calendar}", + "You solved to-do {todo} in list {calendar}" : "Você resolveu a tarefa {todo} na lista {calendar}", + "{actor} reopened to-do {todo} in list {calendar}" : "{actor} reabriu a tarefa {todo} na lista {calendar}", + "You reopened to-do {todo} in list {calendar}" : "Você reabriu a tarefa {todo} na lista {calendar}", + "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor} moveu a tarefa {todo} da lista {sourceCalendar} para a lista {targetCalendar}", + "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "Você moveu a tarefa {todo} da lista {sourceCalendar} para a lista {targetCalendar}", "Calendar, contacts and tasks" : "Calendário, contatos e tarefas", "A <strong>calendar</strong> was modified" : "Um <strong>calendário</strong> foi modificado", "A calendar <strong>event</strong> was modified" : "Um <strong>evento</strong> do calendário foi modificado", - "A calendar <strong>todo</strong> was modified" : "Uma <strong>tarefa</strong> do calendário foi modificada", + "A calendar <strong>to-do</strong> was modified" : "Um calendário <strong>tarefa</strong> foi modificado", "Contact birthdays" : "Aniversário dos contatos", "Death of %s" : "Morte de %s", "Calendar:" : "Calendário:", @@ -155,6 +159,7 @@ OC.L10N.register( "Friday" : "Sexta-feira", "Saturday" : "Sábado ", "Sunday" : "Domingo", + "Automatically set user status to \"Do not disturb\" outside of availability to mute all notifications." : "Defina automaticamente o status do usuário como \"Não perturbe\" fora de disponibilidade para silenciar todas as notificações.", "Save" : "Salvar", "Failed to load availability" : "Falha ao carregar a disponibilidade", "Saved availability" : "Disponibilidade salva", @@ -177,6 +182,18 @@ OC.L10N.register( "Tentative" : "Tentativa", "Number of guests" : "Número de convidados", "Comment" : "Comentário", - "Your attendance was updated successfully." : "Sua presença foi atualizada com sucesso." + "Your attendance was updated successfully." : "Sua presença foi atualizada com sucesso.", + "Todos" : "Tarefas", + "{actor} created todo {todo} in list {calendar}" : "{actor} criou a tarefa {todo} na lista {calendar}", + "You created todo {todo} in list {calendar}" : "Você criou a tarefa {todo} na lista {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} excluiu a tarefa {todo} da lista {calendar}", + "You deleted todo {todo} from list {calendar}" : "Você excluiu a tarefa {todo} da lista {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} atualizou a tarefa {todo} na lista {calendar}", + "You updated todo {todo} in list {calendar}" : "Você atualizou a tarefa {todo} na lista {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} tarefa resolvida {todo} na lista {calendar}", + "You solved todo {todo} in list {calendar}" : "Você terminou a tarefa {todo} na lista {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} reabriu tarefa {todo} na lista {calendar}", + "You reopened todo {todo} in list {calendar}" : "Você reabriu a terefa {todo} na lista {calendar}", + "A calendar <strong>todo</strong> was modified" : "Uma <strong>tarefa</strong> do calendário foi modificada" }, "nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/apps/dav/l10n/pt_BR.json b/apps/dav/l10n/pt_BR.json index 852dac798ba..792d5bf3573 100644 --- a/apps/dav/l10n/pt_BR.json +++ b/apps/dav/l10n/pt_BR.json @@ -1,6 +1,6 @@ { "translations": { "Calendar" : "Calendário", - "Todos" : "Tarefas", + "To-dos" : "Tarefas", "Personal" : "Pessoal", "{actor} created calendar {calendar}" : "{actor} criou o calendário {calendar}", "You created calendar {calendar}" : "Você criou o calendário {calendar}", @@ -30,23 +30,27 @@ "You deleted event {event} from calendar {calendar}" : "Você excluiu o evento {event} do calendário {calendar}", "{actor} updated event {event} in calendar {calendar}" : "{actor} atualizou o evento {event} no calendário {calendar}", "You updated event {event} in calendar {calendar}" : "Você atualizou o evento {event} no calendário {calendar}", + "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{actor} moveu o evento {event} do calendario {sourceCalendar} para o calendario {targetCalendar}", + "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "Você moveu o evento {event} do calendario {sourceCalendar} para o calendario {targetCalendar}", "{actor} restored event {event} of calendar {calendar}" : "{actor} restaurou o evento {event} do calendário {calendar}", "You restored event {event} of calendar {calendar}" : "Você restaurou o evento {event} do calendário {calendar}", "Busy" : "Ocupado", - "{actor} created todo {todo} in list {calendar}" : "{actor} criou a tarefa {todo} na lista {calendar}", - "You created todo {todo} in list {calendar}" : "Você criou a tarefa {todo} na lista {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} excluiu a tarefa {todo} da lista {calendar}", - "You deleted todo {todo} from list {calendar}" : "Você excluiu a tarefa {todo} da lista {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} atualizou a tarefa {todo} na lista {calendar}", - "You updated todo {todo} in list {calendar}" : "Você atualizou a tarefa {todo} na lista {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} tarefa resolvida {todo} na lista {calendar}", - "You solved todo {todo} in list {calendar}" : "Você terminou a tarefa {todo} na lista {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} reabriu tarefa {todo} na lista {calendar}", - "You reopened todo {todo} in list {calendar}" : "Você reabriu a terefa {todo} na lista {calendar}", + "{actor} created to-do {todo} in list {calendar}" : "{actor} criou tarefa {todo} na lista {calendar}", + "You created to-do {todo} in list {calendar}" : "Você criou a tarefa {todo} na lista {calendar}", + "{actor} deleted to-do {todo} from list {calendar}" : "{actor} excluiu a tarefa {todo} da lista {calendar}", + "You deleted to-do {todo} from list {calendar}" : "Você excluiu a tarefa {todo} da lista {calendar}", + "{actor} updated to-do {todo} in list {calendar}" : "{actor} atualizou a tarefa {todo} na lista {calendar}", + "You updated to-do {todo} in list {calendar}" : "Você atualizou a tarefa {todo} na lista {calendar}", + "{actor} solved to-do {todo} in list {calendar}" : "{actor} resolveu a tarefa {todo} na lista {calendar}", + "You solved to-do {todo} in list {calendar}" : "Você resolveu a tarefa {todo} na lista {calendar}", + "{actor} reopened to-do {todo} in list {calendar}" : "{actor} reabriu a tarefa {todo} na lista {calendar}", + "You reopened to-do {todo} in list {calendar}" : "Você reabriu a tarefa {todo} na lista {calendar}", + "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor} moveu a tarefa {todo} da lista {sourceCalendar} para a lista {targetCalendar}", + "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "Você moveu a tarefa {todo} da lista {sourceCalendar} para a lista {targetCalendar}", "Calendar, contacts and tasks" : "Calendário, contatos e tarefas", "A <strong>calendar</strong> was modified" : "Um <strong>calendário</strong> foi modificado", "A calendar <strong>event</strong> was modified" : "Um <strong>evento</strong> do calendário foi modificado", - "A calendar <strong>todo</strong> was modified" : "Uma <strong>tarefa</strong> do calendário foi modificada", + "A calendar <strong>to-do</strong> was modified" : "Um calendário <strong>tarefa</strong> foi modificado", "Contact birthdays" : "Aniversário dos contatos", "Death of %s" : "Morte de %s", "Calendar:" : "Calendário:", @@ -153,6 +157,7 @@ "Friday" : "Sexta-feira", "Saturday" : "Sábado ", "Sunday" : "Domingo", + "Automatically set user status to \"Do not disturb\" outside of availability to mute all notifications." : "Defina automaticamente o status do usuário como \"Não perturbe\" fora de disponibilidade para silenciar todas as notificações.", "Save" : "Salvar", "Failed to load availability" : "Falha ao carregar a disponibilidade", "Saved availability" : "Disponibilidade salva", @@ -175,6 +180,18 @@ "Tentative" : "Tentativa", "Number of guests" : "Número de convidados", "Comment" : "Comentário", - "Your attendance was updated successfully." : "Sua presença foi atualizada com sucesso." + "Your attendance was updated successfully." : "Sua presença foi atualizada com sucesso.", + "Todos" : "Tarefas", + "{actor} created todo {todo} in list {calendar}" : "{actor} criou a tarefa {todo} na lista {calendar}", + "You created todo {todo} in list {calendar}" : "Você criou a tarefa {todo} na lista {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} excluiu a tarefa {todo} da lista {calendar}", + "You deleted todo {todo} from list {calendar}" : "Você excluiu a tarefa {todo} da lista {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} atualizou a tarefa {todo} na lista {calendar}", + "You updated todo {todo} in list {calendar}" : "Você atualizou a tarefa {todo} na lista {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} tarefa resolvida {todo} na lista {calendar}", + "You solved todo {todo} in list {calendar}" : "Você terminou a tarefa {todo} na lista {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} reabriu tarefa {todo} na lista {calendar}", + "You reopened todo {todo} in list {calendar}" : "Você reabriu a terefa {todo} na lista {calendar}", + "A calendar <strong>todo</strong> was modified" : "Uma <strong>tarefa</strong> do calendário foi modificada" },"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/apps/dav/l10n/ru.js b/apps/dav/l10n/ru.js index a2a21aa535f..188f950d4b3 100644 --- a/apps/dav/l10n/ru.js +++ b/apps/dav/l10n/ru.js @@ -2,7 +2,7 @@ OC.L10N.register( "dav", { "Calendar" : "Календарь", - "Todos" : "Задачи", + "To-dos" : "Задачи", "Personal" : "Личное", "{actor} created calendar {calendar}" : "{actor} создал(а) календарь «{calendar}»", "You created calendar {calendar}" : "Вы создали календарь «{calendar}»", @@ -32,23 +32,27 @@ OC.L10N.register( "You deleted event {event} from calendar {calendar}" : "Вы удалили событие «{event}» из календаря «{calendar}»", "{actor} updated event {event} in calendar {calendar}" : "{actor} обновил(а) событие «{event}» в календаре «{calendar}»", "You updated event {event} in calendar {calendar}" : "Вы обновили событие «{event}» в календаре «{calendar}»", + "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{actor} переместил(а) событие «{event}» из календаря «{sourceCalendar}» в календарь «{targetCalendar}»", + "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "Вы переместили событие «{event}» из календаря «{sourceCalendar}» в календарь «{targetCalendar}»", "{actor} restored event {event} of calendar {calendar}" : "{actor} восстановил(а) событие {event} в календаре {calendar}", "You restored event {event} of calendar {calendar}" : "Вы восстановили событие {event} в календаре {calendar}", "Busy" : "Занято", - "{actor} created todo {todo} in list {calendar}" : "{actor} создал(а) задачу «{todo}» в списке «{calendar}»", - "You created todo {todo} in list {calendar}" : "Вы создали задачу «{todo}» в списке «{calendar}»", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} удалил(а) задачу «{todo}» из списка «{calendar}»", - "You deleted todo {todo} from list {calendar}" : "Вы удалили задачу «{todo}» из списка «{calendar}»", - "{actor} updated todo {todo} in list {calendar}" : "{actor} обновил(а) задачу «{todo}» из списка «{calendar}»", - "You updated todo {todo} in list {calendar}" : "Вы обновили задачу «{todo}» из списка «{calendar}»", - "{actor} solved todo {todo} in list {calendar}" : "{actor} завершил(а) задачу «{todo}» из списка «{calendar}»", - "You solved todo {todo} in list {calendar}" : "Вы завершили задачу «{todo}» из списка «{calendar}»", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} повторно(а) открыл задачу «{todo}» из списка «{calendar}»", - "You reopened todo {todo} in list {calendar}" : "Вы повторно открыли задачу «{todo}» из списка «{calendar}»", + "{actor} created to-do {todo} in list {calendar}" : "{actor} создал(а) задачу «{todo}» в списке «{calendar}»", + "You created to-do {todo} in list {calendar}" : "Вы создали задачу «{todo}» в списке «{calendar}»", + "{actor} deleted to-do {todo} from list {calendar}" : "{actor} удалил(а) задачу «{todo}» из списка «{calendar}»", + "You deleted to-do {todo} from list {calendar}" : "Вы удалили задачу «{todo}» из списка «{calendar}»", + "{actor} updated to-do {todo} in list {calendar}" : "{actor} обновил(а) задачу «{todo}» из списка «{calendar}»", + "You updated to-do {todo} in list {calendar}" : "Вы обновили задачу «{todo}» из списка «{calendar}»", + "{actor} solved to-do {todo} in list {calendar}" : "{actor} завершил(а) задачу «{todo}» из списка «{calendar}»", + "You solved to-do {todo} in list {calendar}" : "Вы завершили задачу «{todo}» из списка «{calendar}»", + "{actor} reopened to-do {todo} in list {calendar}" : "{actor} повторно(а) открыл задачу «{todo}» из списка «{calendar}»", + "You reopened to-do {todo} in list {calendar}" : "Вы повторно открыли задачу «{todo}» из списка «{calendar}»", + "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor} переместил(а) задачу «{todo}» из календаря «{sourceCalendar}» в календарь «{targetCalendar}»", + "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "Вы переместили задачу «{todo}» из календаря «{sourceCalendar}» в календарь «{targetCalendar}»", "Calendar, contacts and tasks" : "Календарь, контакты и задачи", "A <strong>calendar</strong> was modified" : "Изменения <strong>календаря</strong> ", "A calendar <strong>event</strong> was modified" : "В календаре изменено <strong>событие</strong>", - "A calendar <strong>todo</strong> was modified" : "В календаре изменена <strong>задача</strong>", + "A calendar <strong>to-do</strong> was modified" : "В календаре изменена <strong>задача</strong> ", "Contact birthdays" : "Дни рождения контакта", "Death of %s" : "Смерть %s", "Calendar:" : "Календарь:", @@ -110,6 +114,12 @@ OC.L10N.register( "A <strong>contact</strong> or <strong>address book</strong> was modified" : "Изменение <strong>контакта</strong> или <strong>адресной книги</strong>", "File is not updatable: %1$s" : "Файл не подлежит обновлению: %1$s", "Could not write file contents" : "Не удалось записать содержимое файла", + "Could not open file" : "Не удалось открыть файл", + "Encryption not ready: %1$s" : "Подсистема шифрования не готова: %1$s", + "Failed to open file: %1$s" : "Не удалось открыть файл: %1$s", + "Invalid chunk name" : "Недопустимое имя сегмента", + "Failed to write file contents: %1$s" : "Не удалось записать содержимое файла: %1$s", + "File not found: %1$s" : "Файл не найден: %1$s", "System is in maintenance mode." : "Сервер находится в режиме обслуживания.", "Upgrade needed" : "Требуется обновление", "Your %s needs to be configured to use HTTPS in order to use CalDAV and CardDAV with iOS/macOS." : "Ваш %s должен быть настроен на использование протокола HTTPS, чтобы можно было использовать CalDAV и CardDAV на iOS/macOS.", @@ -121,6 +131,7 @@ OC.L10N.register( "Completed on %s" : "Завершено %s", "Due on %s by %s" : "До %s %s", "Due on %s" : "До %s", + "Calendars including events, details and attendees" : "Календари, в том числе события, подробные сведения и участники", "Contacts and groups" : "Контакты и группы", "WebDAV" : "WebDAV", "WebDAV endpoint" : "точка подключения WebDAV", @@ -139,6 +150,7 @@ OC.L10N.register( "Saturday" : "Суббота", "Sunday" : "Воскресенье", "Save" : "Сохранить", + "Failed to load availability" : "Не удалось получить сведения о доступности", "Calendar server" : "Сервер календаря", "Send invitations to attendees" : "Отправить приглашения", "Automatically generate a birthday calendar" : "Создавать календарь дней рождения автоматически", @@ -155,6 +167,18 @@ OC.L10N.register( "Tentative" : "Под вопросом", "Number of guests" : "Количество гостей", "Comment" : "Комментарий", - "Your attendance was updated successfully." : "Статус участия обновлён." + "Your attendance was updated successfully." : "Статус участия обновлён.", + "Todos" : "Задачи", + "{actor} created todo {todo} in list {calendar}" : "{actor} создал(а) задачу «{todo}» в списке «{calendar}»", + "You created todo {todo} in list {calendar}" : "Вы создали задачу «{todo}» в списке «{calendar}»", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} удалил(а) задачу «{todo}» из списка «{calendar}»", + "You deleted todo {todo} from list {calendar}" : "Вы удалили задачу «{todo}» из списка «{calendar}»", + "{actor} updated todo {todo} in list {calendar}" : "{actor} обновил(а) задачу «{todo}» из списка «{calendar}»", + "You updated todo {todo} in list {calendar}" : "Вы обновили задачу «{todo}» из списка «{calendar}»", + "{actor} solved todo {todo} in list {calendar}" : "{actor} завершил(а) задачу «{todo}» из списка «{calendar}»", + "You solved todo {todo} in list {calendar}" : "Вы завершили задачу «{todo}» из списка «{calendar}»", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} повторно(а) открыл задачу «{todo}» из списка «{calendar}»", + "You reopened todo {todo} in list {calendar}" : "Вы повторно открыли задачу «{todo}» из списка «{calendar}»", + "A calendar <strong>todo</strong> was modified" : "В календаре изменена <strong>задача</strong>" }, "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/apps/dav/l10n/ru.json b/apps/dav/l10n/ru.json index ef6fd3e653a..49c34dd6bc8 100644 --- a/apps/dav/l10n/ru.json +++ b/apps/dav/l10n/ru.json @@ -1,6 +1,6 @@ { "translations": { "Calendar" : "Календарь", - "Todos" : "Задачи", + "To-dos" : "Задачи", "Personal" : "Личное", "{actor} created calendar {calendar}" : "{actor} создал(а) календарь «{calendar}»", "You created calendar {calendar}" : "Вы создали календарь «{calendar}»", @@ -30,23 +30,27 @@ "You deleted event {event} from calendar {calendar}" : "Вы удалили событие «{event}» из календаря «{calendar}»", "{actor} updated event {event} in calendar {calendar}" : "{actor} обновил(а) событие «{event}» в календаре «{calendar}»", "You updated event {event} in calendar {calendar}" : "Вы обновили событие «{event}» в календаре «{calendar}»", + "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{actor} переместил(а) событие «{event}» из календаря «{sourceCalendar}» в календарь «{targetCalendar}»", + "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "Вы переместили событие «{event}» из календаря «{sourceCalendar}» в календарь «{targetCalendar}»", "{actor} restored event {event} of calendar {calendar}" : "{actor} восстановил(а) событие {event} в календаре {calendar}", "You restored event {event} of calendar {calendar}" : "Вы восстановили событие {event} в календаре {calendar}", "Busy" : "Занято", - "{actor} created todo {todo} in list {calendar}" : "{actor} создал(а) задачу «{todo}» в списке «{calendar}»", - "You created todo {todo} in list {calendar}" : "Вы создали задачу «{todo}» в списке «{calendar}»", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} удалил(а) задачу «{todo}» из списка «{calendar}»", - "You deleted todo {todo} from list {calendar}" : "Вы удалили задачу «{todo}» из списка «{calendar}»", - "{actor} updated todo {todo} in list {calendar}" : "{actor} обновил(а) задачу «{todo}» из списка «{calendar}»", - "You updated todo {todo} in list {calendar}" : "Вы обновили задачу «{todo}» из списка «{calendar}»", - "{actor} solved todo {todo} in list {calendar}" : "{actor} завершил(а) задачу «{todo}» из списка «{calendar}»", - "You solved todo {todo} in list {calendar}" : "Вы завершили задачу «{todo}» из списка «{calendar}»", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} повторно(а) открыл задачу «{todo}» из списка «{calendar}»", - "You reopened todo {todo} in list {calendar}" : "Вы повторно открыли задачу «{todo}» из списка «{calendar}»", + "{actor} created to-do {todo} in list {calendar}" : "{actor} создал(а) задачу «{todo}» в списке «{calendar}»", + "You created to-do {todo} in list {calendar}" : "Вы создали задачу «{todo}» в списке «{calendar}»", + "{actor} deleted to-do {todo} from list {calendar}" : "{actor} удалил(а) задачу «{todo}» из списка «{calendar}»", + "You deleted to-do {todo} from list {calendar}" : "Вы удалили задачу «{todo}» из списка «{calendar}»", + "{actor} updated to-do {todo} in list {calendar}" : "{actor} обновил(а) задачу «{todo}» из списка «{calendar}»", + "You updated to-do {todo} in list {calendar}" : "Вы обновили задачу «{todo}» из списка «{calendar}»", + "{actor} solved to-do {todo} in list {calendar}" : "{actor} завершил(а) задачу «{todo}» из списка «{calendar}»", + "You solved to-do {todo} in list {calendar}" : "Вы завершили задачу «{todo}» из списка «{calendar}»", + "{actor} reopened to-do {todo} in list {calendar}" : "{actor} повторно(а) открыл задачу «{todo}» из списка «{calendar}»", + "You reopened to-do {todo} in list {calendar}" : "Вы повторно открыли задачу «{todo}» из списка «{calendar}»", + "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor} переместил(а) задачу «{todo}» из календаря «{sourceCalendar}» в календарь «{targetCalendar}»", + "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "Вы переместили задачу «{todo}» из календаря «{sourceCalendar}» в календарь «{targetCalendar}»", "Calendar, contacts and tasks" : "Календарь, контакты и задачи", "A <strong>calendar</strong> was modified" : "Изменения <strong>календаря</strong> ", "A calendar <strong>event</strong> was modified" : "В календаре изменено <strong>событие</strong>", - "A calendar <strong>todo</strong> was modified" : "В календаре изменена <strong>задача</strong>", + "A calendar <strong>to-do</strong> was modified" : "В календаре изменена <strong>задача</strong> ", "Contact birthdays" : "Дни рождения контакта", "Death of %s" : "Смерть %s", "Calendar:" : "Календарь:", @@ -108,6 +112,12 @@ "A <strong>contact</strong> or <strong>address book</strong> was modified" : "Изменение <strong>контакта</strong> или <strong>адресной книги</strong>", "File is not updatable: %1$s" : "Файл не подлежит обновлению: %1$s", "Could not write file contents" : "Не удалось записать содержимое файла", + "Could not open file" : "Не удалось открыть файл", + "Encryption not ready: %1$s" : "Подсистема шифрования не готова: %1$s", + "Failed to open file: %1$s" : "Не удалось открыть файл: %1$s", + "Invalid chunk name" : "Недопустимое имя сегмента", + "Failed to write file contents: %1$s" : "Не удалось записать содержимое файла: %1$s", + "File not found: %1$s" : "Файл не найден: %1$s", "System is in maintenance mode." : "Сервер находится в режиме обслуживания.", "Upgrade needed" : "Требуется обновление", "Your %s needs to be configured to use HTTPS in order to use CalDAV and CardDAV with iOS/macOS." : "Ваш %s должен быть настроен на использование протокола HTTPS, чтобы можно было использовать CalDAV и CardDAV на iOS/macOS.", @@ -119,6 +129,7 @@ "Completed on %s" : "Завершено %s", "Due on %s by %s" : "До %s %s", "Due on %s" : "До %s", + "Calendars including events, details and attendees" : "Календари, в том числе события, подробные сведения и участники", "Contacts and groups" : "Контакты и группы", "WebDAV" : "WebDAV", "WebDAV endpoint" : "точка подключения WebDAV", @@ -137,6 +148,7 @@ "Saturday" : "Суббота", "Sunday" : "Воскресенье", "Save" : "Сохранить", + "Failed to load availability" : "Не удалось получить сведения о доступности", "Calendar server" : "Сервер календаря", "Send invitations to attendees" : "Отправить приглашения", "Automatically generate a birthday calendar" : "Создавать календарь дней рождения автоматически", @@ -153,6 +165,18 @@ "Tentative" : "Под вопросом", "Number of guests" : "Количество гостей", "Comment" : "Комментарий", - "Your attendance was updated successfully." : "Статус участия обновлён." + "Your attendance was updated successfully." : "Статус участия обновлён.", + "Todos" : "Задачи", + "{actor} created todo {todo} in list {calendar}" : "{actor} создал(а) задачу «{todo}» в списке «{calendar}»", + "You created todo {todo} in list {calendar}" : "Вы создали задачу «{todo}» в списке «{calendar}»", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} удалил(а) задачу «{todo}» из списка «{calendar}»", + "You deleted todo {todo} from list {calendar}" : "Вы удалили задачу «{todo}» из списка «{calendar}»", + "{actor} updated todo {todo} in list {calendar}" : "{actor} обновил(а) задачу «{todo}» из списка «{calendar}»", + "You updated todo {todo} in list {calendar}" : "Вы обновили задачу «{todo}» из списка «{calendar}»", + "{actor} solved todo {todo} in list {calendar}" : "{actor} завершил(а) задачу «{todo}» из списка «{calendar}»", + "You solved todo {todo} in list {calendar}" : "Вы завершили задачу «{todo}» из списка «{calendar}»", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} повторно(а) открыл задачу «{todo}» из списка «{calendar}»", + "You reopened todo {todo} in list {calendar}" : "Вы повторно открыли задачу «{todo}» из списка «{calendar}»", + "A calendar <strong>todo</strong> was modified" : "В календаре изменена <strong>задача</strong>" },"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/apps/dav/l10n/sc.js b/apps/dav/l10n/sc.js index caeaa8654aa..f2e2b3c6343 100644 --- a/apps/dav/l10n/sc.js +++ b/apps/dav/l10n/sc.js @@ -2,7 +2,6 @@ OC.L10N.register( "dav", { "Calendar" : "Calendàriu", - "Todos" : "Cosas de fàghere", "Personal" : "Personale", "{actor} created calendar {calendar}" : "{actor} at creadu su calendàriu {calendar}", "You created calendar {calendar}" : "As creadu su calendàriu {calendar}", @@ -35,20 +34,9 @@ OC.L10N.register( "{actor} restored event {event} of calendar {calendar}" : "{actor} at ripristinadu s'eventu {event} in su calendàriu {calendar}", "You restored event {event} of calendar {calendar}" : "As ripristinadu s'eventu {event} in su calendàriu {calendar}", "Busy" : "Impinnadu", - "{actor} created todo {todo} in list {calendar}" : "{actor} at creadu sa cosa de fàghere {todo} in s'elencu {calendar}", - "You created todo {todo} in list {calendar}" : "As creadu una cosa de fàghere {todo} in s'elencu {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} at cantzelladu sa cosa de fàghere {todo} dae s'elencu {calendar}", - "You deleted todo {todo} from list {calendar}" : "As eliminadu sa cosa de fàghere {todo} dae s'elencu {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} at agiornadu sa cosa de fàghere {todo} in s'elencu {calendar}", - "You updated todo {todo} in list {calendar}" : "As agiornadu sa cosa de fàghere {todo} in s'elencu {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} at isortu sa cosa de fàghere {todo} in s'elencu {calendar}", - "You solved todo {todo} in list {calendar}" : "As isortu sa cosa de fàghere {todo} in s'elencu {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} at torradu a abèrrere sa cosa de fàghere {todo} in s'elencu {calendar}", - "You reopened todo {todo} in list {calendar}" : "As torradu a abèrrere sa cosa de fàghere {todo} in s'elecu {calendar}", "Calendar, contacts and tasks" : "Calendàriu, cuntatos e fainas", "A <strong>calendar</strong> was modified" : "Unu <strong>calendàriu</strong> est istadu modificadu", "A calendar <strong>event</strong> was modified" : "Un'<strong>eventu</strong> de su calendàriu est istadu modificadu", - "A calendar <strong>todo</strong> was modified" : "Una <strong>cosa de fàghere</strong> de su calendàriu est istada modificada", "Contact birthdays" : "Data de nàschida de is cuntatos", "Death of %s" : "Morte de %s", "Calendar:" : "Calendàriu:", @@ -145,6 +133,18 @@ OC.L10N.register( "Are you accepting the invitation?" : "Cheres atzetare s'invitu?", "Tentative" : "Intentu", "Comment" : "Cummentu", - "Your attendance was updated successfully." : "Sa partetzipatzione tua est istada agiornada in manera curreta." + "Your attendance was updated successfully." : "Sa partetzipatzione tua est istada agiornada in manera curreta.", + "Todos" : "Cosas de fàghere", + "{actor} created todo {todo} in list {calendar}" : "{actor} at creadu sa cosa de fàghere {todo} in s'elencu {calendar}", + "You created todo {todo} in list {calendar}" : "As creadu una cosa de fàghere {todo} in s'elencu {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} at cantzelladu sa cosa de fàghere {todo} dae s'elencu {calendar}", + "You deleted todo {todo} from list {calendar}" : "As eliminadu sa cosa de fàghere {todo} dae s'elencu {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} at agiornadu sa cosa de fàghere {todo} in s'elencu {calendar}", + "You updated todo {todo} in list {calendar}" : "As agiornadu sa cosa de fàghere {todo} in s'elencu {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} at isortu sa cosa de fàghere {todo} in s'elencu {calendar}", + "You solved todo {todo} in list {calendar}" : "As isortu sa cosa de fàghere {todo} in s'elencu {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} at torradu a abèrrere sa cosa de fàghere {todo} in s'elencu {calendar}", + "You reopened todo {todo} in list {calendar}" : "As torradu a abèrrere sa cosa de fàghere {todo} in s'elecu {calendar}", + "A calendar <strong>todo</strong> was modified" : "Una <strong>cosa de fàghere</strong> de su calendàriu est istada modificada" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/dav/l10n/sc.json b/apps/dav/l10n/sc.json index 77c14b27fa2..4ed2e95896f 100644 --- a/apps/dav/l10n/sc.json +++ b/apps/dav/l10n/sc.json @@ -1,6 +1,5 @@ { "translations": { "Calendar" : "Calendàriu", - "Todos" : "Cosas de fàghere", "Personal" : "Personale", "{actor} created calendar {calendar}" : "{actor} at creadu su calendàriu {calendar}", "You created calendar {calendar}" : "As creadu su calendàriu {calendar}", @@ -33,20 +32,9 @@ "{actor} restored event {event} of calendar {calendar}" : "{actor} at ripristinadu s'eventu {event} in su calendàriu {calendar}", "You restored event {event} of calendar {calendar}" : "As ripristinadu s'eventu {event} in su calendàriu {calendar}", "Busy" : "Impinnadu", - "{actor} created todo {todo} in list {calendar}" : "{actor} at creadu sa cosa de fàghere {todo} in s'elencu {calendar}", - "You created todo {todo} in list {calendar}" : "As creadu una cosa de fàghere {todo} in s'elencu {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} at cantzelladu sa cosa de fàghere {todo} dae s'elencu {calendar}", - "You deleted todo {todo} from list {calendar}" : "As eliminadu sa cosa de fàghere {todo} dae s'elencu {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} at agiornadu sa cosa de fàghere {todo} in s'elencu {calendar}", - "You updated todo {todo} in list {calendar}" : "As agiornadu sa cosa de fàghere {todo} in s'elencu {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} at isortu sa cosa de fàghere {todo} in s'elencu {calendar}", - "You solved todo {todo} in list {calendar}" : "As isortu sa cosa de fàghere {todo} in s'elencu {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} at torradu a abèrrere sa cosa de fàghere {todo} in s'elencu {calendar}", - "You reopened todo {todo} in list {calendar}" : "As torradu a abèrrere sa cosa de fàghere {todo} in s'elecu {calendar}", "Calendar, contacts and tasks" : "Calendàriu, cuntatos e fainas", "A <strong>calendar</strong> was modified" : "Unu <strong>calendàriu</strong> est istadu modificadu", "A calendar <strong>event</strong> was modified" : "Un'<strong>eventu</strong> de su calendàriu est istadu modificadu", - "A calendar <strong>todo</strong> was modified" : "Una <strong>cosa de fàghere</strong> de su calendàriu est istada modificada", "Contact birthdays" : "Data de nàschida de is cuntatos", "Death of %s" : "Morte de %s", "Calendar:" : "Calendàriu:", @@ -143,6 +131,18 @@ "Are you accepting the invitation?" : "Cheres atzetare s'invitu?", "Tentative" : "Intentu", "Comment" : "Cummentu", - "Your attendance was updated successfully." : "Sa partetzipatzione tua est istada agiornada in manera curreta." + "Your attendance was updated successfully." : "Sa partetzipatzione tua est istada agiornada in manera curreta.", + "Todos" : "Cosas de fàghere", + "{actor} created todo {todo} in list {calendar}" : "{actor} at creadu sa cosa de fàghere {todo} in s'elencu {calendar}", + "You created todo {todo} in list {calendar}" : "As creadu una cosa de fàghere {todo} in s'elencu {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} at cantzelladu sa cosa de fàghere {todo} dae s'elencu {calendar}", + "You deleted todo {todo} from list {calendar}" : "As eliminadu sa cosa de fàghere {todo} dae s'elencu {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} at agiornadu sa cosa de fàghere {todo} in s'elencu {calendar}", + "You updated todo {todo} in list {calendar}" : "As agiornadu sa cosa de fàghere {todo} in s'elencu {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} at isortu sa cosa de fàghere {todo} in s'elencu {calendar}", + "You solved todo {todo} in list {calendar}" : "As isortu sa cosa de fàghere {todo} in s'elencu {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} at torradu a abèrrere sa cosa de fàghere {todo} in s'elencu {calendar}", + "You reopened todo {todo} in list {calendar}" : "As torradu a abèrrere sa cosa de fàghere {todo} in s'elecu {calendar}", + "A calendar <strong>todo</strong> was modified" : "Una <strong>cosa de fàghere</strong> de su calendàriu est istada modificada" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/dav/l10n/sk.js b/apps/dav/l10n/sk.js index 7b1a92c26bb..1c62436025e 100644 --- a/apps/dav/l10n/sk.js +++ b/apps/dav/l10n/sk.js @@ -2,7 +2,6 @@ OC.L10N.register( "dav", { "Calendar" : "Kalendár", - "Todos" : "Úlohy", "Personal" : "Osobné", "{actor} created calendar {calendar}" : "[actor] vytvoril kalendár [calendar]", "You created calendar {calendar}" : "Vytvorili ste kalendár {calendar}", @@ -35,20 +34,9 @@ OC.L10N.register( "{actor} restored event {event} of calendar {calendar}" : "{actor} obnovil udalosť {event} v kalendári {calendar}", "You restored event {event} of calendar {calendar}" : "Obnovili ste udalosť {event} v kalendári {calendar}", "Busy" : "Zaneprázdnený", - "{actor} created todo {todo} in list {calendar}" : "{actor} vytvoril úlohu {todo} v {calendar}", - "You created todo {todo} in list {calendar}" : "Vytvorili ste úlohu {todo} v {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} zmazal úlohu {todo} z {calendar}", - "You deleted todo {todo} from list {calendar}" : "Zmazali ste úlohu {todo} z {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} upravil úlohu {todo} v {calendar}", - "You updated todo {todo} in list {calendar}" : "Upravili ste úlohu {todo} v {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} vyriešil úlohu {todo} v {calendar}", - "You solved todo {todo} in list {calendar}" : "Vyriešili ste úlohu {todo} v {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} znovu otvoril úlohu {todo} v {calendar}", - "You reopened todo {todo} in list {calendar}" : "Otvorili ste znovu úlohu {todo} v {calendar}", "Calendar, contacts and tasks" : "Kalendár, kontakty a úlohy", "A <strong>calendar</strong> was modified" : "<strong>kalendár</strong> bol upravený", "A calendar <strong>event</strong> was modified" : "<strong>Udalosť</strong> v kalendári bola upravená", - "A calendar <strong>todo</strong> was modified" : "<strong>Pripomienka</strong> v kalendári bola upravená", "Contact birthdays" : "Narodeniny kontaktu", "Death of %s" : "Dátum úmrtia %s", "Calendar:" : "Kalendár:", @@ -137,6 +125,7 @@ OC.L10N.register( "Due on %s by %s" : "Termín od %s do %s", "Due on %s" : "Termín do %s", "Migrated calendar (%1$s)" : "Migrovaný kalendár (%1$s)", + "Calendars including events, details and attendees" : "Kalendáre vrátane udalostí, podrobností a účastníkov", "Contacts and groups" : "Kontakty a skupiny", "WebDAV" : "WebDAV", "WebDAV endpoint" : "Koncový bod WebDAV", @@ -155,6 +144,9 @@ OC.L10N.register( "Saturday" : "Sobota", "Sunday" : "Nedeľa", "Save" : "Uložiť", + "Failed to load availability" : "Nepodarilo sa načítať dostupnosť", + "Saved availability" : "Dostupnosť bola uložená", + "Failed to save availability" : "Nepodarilo sa uložiť dostupnosť", "Calendar server" : "Kalendárový server", "Send invitations to attendees" : "Odoslanie pozvánok účastníkom", "Automatically generate a birthday calendar" : "Automaticky generovať narodeninový kalendár", @@ -162,6 +154,8 @@ OC.L10N.register( "Hence they will not be available immediately after enabling but will show up after some time." : "Preto nebudú dostupné hneď po povolení, ale zobrazia sa po určitom čase", "Send notifications for events" : "Zaslať upozornenia na udalosti", "Notifications are sent via background jobs, so these must occur often enough." : "Upozornenia sa odosielajú prostredníctvom úloh na pozadí - preto je potrebné, aby tieto prebiehali dostatočne často.", + "Send reminder notifications to calendar sharees as well" : "Posielať upozornenia na pripomienky aj zdieľaným osobám v kalendári", + "Reminders are always sent to organizers and attendees." : "Upozornenia sa vždy posielajú organizátorom a účastníkom.", "Enable notifications for events via push" : "Zapnúť oznámenia o udalostiach prostredníctvom technológie push.", "Also install the {calendarappstoreopen}Calendar app{linkclose}, or {calendardocopen}connect your desktop & mobile for syncing ↗{linkclose}." : "Tiež nainštalujte {calendarappstoreopen}apku Kalendár{linkclose} alebo {calendardocopen}pripojte svoj počítač a smartfón pre synchronizáciu ↗{linkclose}.", "Please make sure to properly set up {emailopen}the email server{linkclose}." : "Uistite sa, že ste správne nastavili {emailopen}e-mailový server{linkclose}.", @@ -171,6 +165,18 @@ OC.L10N.register( "Tentative" : "Neistý", "Number of guests" : "Počet návštevníkov", "Comment" : "Komentár", - "Your attendance was updated successfully." : "Vaša účasť bola aktualizovaná úspešne." + "Your attendance was updated successfully." : "Vaša účasť bola aktualizovaná úspešne.", + "Todos" : "Úlohy", + "{actor} created todo {todo} in list {calendar}" : "{actor} vytvoril úlohu {todo} v {calendar}", + "You created todo {todo} in list {calendar}" : "Vytvorili ste úlohu {todo} v {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} zmazal úlohu {todo} z {calendar}", + "You deleted todo {todo} from list {calendar}" : "Zmazali ste úlohu {todo} z {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} upravil úlohu {todo} v {calendar}", + "You updated todo {todo} in list {calendar}" : "Upravili ste úlohu {todo} v {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} vyriešil úlohu {todo} v {calendar}", + "You solved todo {todo} in list {calendar}" : "Vyriešili ste úlohu {todo} v {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} znovu otvoril úlohu {todo} v {calendar}", + "You reopened todo {todo} in list {calendar}" : "Otvorili ste znovu úlohu {todo} v {calendar}", + "A calendar <strong>todo</strong> was modified" : "<strong>Pripomienka</strong> v kalendári bola upravená" }, "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/apps/dav/l10n/sk.json b/apps/dav/l10n/sk.json index fc9ffea27ad..2b2ce1b30fb 100644 --- a/apps/dav/l10n/sk.json +++ b/apps/dav/l10n/sk.json @@ -1,6 +1,5 @@ { "translations": { "Calendar" : "Kalendár", - "Todos" : "Úlohy", "Personal" : "Osobné", "{actor} created calendar {calendar}" : "[actor] vytvoril kalendár [calendar]", "You created calendar {calendar}" : "Vytvorili ste kalendár {calendar}", @@ -33,20 +32,9 @@ "{actor} restored event {event} of calendar {calendar}" : "{actor} obnovil udalosť {event} v kalendári {calendar}", "You restored event {event} of calendar {calendar}" : "Obnovili ste udalosť {event} v kalendári {calendar}", "Busy" : "Zaneprázdnený", - "{actor} created todo {todo} in list {calendar}" : "{actor} vytvoril úlohu {todo} v {calendar}", - "You created todo {todo} in list {calendar}" : "Vytvorili ste úlohu {todo} v {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} zmazal úlohu {todo} z {calendar}", - "You deleted todo {todo} from list {calendar}" : "Zmazali ste úlohu {todo} z {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} upravil úlohu {todo} v {calendar}", - "You updated todo {todo} in list {calendar}" : "Upravili ste úlohu {todo} v {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} vyriešil úlohu {todo} v {calendar}", - "You solved todo {todo} in list {calendar}" : "Vyriešili ste úlohu {todo} v {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} znovu otvoril úlohu {todo} v {calendar}", - "You reopened todo {todo} in list {calendar}" : "Otvorili ste znovu úlohu {todo} v {calendar}", "Calendar, contacts and tasks" : "Kalendár, kontakty a úlohy", "A <strong>calendar</strong> was modified" : "<strong>kalendár</strong> bol upravený", "A calendar <strong>event</strong> was modified" : "<strong>Udalosť</strong> v kalendári bola upravená", - "A calendar <strong>todo</strong> was modified" : "<strong>Pripomienka</strong> v kalendári bola upravená", "Contact birthdays" : "Narodeniny kontaktu", "Death of %s" : "Dátum úmrtia %s", "Calendar:" : "Kalendár:", @@ -135,6 +123,7 @@ "Due on %s by %s" : "Termín od %s do %s", "Due on %s" : "Termín do %s", "Migrated calendar (%1$s)" : "Migrovaný kalendár (%1$s)", + "Calendars including events, details and attendees" : "Kalendáre vrátane udalostí, podrobností a účastníkov", "Contacts and groups" : "Kontakty a skupiny", "WebDAV" : "WebDAV", "WebDAV endpoint" : "Koncový bod WebDAV", @@ -153,6 +142,9 @@ "Saturday" : "Sobota", "Sunday" : "Nedeľa", "Save" : "Uložiť", + "Failed to load availability" : "Nepodarilo sa načítať dostupnosť", + "Saved availability" : "Dostupnosť bola uložená", + "Failed to save availability" : "Nepodarilo sa uložiť dostupnosť", "Calendar server" : "Kalendárový server", "Send invitations to attendees" : "Odoslanie pozvánok účastníkom", "Automatically generate a birthday calendar" : "Automaticky generovať narodeninový kalendár", @@ -160,6 +152,8 @@ "Hence they will not be available immediately after enabling but will show up after some time." : "Preto nebudú dostupné hneď po povolení, ale zobrazia sa po určitom čase", "Send notifications for events" : "Zaslať upozornenia na udalosti", "Notifications are sent via background jobs, so these must occur often enough." : "Upozornenia sa odosielajú prostredníctvom úloh na pozadí - preto je potrebné, aby tieto prebiehali dostatočne často.", + "Send reminder notifications to calendar sharees as well" : "Posielať upozornenia na pripomienky aj zdieľaným osobám v kalendári", + "Reminders are always sent to organizers and attendees." : "Upozornenia sa vždy posielajú organizátorom a účastníkom.", "Enable notifications for events via push" : "Zapnúť oznámenia o udalostiach prostredníctvom technológie push.", "Also install the {calendarappstoreopen}Calendar app{linkclose}, or {calendardocopen}connect your desktop & mobile for syncing ↗{linkclose}." : "Tiež nainštalujte {calendarappstoreopen}apku Kalendár{linkclose} alebo {calendardocopen}pripojte svoj počítač a smartfón pre synchronizáciu ↗{linkclose}.", "Please make sure to properly set up {emailopen}the email server{linkclose}." : "Uistite sa, že ste správne nastavili {emailopen}e-mailový server{linkclose}.", @@ -169,6 +163,18 @@ "Tentative" : "Neistý", "Number of guests" : "Počet návštevníkov", "Comment" : "Komentár", - "Your attendance was updated successfully." : "Vaša účasť bola aktualizovaná úspešne." + "Your attendance was updated successfully." : "Vaša účasť bola aktualizovaná úspešne.", + "Todos" : "Úlohy", + "{actor} created todo {todo} in list {calendar}" : "{actor} vytvoril úlohu {todo} v {calendar}", + "You created todo {todo} in list {calendar}" : "Vytvorili ste úlohu {todo} v {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} zmazal úlohu {todo} z {calendar}", + "You deleted todo {todo} from list {calendar}" : "Zmazali ste úlohu {todo} z {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} upravil úlohu {todo} v {calendar}", + "You updated todo {todo} in list {calendar}" : "Upravili ste úlohu {todo} v {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} vyriešil úlohu {todo} v {calendar}", + "You solved todo {todo} in list {calendar}" : "Vyriešili ste úlohu {todo} v {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} znovu otvoril úlohu {todo} v {calendar}", + "You reopened todo {todo} in list {calendar}" : "Otvorili ste znovu úlohu {todo} v {calendar}", + "A calendar <strong>todo</strong> was modified" : "<strong>Pripomienka</strong> v kalendári bola upravená" },"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/apps/dav/l10n/sl.js b/apps/dav/l10n/sl.js index 2758b9eab04..0eaabf7e2cd 100644 --- a/apps/dav/l10n/sl.js +++ b/apps/dav/l10n/sl.js @@ -2,7 +2,6 @@ OC.L10N.register( "dav", { "Calendar" : "Koledar", - "Todos" : "Naloge", "Personal" : "Osebno", "{actor} created calendar {calendar}" : "{actor} ustvari koledar {calendar}", "You created calendar {calendar}" : "Ustvarim koledar {calendar}", @@ -31,20 +30,9 @@ OC.L10N.register( "{actor} updated event {event} in calendar {calendar}" : "{actor} posodobi dogodek {event} v koledarju {calendar}", "You updated event {event} in calendar {calendar}" : "Posodobite dogodek {event} v koledarju {calendar}", "Busy" : "Zasedeno", - "{actor} created todo {todo} in list {calendar}" : "{actor} ustvari nalogo {todo} v koledarju {calendar}", - "You created todo {todo} in list {calendar}" : "Ustvarite nalogo {todo} v koledarju {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} izbriše nalogo {todo} iz koledara {calendar}", - "You deleted todo {todo} from list {calendar}" : "Izbrišete nalogo {todo} iz koledarja {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} posodobi nalogo {todo} v koledarju {calendar}", - "You updated todo {todo} in list {calendar}" : "Posodobite nalogo {todo} v seznamu {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} razreši nalogo {todo} v koledarju {calendar}", - "You solved todo {todo} in list {calendar}" : "Razrešite nalogo {todo} v seznamu {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} ponovno odpre nalogo {todo} v koledarju {calendar}", - "You reopened todo {todo} in list {calendar}" : "Ponovno odprete nalogo {todo} v seznamu {calendar}", "Calendar, contacts and tasks" : "Koledar, stiki in naloge", "A <strong>calendar</strong> was modified" : "V <strong>koledar</strong> je vpisana sprememba", "A calendar <strong>event</strong> was modified" : "Spremenjen je <strong>dogodek</strong> v koledarju", - "A calendar <strong>todo</strong> was modified" : "Spremenjena je <strong>naloga</strong> koledarja", "Contact birthdays" : "Obletnice stikov", "Death of %s" : "%s (obletnica smrti)", "Calendar:" : "Koledar:", @@ -81,6 +69,7 @@ OC.L10N.register( "More options at %s" : "Več možnosti je na %s", "Contacts" : "Stiki", "You deleted address book {addressbook}" : "Izbrišete imenik {addressbook}", + "Could not write file contents" : "Ni mogoče zapisati vsebine datoteke", "System is in maintenance mode." : "Sistem je v vzdrževalnem načinu.", "Upgrade needed" : "Zahtevana je posodobitev", "Your %s needs to be configured to use HTTPS in order to use CalDAV and CardDAV with iOS/macOS." : "Za uporabo CalDAV in CardDAV v okoljih iOS/macOS je treba %s nastaviti za uporabo HTTPS.", @@ -100,7 +89,7 @@ OC.L10N.register( "to" : "do", "Delete slot" : "Izbriši možnost", "No working hours set" : "Ni navedenih delovnih ur", - "Add slot" : "Dodaj polje", + "Add slot" : "Dodaj možnost", "Monday" : "ponedeljek", "Tuesday" : "torek", "Wednesday" : "sreda", @@ -109,6 +98,7 @@ OC.L10N.register( "Saturday" : "sobota", "Sunday" : "nedelja", "Save" : "Shrani", + "Failed to load availability" : "Nalaganje seznama razpoložljivih polj je spodletelo", "Calendar server" : "Strežnik koledarja", "Send invitations to attendees" : "Pošlji povabilo udeležencem", "Automatically generate a birthday calendar" : "Samodejno ustvari koledar rojstnih dni", @@ -125,6 +115,18 @@ OC.L10N.register( "Tentative" : "Začasno", "Number of guests" : "Število gostov", "Comment" : "Opomba", - "Your attendance was updated successfully." : "Vaša prisotnost je uspešno posodobljena." + "Your attendance was updated successfully." : "Vaša prisotnost je uspešno posodobljena.", + "Todos" : "Naloge", + "{actor} created todo {todo} in list {calendar}" : "{actor} ustvari nalogo {todo} v koledarju {calendar}", + "You created todo {todo} in list {calendar}" : "Ustvarite nalogo {todo} v koledarju {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} izbriše nalogo {todo} iz koledara {calendar}", + "You deleted todo {todo} from list {calendar}" : "Izbrišete nalogo {todo} iz koledarja {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} posodobi nalogo {todo} v koledarju {calendar}", + "You updated todo {todo} in list {calendar}" : "Posodobite nalogo {todo} v seznamu {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} razreši nalogo {todo} v koledarju {calendar}", + "You solved todo {todo} in list {calendar}" : "Razrešite nalogo {todo} v seznamu {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} ponovno odpre nalogo {todo} v koledarju {calendar}", + "You reopened todo {todo} in list {calendar}" : "Ponovno odprete nalogo {todo} v seznamu {calendar}", + "A calendar <strong>todo</strong> was modified" : "Spremenjena je <strong>naloga</strong> koledarja" }, "nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);"); diff --git a/apps/dav/l10n/sl.json b/apps/dav/l10n/sl.json index 591db863702..4df1e51d2a5 100644 --- a/apps/dav/l10n/sl.json +++ b/apps/dav/l10n/sl.json @@ -1,6 +1,5 @@ { "translations": { "Calendar" : "Koledar", - "Todos" : "Naloge", "Personal" : "Osebno", "{actor} created calendar {calendar}" : "{actor} ustvari koledar {calendar}", "You created calendar {calendar}" : "Ustvarim koledar {calendar}", @@ -29,20 +28,9 @@ "{actor} updated event {event} in calendar {calendar}" : "{actor} posodobi dogodek {event} v koledarju {calendar}", "You updated event {event} in calendar {calendar}" : "Posodobite dogodek {event} v koledarju {calendar}", "Busy" : "Zasedeno", - "{actor} created todo {todo} in list {calendar}" : "{actor} ustvari nalogo {todo} v koledarju {calendar}", - "You created todo {todo} in list {calendar}" : "Ustvarite nalogo {todo} v koledarju {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} izbriše nalogo {todo} iz koledara {calendar}", - "You deleted todo {todo} from list {calendar}" : "Izbrišete nalogo {todo} iz koledarja {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} posodobi nalogo {todo} v koledarju {calendar}", - "You updated todo {todo} in list {calendar}" : "Posodobite nalogo {todo} v seznamu {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} razreši nalogo {todo} v koledarju {calendar}", - "You solved todo {todo} in list {calendar}" : "Razrešite nalogo {todo} v seznamu {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} ponovno odpre nalogo {todo} v koledarju {calendar}", - "You reopened todo {todo} in list {calendar}" : "Ponovno odprete nalogo {todo} v seznamu {calendar}", "Calendar, contacts and tasks" : "Koledar, stiki in naloge", "A <strong>calendar</strong> was modified" : "V <strong>koledar</strong> je vpisana sprememba", "A calendar <strong>event</strong> was modified" : "Spremenjen je <strong>dogodek</strong> v koledarju", - "A calendar <strong>todo</strong> was modified" : "Spremenjena je <strong>naloga</strong> koledarja", "Contact birthdays" : "Obletnice stikov", "Death of %s" : "%s (obletnica smrti)", "Calendar:" : "Koledar:", @@ -79,6 +67,7 @@ "More options at %s" : "Več možnosti je na %s", "Contacts" : "Stiki", "You deleted address book {addressbook}" : "Izbrišete imenik {addressbook}", + "Could not write file contents" : "Ni mogoče zapisati vsebine datoteke", "System is in maintenance mode." : "Sistem je v vzdrževalnem načinu.", "Upgrade needed" : "Zahtevana je posodobitev", "Your %s needs to be configured to use HTTPS in order to use CalDAV and CardDAV with iOS/macOS." : "Za uporabo CalDAV in CardDAV v okoljih iOS/macOS je treba %s nastaviti za uporabo HTTPS.", @@ -98,7 +87,7 @@ "to" : "do", "Delete slot" : "Izbriši možnost", "No working hours set" : "Ni navedenih delovnih ur", - "Add slot" : "Dodaj polje", + "Add slot" : "Dodaj možnost", "Monday" : "ponedeljek", "Tuesday" : "torek", "Wednesday" : "sreda", @@ -107,6 +96,7 @@ "Saturday" : "sobota", "Sunday" : "nedelja", "Save" : "Shrani", + "Failed to load availability" : "Nalaganje seznama razpoložljivih polj je spodletelo", "Calendar server" : "Strežnik koledarja", "Send invitations to attendees" : "Pošlji povabilo udeležencem", "Automatically generate a birthday calendar" : "Samodejno ustvari koledar rojstnih dni", @@ -123,6 +113,18 @@ "Tentative" : "Začasno", "Number of guests" : "Število gostov", "Comment" : "Opomba", - "Your attendance was updated successfully." : "Vaša prisotnost je uspešno posodobljena." + "Your attendance was updated successfully." : "Vaša prisotnost je uspešno posodobljena.", + "Todos" : "Naloge", + "{actor} created todo {todo} in list {calendar}" : "{actor} ustvari nalogo {todo} v koledarju {calendar}", + "You created todo {todo} in list {calendar}" : "Ustvarite nalogo {todo} v koledarju {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} izbriše nalogo {todo} iz koledara {calendar}", + "You deleted todo {todo} from list {calendar}" : "Izbrišete nalogo {todo} iz koledarja {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} posodobi nalogo {todo} v koledarju {calendar}", + "You updated todo {todo} in list {calendar}" : "Posodobite nalogo {todo} v seznamu {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} razreši nalogo {todo} v koledarju {calendar}", + "You solved todo {todo} in list {calendar}" : "Razrešite nalogo {todo} v seznamu {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} ponovno odpre nalogo {todo} v koledarju {calendar}", + "You reopened todo {todo} in list {calendar}" : "Ponovno odprete nalogo {todo} v seznamu {calendar}", + "A calendar <strong>todo</strong> was modified" : "Spremenjena je <strong>naloga</strong> koledarja" },"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/apps/dav/l10n/sr.js b/apps/dav/l10n/sr.js index 4412a3999bf..fb78bee1f27 100644 --- a/apps/dav/l10n/sr.js +++ b/apps/dav/l10n/sr.js @@ -2,7 +2,6 @@ OC.L10N.register( "dav", { "Calendar" : "Календар", - "Todos" : "Подсетници", "Personal" : "Лично", "{actor} created calendar {calendar}" : "{actor} направи календар {calendar}", "You created calendar {calendar}" : "Направили сте календар {calendar}", @@ -31,19 +30,8 @@ OC.L10N.register( "{actor} updated event {event} in calendar {calendar}" : "{actor} је ажурирао догађај {event} у календару {calendar}", "You updated event {event} in calendar {calendar}" : "Ажурирали сте догађај {event} у календару {calendar}", "Busy" : "Заузет/а", - "{actor} created todo {todo} in list {calendar}" : "{actor} је направио подсетник {todo} у листи {calendar}", - "You created todo {todo} in list {calendar}" : "Креирали сте подсетник {todo} у листи {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} је обрисао подсетник {todo} из листе {calendar}", - "You deleted todo {todo} from list {calendar}" : "Обрисали сте подсетник {todo} из листе {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} је ажурирао подсетник {todo} у листи {calendar}", - "You updated todo {todo} in list {calendar}" : "Ажурирали сте подсетник {todo} у листи {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} је обрисао подсетник {todo} из листе {calendar}", - "You solved todo {todo} in list {calendar}" : "Маркирали сте подсетник {todo} као готов у листи {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} је поново отворио подсетник {todo} у листи {calendar}", - "You reopened todo {todo} in list {calendar}" : "Поново сте отворили подсетник {todo} у листи {calendar}", "A <strong>calendar</strong> was modified" : "<strong>Календар</strong> је измењен", "A calendar <strong>event</strong> was modified" : "<strong>Догађај</strong> из календара је измењен", - "A calendar <strong>todo</strong> was modified" : "<strong>Подсетник</strong> из календара је измењен", "Contact birthdays" : "Рођендани контаката", "Death of %s" : " %s смрт", "Calendar:" : "Календар:", @@ -112,6 +100,18 @@ OC.L10N.register( "Are you accepting the invitation?" : "Да ли прихватате позивницу?", "Tentative" : "Условна потврда", "Comment" : "Коментар", - "Your attendance was updated successfully." : "Ваше присуство је успешно ажурирано." + "Your attendance was updated successfully." : "Ваше присуство је успешно ажурирано.", + "Todos" : "Подсетници", + "{actor} created todo {todo} in list {calendar}" : "{actor} је направио подсетник {todo} у листи {calendar}", + "You created todo {todo} in list {calendar}" : "Креирали сте подсетник {todo} у листи {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} је обрисао подсетник {todo} из листе {calendar}", + "You deleted todo {todo} from list {calendar}" : "Обрисали сте подсетник {todo} из листе {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} је ажурирао подсетник {todo} у листи {calendar}", + "You updated todo {todo} in list {calendar}" : "Ажурирали сте подсетник {todo} у листи {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} је обрисао подсетник {todo} из листе {calendar}", + "You solved todo {todo} in list {calendar}" : "Маркирали сте подсетник {todo} као готов у листи {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} је поново отворио подсетник {todo} у листи {calendar}", + "You reopened todo {todo} in list {calendar}" : "Поново сте отворили подсетник {todo} у листи {calendar}", + "A calendar <strong>todo</strong> was modified" : "<strong>Подсетник</strong> из календара је измењен" }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/apps/dav/l10n/sr.json b/apps/dav/l10n/sr.json index b0d59d93232..9fd5276b852 100644 --- a/apps/dav/l10n/sr.json +++ b/apps/dav/l10n/sr.json @@ -1,6 +1,5 @@ { "translations": { "Calendar" : "Календар", - "Todos" : "Подсетници", "Personal" : "Лично", "{actor} created calendar {calendar}" : "{actor} направи календар {calendar}", "You created calendar {calendar}" : "Направили сте календар {calendar}", @@ -29,19 +28,8 @@ "{actor} updated event {event} in calendar {calendar}" : "{actor} је ажурирао догађај {event} у календару {calendar}", "You updated event {event} in calendar {calendar}" : "Ажурирали сте догађај {event} у календару {calendar}", "Busy" : "Заузет/а", - "{actor} created todo {todo} in list {calendar}" : "{actor} је направио подсетник {todo} у листи {calendar}", - "You created todo {todo} in list {calendar}" : "Креирали сте подсетник {todo} у листи {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} је обрисао подсетник {todo} из листе {calendar}", - "You deleted todo {todo} from list {calendar}" : "Обрисали сте подсетник {todo} из листе {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} је ажурирао подсетник {todo} у листи {calendar}", - "You updated todo {todo} in list {calendar}" : "Ажурирали сте подсетник {todo} у листи {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} је обрисао подсетник {todo} из листе {calendar}", - "You solved todo {todo} in list {calendar}" : "Маркирали сте подсетник {todo} као готов у листи {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} је поново отворио подсетник {todo} у листи {calendar}", - "You reopened todo {todo} in list {calendar}" : "Поново сте отворили подсетник {todo} у листи {calendar}", "A <strong>calendar</strong> was modified" : "<strong>Календар</strong> је измењен", "A calendar <strong>event</strong> was modified" : "<strong>Догађај</strong> из календара је измењен", - "A calendar <strong>todo</strong> was modified" : "<strong>Подсетник</strong> из календара је измењен", "Contact birthdays" : "Рођендани контаката", "Death of %s" : " %s смрт", "Calendar:" : "Календар:", @@ -110,6 +98,18 @@ "Are you accepting the invitation?" : "Да ли прихватате позивницу?", "Tentative" : "Условна потврда", "Comment" : "Коментар", - "Your attendance was updated successfully." : "Ваше присуство је успешно ажурирано." + "Your attendance was updated successfully." : "Ваше присуство је успешно ажурирано.", + "Todos" : "Подсетници", + "{actor} created todo {todo} in list {calendar}" : "{actor} је направио подсетник {todo} у листи {calendar}", + "You created todo {todo} in list {calendar}" : "Креирали сте подсетник {todo} у листи {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} је обрисао подсетник {todo} из листе {calendar}", + "You deleted todo {todo} from list {calendar}" : "Обрисали сте подсетник {todo} из листе {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} је ажурирао подсетник {todo} у листи {calendar}", + "You updated todo {todo} in list {calendar}" : "Ажурирали сте подсетник {todo} у листи {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} је обрисао подсетник {todo} из листе {calendar}", + "You solved todo {todo} in list {calendar}" : "Маркирали сте подсетник {todo} као готов у листи {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} је поново отворио подсетник {todo} у листи {calendar}", + "You reopened todo {todo} in list {calendar}" : "Поново сте отворили подсетник {todo} у листи {calendar}", + "A calendar <strong>todo</strong> was modified" : "<strong>Подсетник</strong> из календара је измењен" },"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/apps/dav/l10n/sv.js b/apps/dav/l10n/sv.js index 6508c8fc33b..5bcc0d621ae 100644 --- a/apps/dav/l10n/sv.js +++ b/apps/dav/l10n/sv.js @@ -2,7 +2,6 @@ OC.L10N.register( "dav", { "Calendar" : "Kalender", - "Todos" : "Uppgifter", "Personal" : "Privat", "{actor} created calendar {calendar}" : "{actor} skapade kalender {calendar}", "You created calendar {calendar}" : "Du skapade kalender {calendar}", @@ -35,20 +34,9 @@ OC.L10N.register( "{actor} restored event {event} of calendar {calendar}" : "{actor} återställde händelsen {event} i kalendern {calendar}", "You restored event {event} of calendar {calendar}" : "Du återställde händelsen {event} i kalendern {calendar}", "Busy" : "Upptagen", - "{actor} created todo {todo} in list {calendar}" : "{actor} skapade uppgift {todo} i listan {calendar}", - "You created todo {todo} in list {calendar}" : "Du skapade uppgift {todo} i listan {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} tog bort uppgift {todo} från listan {calendar}", - "You deleted todo {todo} from list {calendar}" : "Du tog bort uppgift {todo} från listan {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} uppdaterade uppgift {todo} i listan {calendar}", - "You updated todo {todo} in list {calendar}" : "Du uppdaterade uppgift {todo} i listan {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} löste uppgift {todo} i listan {calendar}", - "You solved todo {todo} in list {calendar}" : "Du löste uppgift {todo} i listan {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} återupptog uppgift {todo} i listan {calendar}", - "You reopened todo {todo} in list {calendar}" : "Du återupptog uppgift {todo} i listan {calendar}", "Calendar, contacts and tasks" : "Kalender, kontakter och uppgifter", "A <strong>calendar</strong> was modified" : "En <strong>kalender</strong> modifierades", "A calendar <strong>event</strong> was modified" : "En kalender-<strong>händelse</strong> modifierades", - "A calendar <strong>todo</strong> was modified" : "En kalender <strong>uppgift</strong> modifierades", "Contact birthdays" : "Födelsedagar", "Death of %s" : "Död av %s", "Calendar:" : "Kalender:", @@ -151,6 +139,18 @@ OC.L10N.register( "Tentative" : "Preliminärt", "Number of guests" : "Antal gäster", "Comment" : "Kommentar", - "Your attendance was updated successfully." : "Dina närvaro uppdaterades." + "Your attendance was updated successfully." : "Dina närvaro uppdaterades.", + "Todos" : "Uppgifter", + "{actor} created todo {todo} in list {calendar}" : "{actor} skapade uppgift {todo} i listan {calendar}", + "You created todo {todo} in list {calendar}" : "Du skapade uppgift {todo} i listan {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} tog bort uppgift {todo} från listan {calendar}", + "You deleted todo {todo} from list {calendar}" : "Du tog bort uppgift {todo} från listan {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} uppdaterade uppgift {todo} i listan {calendar}", + "You updated todo {todo} in list {calendar}" : "Du uppdaterade uppgift {todo} i listan {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} löste uppgift {todo} i listan {calendar}", + "You solved todo {todo} in list {calendar}" : "Du löste uppgift {todo} i listan {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} återupptog uppgift {todo} i listan {calendar}", + "You reopened todo {todo} in list {calendar}" : "Du återupptog uppgift {todo} i listan {calendar}", + "A calendar <strong>todo</strong> was modified" : "En kalender <strong>uppgift</strong> modifierades" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/dav/l10n/sv.json b/apps/dav/l10n/sv.json index 8040b5f3f34..e4bbb46e490 100644 --- a/apps/dav/l10n/sv.json +++ b/apps/dav/l10n/sv.json @@ -1,6 +1,5 @@ { "translations": { "Calendar" : "Kalender", - "Todos" : "Uppgifter", "Personal" : "Privat", "{actor} created calendar {calendar}" : "{actor} skapade kalender {calendar}", "You created calendar {calendar}" : "Du skapade kalender {calendar}", @@ -33,20 +32,9 @@ "{actor} restored event {event} of calendar {calendar}" : "{actor} återställde händelsen {event} i kalendern {calendar}", "You restored event {event} of calendar {calendar}" : "Du återställde händelsen {event} i kalendern {calendar}", "Busy" : "Upptagen", - "{actor} created todo {todo} in list {calendar}" : "{actor} skapade uppgift {todo} i listan {calendar}", - "You created todo {todo} in list {calendar}" : "Du skapade uppgift {todo} i listan {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} tog bort uppgift {todo} från listan {calendar}", - "You deleted todo {todo} from list {calendar}" : "Du tog bort uppgift {todo} från listan {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} uppdaterade uppgift {todo} i listan {calendar}", - "You updated todo {todo} in list {calendar}" : "Du uppdaterade uppgift {todo} i listan {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} löste uppgift {todo} i listan {calendar}", - "You solved todo {todo} in list {calendar}" : "Du löste uppgift {todo} i listan {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} återupptog uppgift {todo} i listan {calendar}", - "You reopened todo {todo} in list {calendar}" : "Du återupptog uppgift {todo} i listan {calendar}", "Calendar, contacts and tasks" : "Kalender, kontakter och uppgifter", "A <strong>calendar</strong> was modified" : "En <strong>kalender</strong> modifierades", "A calendar <strong>event</strong> was modified" : "En kalender-<strong>händelse</strong> modifierades", - "A calendar <strong>todo</strong> was modified" : "En kalender <strong>uppgift</strong> modifierades", "Contact birthdays" : "Födelsedagar", "Death of %s" : "Död av %s", "Calendar:" : "Kalender:", @@ -149,6 +137,18 @@ "Tentative" : "Preliminärt", "Number of guests" : "Antal gäster", "Comment" : "Kommentar", - "Your attendance was updated successfully." : "Dina närvaro uppdaterades." + "Your attendance was updated successfully." : "Dina närvaro uppdaterades.", + "Todos" : "Uppgifter", + "{actor} created todo {todo} in list {calendar}" : "{actor} skapade uppgift {todo} i listan {calendar}", + "You created todo {todo} in list {calendar}" : "Du skapade uppgift {todo} i listan {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} tog bort uppgift {todo} från listan {calendar}", + "You deleted todo {todo} from list {calendar}" : "Du tog bort uppgift {todo} från listan {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} uppdaterade uppgift {todo} i listan {calendar}", + "You updated todo {todo} in list {calendar}" : "Du uppdaterade uppgift {todo} i listan {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} löste uppgift {todo} i listan {calendar}", + "You solved todo {todo} in list {calendar}" : "Du löste uppgift {todo} i listan {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} återupptog uppgift {todo} i listan {calendar}", + "You reopened todo {todo} in list {calendar}" : "Du återupptog uppgift {todo} i listan {calendar}", + "A calendar <strong>todo</strong> was modified" : "En kalender <strong>uppgift</strong> modifierades" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/dav/l10n/tr.js b/apps/dav/l10n/tr.js index bd11fb3dada..a7c71588df5 100644 --- a/apps/dav/l10n/tr.js +++ b/apps/dav/l10n/tr.js @@ -2,7 +2,7 @@ OC.L10N.register( "dav", { "Calendar" : "Takvim", - "Todos" : "Yapılacak işler", + "To-dos" : "Yapılacak işler", "Personal" : "Kişisel", "{actor} created calendar {calendar}" : "{actor}, {calendar} takvimini ekledi", "You created calendar {calendar}" : "{calendar} takvimini eklediniz", @@ -32,23 +32,27 @@ OC.L10N.register( "You deleted event {event} from calendar {calendar}" : "{calendar} takviminden {event} etkinliğini sildiniz", "{actor} updated event {event} in calendar {calendar}" : "{actor}, {calendar} takvimindeki {event} etkinliğini güncelledi", "You updated event {event} in calendar {calendar}" : "{calendar} takvimindeki {event} etkinliğini güncellediniz", + "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{actor}, {event} etkinliğini {sourceCalendar} takviminden {targetCalendar} takvimine taşıdı", + "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{event} etkinliğini {sourceCalendar} takviminden {targetCalendar} takvimine taşıdınız", "{actor} restored event {event} of calendar {calendar}" : "{actor}, {calendar} takvimindeki {event} etkinliğini geri yükledi", "You restored event {event} of calendar {calendar}" : "{calendar} takvimindeki {event} etkinliğini geri yüklediniz", "Busy" : "Meşgul", - "{actor} created todo {todo} in list {calendar}" : "{actor}, {calendar} takvimi listesine {todo} yapılacak işini ekledi", - "You created todo {todo} in list {calendar}" : "{calendar} takvimi listesine {todo} yapılacak işini eklediniz", - "{actor} deleted todo {todo} from list {calendar}" : "{actor}, {calendar} takvimi listesinden {todo} yapılacak işini sildi", - "You deleted todo {todo} from list {calendar}" : "{calendar} takvimi listesinden {todo} yapılacak işini sildiniz", - "{actor} updated todo {todo} in list {calendar}" : "{actor}, {calendar} takvimi listesindeki {todo} yapılacak işini güncelledi", - "You updated todo {todo} in list {calendar}" : "{calendar} takvimi listesindeki {todo} yapılacak işini güncellediniz", - "{actor} solved todo {todo} in list {calendar}" : "{actor}, {calendar} takvimi listesindeki {todo} yapılacak işini tamamladı", - "You solved todo {todo} in list {calendar}" : "{calendar} takvimi listesindeki {todo} yapılacak işini tamamladınız", - "{actor} reopened todo {todo} in list {calendar}" : "{actor}, {calendar} takvimi listesindeki {todo} yapılacak işini yeniden başlattı", - "You reopened todo {todo} in list {calendar}" : "{calendar} takvimi listesindeki {todo} yapılacak işini yeniden başlattınız", + "{actor} created to-do {todo} in list {calendar}" : "{actor}, {calendar} takvimi listesine {todo} yapılacak işini ekledi", + "You created to-do {todo} in list {calendar}" : "{calendar} takvimi listesine {todo} yapılacak işini eklediniz", + "{actor} deleted to-do {todo} from list {calendar}" : "{actor}, {calendar} takvimi listesinden {todo} yapılacak işini sildi", + "You deleted to-do {todo} from list {calendar}" : "{calendar} takvimi listesinden {todo} yapılacak işini sildiniz", + "{actor} updated to-do {todo} in list {calendar}" : "{actor}, {calendar} takvimi listesindeki {todo} yapılacak işini güncelledi", + "You updated to-do {todo} in list {calendar}" : "{calendar} takvimi listesindeki {todo} yapılacak işini güncellediniz", + "{actor} solved to-do {todo} in list {calendar}" : "{actor}, {calendar} takvimi listesindeki {todo} yapılacak işini tamamladı", + "You solved to-do {todo} in list {calendar}" : "{calendar} takvimi listesindeki {todo} yapılacak işini tamamladınız", + "{actor} reopened to-do {todo} in list {calendar}" : "{actor}, {calendar} takvimi listesindeki {todo} yapılacak işini yeniden başlattı", + "You reopened to-do {todo} in list {calendar}" : "{calendar} takvimi listesindeki {todo} yapılacak işini yeniden başlattınız", + "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor}, {todo} yapılacak işini {sourceCalendar} listesinden {targetCalendar} listesine taşıdı", + "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{todo} yapılacak işini {sourceCalendar} listesinden {targetCalendar} listesine taşıdınız", "Calendar, contacts and tasks" : "Takvim, kişiler ve görevler", "A <strong>calendar</strong> was modified" : "Bir <strong>takvim</strong> düzenlendi", "A calendar <strong>event</strong> was modified" : "Bir takvim <strong>etkinliği</strong> düzenlendi", - "A calendar <strong>todo</strong> was modified" : "Bir takvim <strong>yapılacak işi</strong> düzenlendi", + "A calendar <strong>to-do</strong> was modified" : "Bir takvim <strong>yapılacak işi</strong> düzenlendi", "Contact birthdays" : "Kişi doğum günleri", "Death of %s" : "%s ölümü", "Calendar:" : "Takvim:", @@ -155,6 +159,7 @@ OC.L10N.register( "Friday" : "Cuma", "Saturday" : "Cumartesi", "Sunday" : "Pazar", + "Automatically set user status to \"Do not disturb\" outside of availability to mute all notifications." : "Tüm bildirimleri sessize almak için, uygunluk durumu dışında kullanıcı durumu otomatik olarak \"Rahatsız etmeyin\" olarak ayarlanır.", "Save" : "Kaydet", "Failed to load availability" : "Uygunluk yüklenemedi", "Saved availability" : "Uygunluk kaydedildi", @@ -177,6 +182,18 @@ OC.L10N.register( "Tentative" : "Kesin değil", "Number of guests" : "Konuk sayısı", "Comment" : "Yorum", - "Your attendance was updated successfully." : "Katılımınız güncellendi." + "Your attendance was updated successfully." : "Katılımınız güncellendi.", + "Todos" : "Yapılacak işler", + "{actor} created todo {todo} in list {calendar}" : "{actor}, {calendar} takvimi listesine {todo} yapılacak işini ekledi", + "You created todo {todo} in list {calendar}" : "{calendar} takvimi listesine {todo} yapılacak işini eklediniz", + "{actor} deleted todo {todo} from list {calendar}" : "{actor}, {calendar} takvimi listesinden {todo} yapılacak işini sildi", + "You deleted todo {todo} from list {calendar}" : "{calendar} takvimi listesinden {todo} yapılacak işini sildiniz", + "{actor} updated todo {todo} in list {calendar}" : "{actor}, {calendar} takvimi listesindeki {todo} yapılacak işini güncelledi", + "You updated todo {todo} in list {calendar}" : "{calendar} takvimi listesindeki {todo} yapılacak işini güncellediniz", + "{actor} solved todo {todo} in list {calendar}" : "{actor}, {calendar} takvimi listesindeki {todo} yapılacak işini tamamladı", + "You solved todo {todo} in list {calendar}" : "{calendar} takvimi listesindeki {todo} yapılacak işini tamamladınız", + "{actor} reopened todo {todo} in list {calendar}" : "{actor}, {calendar} takvimi listesindeki {todo} yapılacak işini yeniden başlattı", + "You reopened todo {todo} in list {calendar}" : "{calendar} takvimi listesindeki {todo} yapılacak işini yeniden başlattınız", + "A calendar <strong>todo</strong> was modified" : "Bir takvim <strong>yapılacak işi</strong> düzenlendi" }, "nplurals=2; plural=(n > 1);"); diff --git a/apps/dav/l10n/tr.json b/apps/dav/l10n/tr.json index 5767d918f7a..042418f79ec 100644 --- a/apps/dav/l10n/tr.json +++ b/apps/dav/l10n/tr.json @@ -1,6 +1,6 @@ { "translations": { "Calendar" : "Takvim", - "Todos" : "Yapılacak işler", + "To-dos" : "Yapılacak işler", "Personal" : "Kişisel", "{actor} created calendar {calendar}" : "{actor}, {calendar} takvimini ekledi", "You created calendar {calendar}" : "{calendar} takvimini eklediniz", @@ -30,23 +30,27 @@ "You deleted event {event} from calendar {calendar}" : "{calendar} takviminden {event} etkinliğini sildiniz", "{actor} updated event {event} in calendar {calendar}" : "{actor}, {calendar} takvimindeki {event} etkinliğini güncelledi", "You updated event {event} in calendar {calendar}" : "{calendar} takvimindeki {event} etkinliğini güncellediniz", + "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{actor}, {event} etkinliğini {sourceCalendar} takviminden {targetCalendar} takvimine taşıdı", + "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{event} etkinliğini {sourceCalendar} takviminden {targetCalendar} takvimine taşıdınız", "{actor} restored event {event} of calendar {calendar}" : "{actor}, {calendar} takvimindeki {event} etkinliğini geri yükledi", "You restored event {event} of calendar {calendar}" : "{calendar} takvimindeki {event} etkinliğini geri yüklediniz", "Busy" : "Meşgul", - "{actor} created todo {todo} in list {calendar}" : "{actor}, {calendar} takvimi listesine {todo} yapılacak işini ekledi", - "You created todo {todo} in list {calendar}" : "{calendar} takvimi listesine {todo} yapılacak işini eklediniz", - "{actor} deleted todo {todo} from list {calendar}" : "{actor}, {calendar} takvimi listesinden {todo} yapılacak işini sildi", - "You deleted todo {todo} from list {calendar}" : "{calendar} takvimi listesinden {todo} yapılacak işini sildiniz", - "{actor} updated todo {todo} in list {calendar}" : "{actor}, {calendar} takvimi listesindeki {todo} yapılacak işini güncelledi", - "You updated todo {todo} in list {calendar}" : "{calendar} takvimi listesindeki {todo} yapılacak işini güncellediniz", - "{actor} solved todo {todo} in list {calendar}" : "{actor}, {calendar} takvimi listesindeki {todo} yapılacak işini tamamladı", - "You solved todo {todo} in list {calendar}" : "{calendar} takvimi listesindeki {todo} yapılacak işini tamamladınız", - "{actor} reopened todo {todo} in list {calendar}" : "{actor}, {calendar} takvimi listesindeki {todo} yapılacak işini yeniden başlattı", - "You reopened todo {todo} in list {calendar}" : "{calendar} takvimi listesindeki {todo} yapılacak işini yeniden başlattınız", + "{actor} created to-do {todo} in list {calendar}" : "{actor}, {calendar} takvimi listesine {todo} yapılacak işini ekledi", + "You created to-do {todo} in list {calendar}" : "{calendar} takvimi listesine {todo} yapılacak işini eklediniz", + "{actor} deleted to-do {todo} from list {calendar}" : "{actor}, {calendar} takvimi listesinden {todo} yapılacak işini sildi", + "You deleted to-do {todo} from list {calendar}" : "{calendar} takvimi listesinden {todo} yapılacak işini sildiniz", + "{actor} updated to-do {todo} in list {calendar}" : "{actor}, {calendar} takvimi listesindeki {todo} yapılacak işini güncelledi", + "You updated to-do {todo} in list {calendar}" : "{calendar} takvimi listesindeki {todo} yapılacak işini güncellediniz", + "{actor} solved to-do {todo} in list {calendar}" : "{actor}, {calendar} takvimi listesindeki {todo} yapılacak işini tamamladı", + "You solved to-do {todo} in list {calendar}" : "{calendar} takvimi listesindeki {todo} yapılacak işini tamamladınız", + "{actor} reopened to-do {todo} in list {calendar}" : "{actor}, {calendar} takvimi listesindeki {todo} yapılacak işini yeniden başlattı", + "You reopened to-do {todo} in list {calendar}" : "{calendar} takvimi listesindeki {todo} yapılacak işini yeniden başlattınız", + "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor}, {todo} yapılacak işini {sourceCalendar} listesinden {targetCalendar} listesine taşıdı", + "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{todo} yapılacak işini {sourceCalendar} listesinden {targetCalendar} listesine taşıdınız", "Calendar, contacts and tasks" : "Takvim, kişiler ve görevler", "A <strong>calendar</strong> was modified" : "Bir <strong>takvim</strong> düzenlendi", "A calendar <strong>event</strong> was modified" : "Bir takvim <strong>etkinliği</strong> düzenlendi", - "A calendar <strong>todo</strong> was modified" : "Bir takvim <strong>yapılacak işi</strong> düzenlendi", + "A calendar <strong>to-do</strong> was modified" : "Bir takvim <strong>yapılacak işi</strong> düzenlendi", "Contact birthdays" : "Kişi doğum günleri", "Death of %s" : "%s ölümü", "Calendar:" : "Takvim:", @@ -153,6 +157,7 @@ "Friday" : "Cuma", "Saturday" : "Cumartesi", "Sunday" : "Pazar", + "Automatically set user status to \"Do not disturb\" outside of availability to mute all notifications." : "Tüm bildirimleri sessize almak için, uygunluk durumu dışında kullanıcı durumu otomatik olarak \"Rahatsız etmeyin\" olarak ayarlanır.", "Save" : "Kaydet", "Failed to load availability" : "Uygunluk yüklenemedi", "Saved availability" : "Uygunluk kaydedildi", @@ -175,6 +180,18 @@ "Tentative" : "Kesin değil", "Number of guests" : "Konuk sayısı", "Comment" : "Yorum", - "Your attendance was updated successfully." : "Katılımınız güncellendi." + "Your attendance was updated successfully." : "Katılımınız güncellendi.", + "Todos" : "Yapılacak işler", + "{actor} created todo {todo} in list {calendar}" : "{actor}, {calendar} takvimi listesine {todo} yapılacak işini ekledi", + "You created todo {todo} in list {calendar}" : "{calendar} takvimi listesine {todo} yapılacak işini eklediniz", + "{actor} deleted todo {todo} from list {calendar}" : "{actor}, {calendar} takvimi listesinden {todo} yapılacak işini sildi", + "You deleted todo {todo} from list {calendar}" : "{calendar} takvimi listesinden {todo} yapılacak işini sildiniz", + "{actor} updated todo {todo} in list {calendar}" : "{actor}, {calendar} takvimi listesindeki {todo} yapılacak işini güncelledi", + "You updated todo {todo} in list {calendar}" : "{calendar} takvimi listesindeki {todo} yapılacak işini güncellediniz", + "{actor} solved todo {todo} in list {calendar}" : "{actor}, {calendar} takvimi listesindeki {todo} yapılacak işini tamamladı", + "You solved todo {todo} in list {calendar}" : "{calendar} takvimi listesindeki {todo} yapılacak işini tamamladınız", + "{actor} reopened todo {todo} in list {calendar}" : "{actor}, {calendar} takvimi listesindeki {todo} yapılacak işini yeniden başlattı", + "You reopened todo {todo} in list {calendar}" : "{calendar} takvimi listesindeki {todo} yapılacak işini yeniden başlattınız", + "A calendar <strong>todo</strong> was modified" : "Bir takvim <strong>yapılacak işi</strong> düzenlendi" },"pluralForm" :"nplurals=2; plural=(n > 1);" }
\ No newline at end of file diff --git a/apps/dav/l10n/uk.js b/apps/dav/l10n/uk.js index 22de431e2e0..a4e95881167 100644 --- a/apps/dav/l10n/uk.js +++ b/apps/dav/l10n/uk.js @@ -2,7 +2,6 @@ OC.L10N.register( "dav", { "Calendar" : "Календар", - "Todos" : "До роботи", "Personal" : "Особисте", "{actor} created calendar {calendar}" : "{actor} створив календар {calendar}", "You created calendar {calendar}" : "Ви створили календар {calendar}", @@ -31,19 +30,8 @@ OC.L10N.register( "{actor} updated event {event} in calendar {calendar}" : "{actor} оновив подію {event} у календарі {calendar}", "You updated event {event} in calendar {calendar}" : "Ви оновили подію {event} у календарі {calendar}", "Busy" : "Зайнято", - "{actor} created todo {todo} in list {calendar}" : "{actor} створив завдання {todo} у списку {calendar}", - "You created todo {todo} in list {calendar}" : "Ви створили завдання {todo} у списку {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} вилучили завдання {todo} зі списку {calendar}", - "You deleted todo {todo} from list {calendar}" : "Ви вилучили завдання {todo} зі списку {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} оновив завдання {todo} у списку {calendar}", - "You updated todo {todo} in list {calendar}" : "Ви оновили завдання {todo} у списку {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} виконав завдання {todo} зі списку {calendar}", - "You solved todo {todo} in list {calendar}" : "Ви виконали завдання {todo} зі списку {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} повторно відкрив завдання {todo} у списку {calendar}", - "You reopened todo {todo} in list {calendar}" : "Ви повторно відкрили завдання {todo} у списку {calendar}", "A <strong>calendar</strong> was modified" : "<strong>Календар</strong> був змінений", "A calendar <strong>event</strong> was modified" : "Календарна <strong>подія</strong> була змінена", - "A calendar <strong>todo</strong> was modified" : "Календарне <strong>завдання</strong> було змінене", "Contact birthdays" : "Дні народження контактів", "Death of %s" : "Смерть %s", "Calendar:" : "Календар:", @@ -103,6 +91,18 @@ OC.L10N.register( "Are you accepting the invitation?" : "Чи приймаєте ви запрошення?", "Tentative" : "Попередній", "Comment" : "Коментар", - "Your attendance was updated successfully." : "Ваша участь успішно оновлена." + "Your attendance was updated successfully." : "Ваша участь успішно оновлена.", + "Todos" : "До роботи", + "{actor} created todo {todo} in list {calendar}" : "{actor} створив завдання {todo} у списку {calendar}", + "You created todo {todo} in list {calendar}" : "Ви створили завдання {todo} у списку {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} вилучили завдання {todo} зі списку {calendar}", + "You deleted todo {todo} from list {calendar}" : "Ви вилучили завдання {todo} зі списку {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} оновив завдання {todo} у списку {calendar}", + "You updated todo {todo} in list {calendar}" : "Ви оновили завдання {todo} у списку {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} виконав завдання {todo} зі списку {calendar}", + "You solved todo {todo} in list {calendar}" : "Ви виконали завдання {todo} зі списку {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} повторно відкрив завдання {todo} у списку {calendar}", + "You reopened todo {todo} in list {calendar}" : "Ви повторно відкрили завдання {todo} у списку {calendar}", + "A calendar <strong>todo</strong> was modified" : "Календарне <strong>завдання</strong> було змінене" }, "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/apps/dav/l10n/uk.json b/apps/dav/l10n/uk.json index f1ec48b299b..a422698345e 100644 --- a/apps/dav/l10n/uk.json +++ b/apps/dav/l10n/uk.json @@ -1,6 +1,5 @@ { "translations": { "Calendar" : "Календар", - "Todos" : "До роботи", "Personal" : "Особисте", "{actor} created calendar {calendar}" : "{actor} створив календар {calendar}", "You created calendar {calendar}" : "Ви створили календар {calendar}", @@ -29,19 +28,8 @@ "{actor} updated event {event} in calendar {calendar}" : "{actor} оновив подію {event} у календарі {calendar}", "You updated event {event} in calendar {calendar}" : "Ви оновили подію {event} у календарі {calendar}", "Busy" : "Зайнято", - "{actor} created todo {todo} in list {calendar}" : "{actor} створив завдання {todo} у списку {calendar}", - "You created todo {todo} in list {calendar}" : "Ви створили завдання {todo} у списку {calendar}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} вилучили завдання {todo} зі списку {calendar}", - "You deleted todo {todo} from list {calendar}" : "Ви вилучили завдання {todo} зі списку {calendar}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} оновив завдання {todo} у списку {calendar}", - "You updated todo {todo} in list {calendar}" : "Ви оновили завдання {todo} у списку {calendar}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} виконав завдання {todo} зі списку {calendar}", - "You solved todo {todo} in list {calendar}" : "Ви виконали завдання {todo} зі списку {calendar}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} повторно відкрив завдання {todo} у списку {calendar}", - "You reopened todo {todo} in list {calendar}" : "Ви повторно відкрили завдання {todo} у списку {calendar}", "A <strong>calendar</strong> was modified" : "<strong>Календар</strong> був змінений", "A calendar <strong>event</strong> was modified" : "Календарна <strong>подія</strong> була змінена", - "A calendar <strong>todo</strong> was modified" : "Календарне <strong>завдання</strong> було змінене", "Contact birthdays" : "Дні народження контактів", "Death of %s" : "Смерть %s", "Calendar:" : "Календар:", @@ -101,6 +89,18 @@ "Are you accepting the invitation?" : "Чи приймаєте ви запрошення?", "Tentative" : "Попередній", "Comment" : "Коментар", - "Your attendance was updated successfully." : "Ваша участь успішно оновлена." + "Your attendance was updated successfully." : "Ваша участь успішно оновлена.", + "Todos" : "До роботи", + "{actor} created todo {todo} in list {calendar}" : "{actor} створив завдання {todo} у списку {calendar}", + "You created todo {todo} in list {calendar}" : "Ви створили завдання {todo} у списку {calendar}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} вилучили завдання {todo} зі списку {calendar}", + "You deleted todo {todo} from list {calendar}" : "Ви вилучили завдання {todo} зі списку {calendar}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} оновив завдання {todo} у списку {calendar}", + "You updated todo {todo} in list {calendar}" : "Ви оновили завдання {todo} у списку {calendar}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} виконав завдання {todo} зі списку {calendar}", + "You solved todo {todo} in list {calendar}" : "Ви виконали завдання {todo} зі списку {calendar}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} повторно відкрив завдання {todo} у списку {calendar}", + "You reopened todo {todo} in list {calendar}" : "Ви повторно відкрили завдання {todo} у списку {calendar}", + "A calendar <strong>todo</strong> was modified" : "Календарне <strong>завдання</strong> було змінене" },"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/apps/dav/l10n/zh_CN.js b/apps/dav/l10n/zh_CN.js index f661cd87bf9..8a8c9330513 100644 --- a/apps/dav/l10n/zh_CN.js +++ b/apps/dav/l10n/zh_CN.js @@ -2,7 +2,6 @@ OC.L10N.register( "dav", { "Calendar" : "日历", - "Todos" : "待办事项", "Personal" : "个人", "{actor} created calendar {calendar}" : "{actor} 创建了日历 {calendar}", "You created calendar {calendar}" : "您创建的日历 {calendar}", @@ -35,20 +34,9 @@ OC.L10N.register( "{actor} restored event {event} of calendar {calendar}" : "{actor} 还原了事件 {event},它位于日历 {calendar}", "You restored event {event} of calendar {calendar}" : "你还原了事件 {event},它位于日历 {calendar}", "Busy" : "忙碌", - "{actor} created todo {todo} in list {calendar}" : "{actor} 在列表 {calendar} 中创建了待办事项 {todo}", - "You created todo {todo} in list {calendar}" : "您在列表 {calendar} 中创建了待办事项 {todo}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} 在列表 {calendar} 中删除了待办事项 {todo}", - "You deleted todo {todo} from list {calendar}" : "您在列表 {calendar} 中删除了待办事项 {todo}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} 在列表 {calendar} 中更新了待办事项 {todo}", - "You updated todo {todo} in list {calendar}" : "您在列表 {calendar} 中更新了待办事项 {todo}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} 在列表 {calendar} 中解决了待办事项 {todo}", - "You solved todo {todo} in list {calendar}" : "您在列表 {calendar} 中解决了待办事项 {todo}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} 在列表 {calendar} 中重新打开了待办事项 {todo}", - "You reopened todo {todo} in list {calendar}" : "您在列表 {calendar} 中重新打开了待办事项 {todo}", "Calendar, contacts and tasks" : "日历、联系人和任务", "A <strong>calendar</strong> was modified" : "<strong>日历</strong>已经修改", "A calendar <strong>event</strong> was modified" : "日历中<strong>事件</strong>已经修改", - "A calendar <strong>todo</strong> was modified" : "列表中<strong>待办事项</strong>已经修改", "Contact birthdays" : "联系人生日", "Death of %s" : "%s 的忌日", "Calendar:" : "日历:", @@ -144,6 +132,8 @@ OC.L10N.register( "Hence they will not be available immediately after enabling but will show up after some time." : "因此,它们在启用后不会立即可用,但会在一段时间后显示出来。", "Send notifications for events" : "发送事件通知", "Notifications are sent via background jobs, so these must occur often enough." : "通知将通过后台任务发送,所以任务的频率要足够高。", + "Send reminder notifications to calendar sharees as well" : "同时向日历共享者发送提醒通知", + "Reminders are always sent to organizers and attendees." : "始终向组织者和与会者发出提醒。", "Enable notifications for events via push" : "启用推送事件通知", "Also install the {calendarappstoreopen}Calendar app{linkclose}, or {calendardocopen}connect your desktop & mobile for syncing ↗{linkclose}." : "也安装 {calendarappstoreopen}日历应用{linkclose},或者 {calendardocopen}连接您的桌面和移动端同步日历 ↗{linkclose}。", "Please make sure to properly set up {emailopen}the email server{linkclose}." : "请确保正确设置 {emailopen}邮件服务器{linkclose}。", @@ -153,6 +143,18 @@ OC.L10N.register( "Tentative" : "暂定", "Number of guests" : "客人数目", "Comment" : "备注", - "Your attendance was updated successfully." : "您的出席状态更新成功。" + "Your attendance was updated successfully." : "您的出席状态更新成功。", + "Todos" : "待办事项", + "{actor} created todo {todo} in list {calendar}" : "{actor} 在列表 {calendar} 中创建了待办事项 {todo}", + "You created todo {todo} in list {calendar}" : "您在列表 {calendar} 中创建了待办事项 {todo}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} 在列表 {calendar} 中删除了待办事项 {todo}", + "You deleted todo {todo} from list {calendar}" : "您在列表 {calendar} 中删除了待办事项 {todo}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} 在列表 {calendar} 中更新了待办事项 {todo}", + "You updated todo {todo} in list {calendar}" : "您在列表 {calendar} 中更新了待办事项 {todo}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} 在列表 {calendar} 中解决了待办事项 {todo}", + "You solved todo {todo} in list {calendar}" : "您在列表 {calendar} 中解决了待办事项 {todo}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} 在列表 {calendar} 中重新打开了待办事项 {todo}", + "You reopened todo {todo} in list {calendar}" : "您在列表 {calendar} 中重新打开了待办事项 {todo}", + "A calendar <strong>todo</strong> was modified" : "列表中<strong>待办事项</strong>已经修改" }, "nplurals=1; plural=0;"); diff --git a/apps/dav/l10n/zh_CN.json b/apps/dav/l10n/zh_CN.json index 77ddaaf5f58..9f69313b98e 100644 --- a/apps/dav/l10n/zh_CN.json +++ b/apps/dav/l10n/zh_CN.json @@ -1,6 +1,5 @@ { "translations": { "Calendar" : "日历", - "Todos" : "待办事项", "Personal" : "个人", "{actor} created calendar {calendar}" : "{actor} 创建了日历 {calendar}", "You created calendar {calendar}" : "您创建的日历 {calendar}", @@ -33,20 +32,9 @@ "{actor} restored event {event} of calendar {calendar}" : "{actor} 还原了事件 {event},它位于日历 {calendar}", "You restored event {event} of calendar {calendar}" : "你还原了事件 {event},它位于日历 {calendar}", "Busy" : "忙碌", - "{actor} created todo {todo} in list {calendar}" : "{actor} 在列表 {calendar} 中创建了待办事项 {todo}", - "You created todo {todo} in list {calendar}" : "您在列表 {calendar} 中创建了待办事项 {todo}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} 在列表 {calendar} 中删除了待办事项 {todo}", - "You deleted todo {todo} from list {calendar}" : "您在列表 {calendar} 中删除了待办事项 {todo}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} 在列表 {calendar} 中更新了待办事项 {todo}", - "You updated todo {todo} in list {calendar}" : "您在列表 {calendar} 中更新了待办事项 {todo}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} 在列表 {calendar} 中解决了待办事项 {todo}", - "You solved todo {todo} in list {calendar}" : "您在列表 {calendar} 中解决了待办事项 {todo}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} 在列表 {calendar} 中重新打开了待办事项 {todo}", - "You reopened todo {todo} in list {calendar}" : "您在列表 {calendar} 中重新打开了待办事项 {todo}", "Calendar, contacts and tasks" : "日历、联系人和任务", "A <strong>calendar</strong> was modified" : "<strong>日历</strong>已经修改", "A calendar <strong>event</strong> was modified" : "日历中<strong>事件</strong>已经修改", - "A calendar <strong>todo</strong> was modified" : "列表中<strong>待办事项</strong>已经修改", "Contact birthdays" : "联系人生日", "Death of %s" : "%s 的忌日", "Calendar:" : "日历:", @@ -142,6 +130,8 @@ "Hence they will not be available immediately after enabling but will show up after some time." : "因此,它们在启用后不会立即可用,但会在一段时间后显示出来。", "Send notifications for events" : "发送事件通知", "Notifications are sent via background jobs, so these must occur often enough." : "通知将通过后台任务发送,所以任务的频率要足够高。", + "Send reminder notifications to calendar sharees as well" : "同时向日历共享者发送提醒通知", + "Reminders are always sent to organizers and attendees." : "始终向组织者和与会者发出提醒。", "Enable notifications for events via push" : "启用推送事件通知", "Also install the {calendarappstoreopen}Calendar app{linkclose}, or {calendardocopen}connect your desktop & mobile for syncing ↗{linkclose}." : "也安装 {calendarappstoreopen}日历应用{linkclose},或者 {calendardocopen}连接您的桌面和移动端同步日历 ↗{linkclose}。", "Please make sure to properly set up {emailopen}the email server{linkclose}." : "请确保正确设置 {emailopen}邮件服务器{linkclose}。", @@ -151,6 +141,18 @@ "Tentative" : "暂定", "Number of guests" : "客人数目", "Comment" : "备注", - "Your attendance was updated successfully." : "您的出席状态更新成功。" + "Your attendance was updated successfully." : "您的出席状态更新成功。", + "Todos" : "待办事项", + "{actor} created todo {todo} in list {calendar}" : "{actor} 在列表 {calendar} 中创建了待办事项 {todo}", + "You created todo {todo} in list {calendar}" : "您在列表 {calendar} 中创建了待办事项 {todo}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} 在列表 {calendar} 中删除了待办事项 {todo}", + "You deleted todo {todo} from list {calendar}" : "您在列表 {calendar} 中删除了待办事项 {todo}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} 在列表 {calendar} 中更新了待办事项 {todo}", + "You updated todo {todo} in list {calendar}" : "您在列表 {calendar} 中更新了待办事项 {todo}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} 在列表 {calendar} 中解决了待办事项 {todo}", + "You solved todo {todo} in list {calendar}" : "您在列表 {calendar} 中解决了待办事项 {todo}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} 在列表 {calendar} 中重新打开了待办事项 {todo}", + "You reopened todo {todo} in list {calendar}" : "您在列表 {calendar} 中重新打开了待办事项 {todo}", + "A calendar <strong>todo</strong> was modified" : "列表中<strong>待办事项</strong>已经修改" },"pluralForm" :"nplurals=1; plural=0;" }
\ No newline at end of file diff --git a/apps/dav/l10n/zh_HK.js b/apps/dav/l10n/zh_HK.js index abc214c3cdf..4dc2fbd420e 100644 --- a/apps/dav/l10n/zh_HK.js +++ b/apps/dav/l10n/zh_HK.js @@ -2,7 +2,7 @@ OC.L10N.register( "dav", { "Calendar" : "日曆", - "Todos" : "待辦事項", + "To-dos" : "待辦事項", "Personal" : "個人", "{actor} created calendar {calendar}" : "{actor} 建立了日曆 {calendar}", "You created calendar {calendar}" : "您建立了日曆 {calendar}", @@ -32,23 +32,27 @@ OC.L10N.register( "You deleted event {event} from calendar {calendar}" : "您從日曆 {calendar} 中刪除了活動 {event}", "{actor} updated event {event} in calendar {calendar}" : "{actor} 更新了日曆 {calendar} 中的活動 {event}", "You updated event {event} in calendar {calendar}" : "您更新了日曆 {calendar} 中的活動 {event}", + "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{actor} 將活動 {event} 從日曆 {sourceCalendar} 移到日曆 {targetCalendar}", + "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "您將活動 {event} 從日曆 {sourceCalendar} 移到日曆 {targetCalendar}", "{actor} restored event {event} of calendar {calendar}" : "{actor} 復原了日曆 {calendar} 的活動 {event}", "You restored event {event} of calendar {calendar}" : "您復原了日曆 {calendar} 的活動 {event}", "Busy" : "忙碌中", - "{actor} created todo {todo} in list {calendar}" : "{actor} 在任務列表 {calendar} 中建立了待辦事項 {todo}", - "You created todo {todo} in list {calendar}" : "您在任務列表 {calendar} 中建立了待辦事項 {todo}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} 從任務列表 {calendar} 中刪除了待辦事項 {todo}", - "You deleted todo {todo} from list {calendar}" : "您從任務列表 {calendar} 中刪除了待辦事項 {todo}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} 從任務列表 {calendar} 中更新了待辦事項 {todo}", - "You updated todo {todo} in list {calendar}" : "您在任務列表 {calendar} 中更新了待辦事項 {todo}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} 解决了任務列表 {calendar} 中的代辦事項 {todo}", - "You solved todo {todo} in list {calendar}" : "您解决了任務列表 {calendar} 中的代辦事項 {todo}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} 重新開啟了任務列表 {calendar} 中的代辦事項 {todo}", - "You reopened todo {todo} in list {calendar}" : "你重新開啟了 {calendar} 清單中的代辦事項 {todo}", + "{actor} created to-do {todo} in list {calendar}" : "{actor} 在任務清單 {calendar} 中建立了待辦事項 {todo}", + "You created to-do {todo} in list {calendar}" : "您在任務清單 {calendar} 中建立了待辦事項 {todo}", + "{actor} deleted to-do {todo} from list {calendar}" : "{actor} 從任務清單 {calendar} 中刪除了待辦事項 {todo}", + "You deleted to-do {todo} from list {calendar}" : "您從任務清單 {calendar} 中刪除了待辦事項 {todo}", + "{actor} updated to-do {todo} in list {calendar}" : "{actor} 從任務清單 {calendar} 中更新了待辦事項 {todo}", + "You updated to-do {todo} in list {calendar}" : "您在任務清單 {calendar} 中更新了待辦事項 {todo}", + "{actor} solved to-do {todo} in list {calendar}" : "{actor} 解决了任務清單 {calendar} 中的代辦事項 {todo}", + "You solved to-do {todo} in list {calendar}" : "您解决了任務清單 {calendar} 中的代辦事項 {todo}", + "{actor} reopened to-do {todo} in list {calendar}" : "{actor} 重新開啟了任務清單 {calendar} 中的代辦事項 {todo}", + "You reopened to-do {todo} in list {calendar}" : "你重新開啟了任務清單 {calendar} 中的代辦事項 {todo}", + "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor} 將待辦事項 {todo} 從清單 {sourceCalendar} 移到清單 {targetCalendar}", + "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "您將待辦事項 {todo} 從清單 {sourceCalendar} 移到清單 {targetCalendar}", "Calendar, contacts and tasks" : "日曆、聯絡人和任務", "A <strong>calendar</strong> was modified" : "<strong>日曆</strong>被修改", "A calendar <strong>event</strong> was modified" : "日曆<strong>活動</strong>被修改", - "A calendar <strong>todo</strong> was modified" : "日曆<strong>代辦事項</strong>被修改", + "A calendar <strong>to-do</strong> was modified" : "日曆<strong>代辦事項</strong>被修改", "Contact birthdays" : "聯絡人生日", "Death of %s" : "%s之卒", "Calendar:" : "日曆:", @@ -155,6 +159,7 @@ OC.L10N.register( "Friday" : "星期五", "Saturday" : "星期六", "Sunday" : "星期日", + "Automatically set user status to \"Do not disturb\" outside of availability to mute all notifications." : "當系統可得性時,自動將用戶狀態設置為“請勿打擾”以關閉所有音頻通知。", "Save" : "儲存", "Failed to load availability" : "加載可得性失敗", "Saved availability" : "已保存可得性", @@ -177,6 +182,18 @@ OC.L10N.register( "Tentative" : "暫定", "Number of guests" : "訪客数目", "Comment" : "留言", - "Your attendance was updated successfully." : "您的參與狀況成功更新" + "Your attendance was updated successfully." : "您的參與狀況成功更新", + "Todos" : "待辦事項", + "{actor} created todo {todo} in list {calendar}" : "{actor} 在任務列表 {calendar} 中建立了待辦事項 {todo}", + "You created todo {todo} in list {calendar}" : "您在任務列表 {calendar} 中建立了待辦事項 {todo}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} 從任務列表 {calendar} 中刪除了待辦事項 {todo}", + "You deleted todo {todo} from list {calendar}" : "您從任務列表 {calendar} 中刪除了待辦事項 {todo}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} 從任務列表 {calendar} 中更新了待辦事項 {todo}", + "You updated todo {todo} in list {calendar}" : "您在任務列表 {calendar} 中更新了待辦事項 {todo}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} 解决了任務列表 {calendar} 中的代辦事項 {todo}", + "You solved todo {todo} in list {calendar}" : "您解决了任務列表 {calendar} 中的代辦事項 {todo}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} 重新開啟了任務列表 {calendar} 中的代辦事項 {todo}", + "You reopened todo {todo} in list {calendar}" : "你重新開啟了 {calendar} 清單中的代辦事項 {todo}", + "A calendar <strong>todo</strong> was modified" : "日曆<strong>代辦事項</strong>被修改" }, "nplurals=1; plural=0;"); diff --git a/apps/dav/l10n/zh_HK.json b/apps/dav/l10n/zh_HK.json index 8ca935a748a..6608f6e268e 100644 --- a/apps/dav/l10n/zh_HK.json +++ b/apps/dav/l10n/zh_HK.json @@ -1,6 +1,6 @@ { "translations": { "Calendar" : "日曆", - "Todos" : "待辦事項", + "To-dos" : "待辦事項", "Personal" : "個人", "{actor} created calendar {calendar}" : "{actor} 建立了日曆 {calendar}", "You created calendar {calendar}" : "您建立了日曆 {calendar}", @@ -30,23 +30,27 @@ "You deleted event {event} from calendar {calendar}" : "您從日曆 {calendar} 中刪除了活動 {event}", "{actor} updated event {event} in calendar {calendar}" : "{actor} 更新了日曆 {calendar} 中的活動 {event}", "You updated event {event} in calendar {calendar}" : "您更新了日曆 {calendar} 中的活動 {event}", + "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{actor} 將活動 {event} 從日曆 {sourceCalendar} 移到日曆 {targetCalendar}", + "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "您將活動 {event} 從日曆 {sourceCalendar} 移到日曆 {targetCalendar}", "{actor} restored event {event} of calendar {calendar}" : "{actor} 復原了日曆 {calendar} 的活動 {event}", "You restored event {event} of calendar {calendar}" : "您復原了日曆 {calendar} 的活動 {event}", "Busy" : "忙碌中", - "{actor} created todo {todo} in list {calendar}" : "{actor} 在任務列表 {calendar} 中建立了待辦事項 {todo}", - "You created todo {todo} in list {calendar}" : "您在任務列表 {calendar} 中建立了待辦事項 {todo}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} 從任務列表 {calendar} 中刪除了待辦事項 {todo}", - "You deleted todo {todo} from list {calendar}" : "您從任務列表 {calendar} 中刪除了待辦事項 {todo}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} 從任務列表 {calendar} 中更新了待辦事項 {todo}", - "You updated todo {todo} in list {calendar}" : "您在任務列表 {calendar} 中更新了待辦事項 {todo}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} 解决了任務列表 {calendar} 中的代辦事項 {todo}", - "You solved todo {todo} in list {calendar}" : "您解决了任務列表 {calendar} 中的代辦事項 {todo}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} 重新開啟了任務列表 {calendar} 中的代辦事項 {todo}", - "You reopened todo {todo} in list {calendar}" : "你重新開啟了 {calendar} 清單中的代辦事項 {todo}", + "{actor} created to-do {todo} in list {calendar}" : "{actor} 在任務清單 {calendar} 中建立了待辦事項 {todo}", + "You created to-do {todo} in list {calendar}" : "您在任務清單 {calendar} 中建立了待辦事項 {todo}", + "{actor} deleted to-do {todo} from list {calendar}" : "{actor} 從任務清單 {calendar} 中刪除了待辦事項 {todo}", + "You deleted to-do {todo} from list {calendar}" : "您從任務清單 {calendar} 中刪除了待辦事項 {todo}", + "{actor} updated to-do {todo} in list {calendar}" : "{actor} 從任務清單 {calendar} 中更新了待辦事項 {todo}", + "You updated to-do {todo} in list {calendar}" : "您在任務清單 {calendar} 中更新了待辦事項 {todo}", + "{actor} solved to-do {todo} in list {calendar}" : "{actor} 解决了任務清單 {calendar} 中的代辦事項 {todo}", + "You solved to-do {todo} in list {calendar}" : "您解决了任務清單 {calendar} 中的代辦事項 {todo}", + "{actor} reopened to-do {todo} in list {calendar}" : "{actor} 重新開啟了任務清單 {calendar} 中的代辦事項 {todo}", + "You reopened to-do {todo} in list {calendar}" : "你重新開啟了任務清單 {calendar} 中的代辦事項 {todo}", + "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor} 將待辦事項 {todo} 從清單 {sourceCalendar} 移到清單 {targetCalendar}", + "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "您將待辦事項 {todo} 從清單 {sourceCalendar} 移到清單 {targetCalendar}", "Calendar, contacts and tasks" : "日曆、聯絡人和任務", "A <strong>calendar</strong> was modified" : "<strong>日曆</strong>被修改", "A calendar <strong>event</strong> was modified" : "日曆<strong>活動</strong>被修改", - "A calendar <strong>todo</strong> was modified" : "日曆<strong>代辦事項</strong>被修改", + "A calendar <strong>to-do</strong> was modified" : "日曆<strong>代辦事項</strong>被修改", "Contact birthdays" : "聯絡人生日", "Death of %s" : "%s之卒", "Calendar:" : "日曆:", @@ -153,6 +157,7 @@ "Friday" : "星期五", "Saturday" : "星期六", "Sunday" : "星期日", + "Automatically set user status to \"Do not disturb\" outside of availability to mute all notifications." : "當系統可得性時,自動將用戶狀態設置為“請勿打擾”以關閉所有音頻通知。", "Save" : "儲存", "Failed to load availability" : "加載可得性失敗", "Saved availability" : "已保存可得性", @@ -175,6 +180,18 @@ "Tentative" : "暫定", "Number of guests" : "訪客数目", "Comment" : "留言", - "Your attendance was updated successfully." : "您的參與狀況成功更新" + "Your attendance was updated successfully." : "您的參與狀況成功更新", + "Todos" : "待辦事項", + "{actor} created todo {todo} in list {calendar}" : "{actor} 在任務列表 {calendar} 中建立了待辦事項 {todo}", + "You created todo {todo} in list {calendar}" : "您在任務列表 {calendar} 中建立了待辦事項 {todo}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} 從任務列表 {calendar} 中刪除了待辦事項 {todo}", + "You deleted todo {todo} from list {calendar}" : "您從任務列表 {calendar} 中刪除了待辦事項 {todo}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} 從任務列表 {calendar} 中更新了待辦事項 {todo}", + "You updated todo {todo} in list {calendar}" : "您在任務列表 {calendar} 中更新了待辦事項 {todo}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} 解决了任務列表 {calendar} 中的代辦事項 {todo}", + "You solved todo {todo} in list {calendar}" : "您解决了任務列表 {calendar} 中的代辦事項 {todo}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} 重新開啟了任務列表 {calendar} 中的代辦事項 {todo}", + "You reopened todo {todo} in list {calendar}" : "你重新開啟了 {calendar} 清單中的代辦事項 {todo}", + "A calendar <strong>todo</strong> was modified" : "日曆<strong>代辦事項</strong>被修改" },"pluralForm" :"nplurals=1; plural=0;" }
\ No newline at end of file diff --git a/apps/dav/l10n/zh_TW.js b/apps/dav/l10n/zh_TW.js index d822b523b26..166c6edb4c3 100644 --- a/apps/dav/l10n/zh_TW.js +++ b/apps/dav/l10n/zh_TW.js @@ -2,7 +2,7 @@ OC.L10N.register( "dav", { "Calendar" : "日曆", - "Todos" : "待辦事項", + "To-dos" : "待辦事項", "Personal" : "個人", "{actor} created calendar {calendar}" : "{actor} 建立了日曆 {calendar}", "You created calendar {calendar}" : "您建立了日曆 {calendar}", @@ -32,23 +32,27 @@ OC.L10N.register( "You deleted event {event} from calendar {calendar}" : "您在日曆 {calendar} 中刪除了 {event} 活動", "{actor} updated event {event} in calendar {calendar}" : "{actor} 在日曆 {calendar} 中更新了 {event} 活動", "You updated event {event} in calendar {calendar}" : "您在日曆 {calendar} 中刪除了 {event} 活動", + "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{actor} 將事件 {event} 從行事曆 {sourceCalendar} 移動至行事曆 {targetCalendar}", + "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "您將事件 {event} 從行事曆 {sourceCalendar} 移動至行事曆 {targetCalendar}", "{actor} restored event {event} of calendar {calendar}" : "{actor} 復原了日曆 {calendar} 中的活動 {event}", "You restored event {event} of calendar {calendar}" : "您復原了日曆 {calendar} 中的活動 {event}", "Busy" : "忙碌", - "{actor} created todo {todo} in list {calendar}" : "{actor} 在列表 {calendar} 中建立了待辦事項 {todo}", - "You created todo {todo} in list {calendar}" : "您在列表 {calendar} 中建立了待辦事項 {todo}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} 在列表 {calendar} 中刪除了待辦事項 {todo}", - "You deleted todo {todo} from list {calendar}" : "您在列表 {calendar} 中刪除了待辦事項 {todo}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} 在列表 {calendar} 中更新了待辦事項 {todo}", - "You updated todo {todo} in list {calendar}" : "您在列表 {calendar} 中更新了待辦事項 {todo}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} 在列表 {calendar} 中解決了待辦事項 {todo}", - "You solved todo {todo} in list {calendar}" : "您在列表 {calendar} 中解決了待辦事項 {todo}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} 在列表 {calendar} 中重新開啟了待辦事項 {todo}", - "You reopened todo {todo} in list {calendar}" : "您在列表 {calendar} 中重新開啟了待辦事項 {todo}", + "{actor} created to-do {todo} in list {calendar}" : "{actor} 在清單 {calendar} 中建立了待辦事項 {todo}", + "You created to-do {todo} in list {calendar}" : "您在清單 {calendar} 中建立了待辦事項 {todo}", + "{actor} deleted to-do {todo} from list {calendar}" : "{actor} 從清單 {calendar} 中刪除了待辦事項 {todo}", + "You deleted to-do {todo} from list {calendar}" : "您從清單 {calendar} 中刪除了待辦事項 {todo}", + "{actor} updated to-do {todo} in list {calendar}" : "{actor} 在清單 {calendar} 中更新了待辦事項 {todo}", + "You updated to-do {todo} in list {calendar}" : "您在清單 {calendar} 中更新了待辦事項 {todo}", + "{actor} solved to-do {todo} in list {calendar}" : "{actor} 在清單 {calendar} 中解決了待辦事項 {todo}", + "You solved to-do {todo} in list {calendar}" : "您在清單 {calendar} 中解決了待辦事項 {todo}", + "{actor} reopened to-do {todo} in list {calendar}" : "{actor} 在清單 {calendar} 中重新開啟了待辦事項 {todo}", + "You reopened to-do {todo} in list {calendar}" : "您在清單 {calendar} 中重新開啟了待辦事項 {todo}", + "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor} 將待辦事項 {todo} 從清單 {sourceCalendar} 移動到清單 {targetCalendar}", + "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "您將待辦事項 {todo} 從清單 {sourceCalendar} 移動到清單 {targetCalendar}", "Calendar, contacts and tasks" : "日曆、通訊錄與工作項目", "A <strong>calendar</strong> was modified" : "一個<strong>日曆</strong>被更動", "A calendar <strong>event</strong> was modified" : "一個日曆<strong>活動</strong>被更動", - "A calendar <strong>todo</strong> was modified" : "一個日曆<strong>待辦事項</strong>被更動", + "A calendar <strong>to-do</strong> was modified" : "已修改一個行事曆<strong>待辦事項</strong>", "Contact birthdays" : "聯絡人生日", "Death of %s" : "%s 逝世", "Calendar:" : "日曆:", @@ -155,6 +159,7 @@ OC.L10N.register( "Friday" : "週五", "Saturday" : "週六", "Sunday" : "週日", + "Automatically set user status to \"Do not disturb\" outside of availability to mute all notifications." : "在忙碌時,自動將使用者狀態設定為「請勿打擾」以靜音所有通知。", "Save" : "儲存", "Failed to load availability" : "載入可用性失敗", "Saved availability" : "已儲存可用性", @@ -177,6 +182,18 @@ OC.L10N.register( "Tentative" : "暫定", "Number of guests" : "訪客數量", "Comment" : "留言", - "Your attendance was updated successfully." : "您的參與狀態成功更新。" + "Your attendance was updated successfully." : "您的參與狀態成功更新。", + "Todos" : "待辦事項", + "{actor} created todo {todo} in list {calendar}" : "{actor} 在列表 {calendar} 中建立了待辦事項 {todo}", + "You created todo {todo} in list {calendar}" : "您在列表 {calendar} 中建立了待辦事項 {todo}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} 在列表 {calendar} 中刪除了待辦事項 {todo}", + "You deleted todo {todo} from list {calendar}" : "您在列表 {calendar} 中刪除了待辦事項 {todo}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} 在列表 {calendar} 中更新了待辦事項 {todo}", + "You updated todo {todo} in list {calendar}" : "您在列表 {calendar} 中更新了待辦事項 {todo}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} 在列表 {calendar} 中解決了待辦事項 {todo}", + "You solved todo {todo} in list {calendar}" : "您在列表 {calendar} 中解決了待辦事項 {todo}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} 在列表 {calendar} 中重新開啟了待辦事項 {todo}", + "You reopened todo {todo} in list {calendar}" : "您在列表 {calendar} 中重新開啟了待辦事項 {todo}", + "A calendar <strong>todo</strong> was modified" : "一個日曆<strong>待辦事項</strong>被更動" }, "nplurals=1; plural=0;"); diff --git a/apps/dav/l10n/zh_TW.json b/apps/dav/l10n/zh_TW.json index a0786132472..15c068b3350 100644 --- a/apps/dav/l10n/zh_TW.json +++ b/apps/dav/l10n/zh_TW.json @@ -1,6 +1,6 @@ { "translations": { "Calendar" : "日曆", - "Todos" : "待辦事項", + "To-dos" : "待辦事項", "Personal" : "個人", "{actor} created calendar {calendar}" : "{actor} 建立了日曆 {calendar}", "You created calendar {calendar}" : "您建立了日曆 {calendar}", @@ -30,23 +30,27 @@ "You deleted event {event} from calendar {calendar}" : "您在日曆 {calendar} 中刪除了 {event} 活動", "{actor} updated event {event} in calendar {calendar}" : "{actor} 在日曆 {calendar} 中更新了 {event} 活動", "You updated event {event} in calendar {calendar}" : "您在日曆 {calendar} 中刪除了 {event} 活動", + "{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "{actor} 將事件 {event} 從行事曆 {sourceCalendar} 移動至行事曆 {targetCalendar}", + "You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}" : "您將事件 {event} 從行事曆 {sourceCalendar} 移動至行事曆 {targetCalendar}", "{actor} restored event {event} of calendar {calendar}" : "{actor} 復原了日曆 {calendar} 中的活動 {event}", "You restored event {event} of calendar {calendar}" : "您復原了日曆 {calendar} 中的活動 {event}", "Busy" : "忙碌", - "{actor} created todo {todo} in list {calendar}" : "{actor} 在列表 {calendar} 中建立了待辦事項 {todo}", - "You created todo {todo} in list {calendar}" : "您在列表 {calendar} 中建立了待辦事項 {todo}", - "{actor} deleted todo {todo} from list {calendar}" : "{actor} 在列表 {calendar} 中刪除了待辦事項 {todo}", - "You deleted todo {todo} from list {calendar}" : "您在列表 {calendar} 中刪除了待辦事項 {todo}", - "{actor} updated todo {todo} in list {calendar}" : "{actor} 在列表 {calendar} 中更新了待辦事項 {todo}", - "You updated todo {todo} in list {calendar}" : "您在列表 {calendar} 中更新了待辦事項 {todo}", - "{actor} solved todo {todo} in list {calendar}" : "{actor} 在列表 {calendar} 中解決了待辦事項 {todo}", - "You solved todo {todo} in list {calendar}" : "您在列表 {calendar} 中解決了待辦事項 {todo}", - "{actor} reopened todo {todo} in list {calendar}" : "{actor} 在列表 {calendar} 中重新開啟了待辦事項 {todo}", - "You reopened todo {todo} in list {calendar}" : "您在列表 {calendar} 中重新開啟了待辦事項 {todo}", + "{actor} created to-do {todo} in list {calendar}" : "{actor} 在清單 {calendar} 中建立了待辦事項 {todo}", + "You created to-do {todo} in list {calendar}" : "您在清單 {calendar} 中建立了待辦事項 {todo}", + "{actor} deleted to-do {todo} from list {calendar}" : "{actor} 從清單 {calendar} 中刪除了待辦事項 {todo}", + "You deleted to-do {todo} from list {calendar}" : "您從清單 {calendar} 中刪除了待辦事項 {todo}", + "{actor} updated to-do {todo} in list {calendar}" : "{actor} 在清單 {calendar} 中更新了待辦事項 {todo}", + "You updated to-do {todo} in list {calendar}" : "您在清單 {calendar} 中更新了待辦事項 {todo}", + "{actor} solved to-do {todo} in list {calendar}" : "{actor} 在清單 {calendar} 中解決了待辦事項 {todo}", + "You solved to-do {todo} in list {calendar}" : "您在清單 {calendar} 中解決了待辦事項 {todo}", + "{actor} reopened to-do {todo} in list {calendar}" : "{actor} 在清單 {calendar} 中重新開啟了待辦事項 {todo}", + "You reopened to-do {todo} in list {calendar}" : "您在清單 {calendar} 中重新開啟了待辦事項 {todo}", + "{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "{actor} 將待辦事項 {todo} 從清單 {sourceCalendar} 移動到清單 {targetCalendar}", + "You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}" : "您將待辦事項 {todo} 從清單 {sourceCalendar} 移動到清單 {targetCalendar}", "Calendar, contacts and tasks" : "日曆、通訊錄與工作項目", "A <strong>calendar</strong> was modified" : "一個<strong>日曆</strong>被更動", "A calendar <strong>event</strong> was modified" : "一個日曆<strong>活動</strong>被更動", - "A calendar <strong>todo</strong> was modified" : "一個日曆<strong>待辦事項</strong>被更動", + "A calendar <strong>to-do</strong> was modified" : "已修改一個行事曆<strong>待辦事項</strong>", "Contact birthdays" : "聯絡人生日", "Death of %s" : "%s 逝世", "Calendar:" : "日曆:", @@ -153,6 +157,7 @@ "Friday" : "週五", "Saturday" : "週六", "Sunday" : "週日", + "Automatically set user status to \"Do not disturb\" outside of availability to mute all notifications." : "在忙碌時,自動將使用者狀態設定為「請勿打擾」以靜音所有通知。", "Save" : "儲存", "Failed to load availability" : "載入可用性失敗", "Saved availability" : "已儲存可用性", @@ -175,6 +180,18 @@ "Tentative" : "暫定", "Number of guests" : "訪客數量", "Comment" : "留言", - "Your attendance was updated successfully." : "您的參與狀態成功更新。" + "Your attendance was updated successfully." : "您的參與狀態成功更新。", + "Todos" : "待辦事項", + "{actor} created todo {todo} in list {calendar}" : "{actor} 在列表 {calendar} 中建立了待辦事項 {todo}", + "You created todo {todo} in list {calendar}" : "您在列表 {calendar} 中建立了待辦事項 {todo}", + "{actor} deleted todo {todo} from list {calendar}" : "{actor} 在列表 {calendar} 中刪除了待辦事項 {todo}", + "You deleted todo {todo} from list {calendar}" : "您在列表 {calendar} 中刪除了待辦事項 {todo}", + "{actor} updated todo {todo} in list {calendar}" : "{actor} 在列表 {calendar} 中更新了待辦事項 {todo}", + "You updated todo {todo} in list {calendar}" : "您在列表 {calendar} 中更新了待辦事項 {todo}", + "{actor} solved todo {todo} in list {calendar}" : "{actor} 在列表 {calendar} 中解決了待辦事項 {todo}", + "You solved todo {todo} in list {calendar}" : "您在列表 {calendar} 中解決了待辦事項 {todo}", + "{actor} reopened todo {todo} in list {calendar}" : "{actor} 在列表 {calendar} 中重新開啟了待辦事項 {todo}", + "You reopened todo {todo} in list {calendar}" : "您在列表 {calendar} 中重新開啟了待辦事項 {todo}", + "A calendar <strong>todo</strong> was modified" : "一個日曆<strong>待辦事項</strong>被更動" },"pluralForm" :"nplurals=1; plural=0;" }
\ No newline at end of file diff --git a/apps/dav/lib/AppInfo/Application.php b/apps/dav/lib/AppInfo/Application.php index 580918a6450..86749862626 100644 --- a/apps/dav/lib/AppInfo/Application.php +++ b/apps/dav/lib/AppInfo/Application.php @@ -35,18 +35,14 @@ namespace OCA\DAV\AppInfo; use Exception; use OCA\DAV\BackgroundJob\UpdateCalendarResourcesRoomsBackgroundJob; use OCA\DAV\CalDAV\Activity\Backend; -use OCA\DAV\CalDAV\BirthdayService; -use OCA\DAV\CalDAV\CalDavBackend; use OCA\DAV\CalDAV\CalendarManager; use OCA\DAV\CalDAV\CalendarProvider; -use OCA\DAV\CalDAV\Reminder\Backend as ReminderBackend; use OCA\DAV\CalDAV\Reminder\NotificationProvider\AudioProvider; use OCA\DAV\CalDAV\Reminder\NotificationProvider\EmailProvider; use OCA\DAV\CalDAV\Reminder\NotificationProvider\PushProvider; use OCA\DAV\CalDAV\Reminder\NotificationProviderManager; use OCA\DAV\CalDAV\Reminder\Notifier; -use OCA\DAV\CalDAV\WebcalCaching\RefreshWebcalService; use OCA\DAV\Capabilities; use OCA\DAV\CardDAV\CardDavBackend; use OCA\DAV\CardDAV\ContactsManager; @@ -61,22 +57,35 @@ use OCA\DAV\Events\CalendarDeletedEvent; use OCA\DAV\Events\CalendarMovedToTrashEvent; use OCA\DAV\Events\CalendarObjectCreatedEvent; use OCA\DAV\Events\CalendarObjectDeletedEvent; +use OCA\DAV\Events\CalendarObjectMovedEvent; use OCA\DAV\Events\CalendarObjectMovedToTrashEvent; use OCA\DAV\Events\CalendarObjectRestoredEvent; use OCA\DAV\Events\CalendarObjectUpdatedEvent; +use OCA\DAV\Events\CalendarPublishedEvent; use OCA\DAV\Events\CalendarRestoredEvent; use OCA\DAV\Events\CalendarShareUpdatedEvent; +use OCA\DAV\Events\CalendarUnpublishedEvent; use OCA\DAV\Events\CalendarUpdatedEvent; use OCA\DAV\Events\CardCreatedEvent; use OCA\DAV\Events\CardDeletedEvent; use OCA\DAV\Events\CardUpdatedEvent; +use OCA\DAV\Events\SubscriptionCreatedEvent; +use OCA\DAV\Events\SubscriptionDeletedEvent; +use OCP\Federation\Events\TrustedServerRemovedEvent; use OCA\DAV\HookManager; use OCA\DAV\Listener\ActivityUpdaterListener; use OCA\DAV\Listener\AddressbookListener; +use OCA\DAV\Listener\BirthdayListener; use OCA\DAV\Listener\CalendarContactInteractionListener; use OCA\DAV\Listener\CalendarDeletionDefaultUpdaterListener; use OCA\DAV\Listener\CalendarObjectReminderUpdaterListener; +use OCA\DAV\Listener\CalendarPublicationListener; +use OCA\DAV\Listener\CalendarShareUpdateListener; use OCA\DAV\Listener\CardListener; +use OCA\DAV\Listener\ClearPhotoCacheListener; +use OCA\DAV\Listener\SubscriptionListener; +use OCA\DAV\Listener\TrustedServerRemovedListener; +use OCA\DAV\Listener\UserPreferenceListener; use OCA\DAV\Search\ContactsSearchProvider; use OCA\DAV\Search\EventsSearchProvider; use OCA\DAV\Search\TasksSearchProvider; @@ -88,6 +97,8 @@ use OCP\AppFramework\Bootstrap\IBootstrap; use OCP\AppFramework\Bootstrap\IRegistrationContext; use OCP\AppFramework\IAppContainer; use OCP\Calendar\IManager as ICalendarManager; +use OCP\Config\BeforePreferenceDeletedEvent; +use OCP\Config\BeforePreferenceSetEvent; use OCP\Contacts\IManager as IContactsManager; use OCP\IServerContainer; use OCP\IUser; @@ -149,11 +160,19 @@ class Application extends App implements IBootstrap { $context->registerEventListener(CalendarObjectUpdatedEvent::class, CalendarObjectReminderUpdaterListener::class); $context->registerEventListener(CalendarObjectDeletedEvent::class, ActivityUpdaterListener::class); $context->registerEventListener(CalendarObjectDeletedEvent::class, CalendarObjectReminderUpdaterListener::class); + $context->registerEventListener(CalendarObjectMovedEvent::class, ActivityUpdaterListener::class); + $context->registerEventListener(CalendarObjectMovedEvent::class, CalendarObjectReminderUpdaterListener::class); $context->registerEventListener(CalendarObjectMovedToTrashEvent::class, ActivityUpdaterListener::class); $context->registerEventListener(CalendarObjectMovedToTrashEvent::class, CalendarObjectReminderUpdaterListener::class); $context->registerEventListener(CalendarObjectRestoredEvent::class, ActivityUpdaterListener::class); $context->registerEventListener(CalendarObjectRestoredEvent::class, CalendarObjectReminderUpdaterListener::class); $context->registerEventListener(CalendarShareUpdatedEvent::class, CalendarContactInteractionListener::class); + $context->registerEventListener(CalendarPublishedEvent::class, CalendarPublicationListener::class); + $context->registerEventListener(CalendarUnpublishedEvent::class, CalendarPublicationListener::class); + $context->registerEventListener(CalendarShareUpdatedEvent::class, CalendarShareUpdateListener::class); + + $context->registerEventListener(SubscriptionCreatedEvent::class, SubscriptionListener::class); + $context->registerEventListener(SubscriptionDeletedEvent::class, SubscriptionListener::class); $context->registerEventListener(AddressBookCreatedEvent::class, AddressbookListener::class); @@ -163,6 +182,15 @@ class Application extends App implements IBootstrap { $context->registerEventListener(CardCreatedEvent::class, CardListener::class); $context->registerEventListener(CardDeletedEvent::class, CardListener::class); $context->registerEventListener(CardUpdatedEvent::class, CardListener::class); + $context->registerEventListener(CardCreatedEvent::class, BirthdayListener::class); + $context->registerEventListener(CardDeletedEvent::class, BirthdayListener::class); + $context->registerEventListener(CardUpdatedEvent::class, BirthdayListener::class); + $context->registerEventListener(CardDeletedEvent::class, ClearPhotoCacheListener::class); + $context->registerEventListener(CardUpdatedEvent::class, ClearPhotoCacheListener::class); + $context->registerEventListener(TrustedServerRemovedEvent::class, TrustedServerRemovedListener::class); + + $context->registerEventListener(BeforePreferenceDeletedEvent::class, UserPreferenceListener::class); + $context->registerEventListener(BeforePreferenceSetEvent::class, UserPreferenceListener::class); $context->registerNotifierService(Notifier::class); @@ -195,44 +223,6 @@ class Application extends App implements IBootstrap { } }); - $birthdayListener = function ($event) use ($container): void { - if ($event instanceof GenericEvent) { - /** @var BirthdayService $b */ - $b = $container->query(BirthdayService::class); - $b->onCardChanged( - (int) $event->getArgument('addressBookId'), - (string) $event->getArgument('cardUri'), - (string) $event->getArgument('cardData') - ); - } - }; - - $dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::createCard', $birthdayListener); - $dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::updateCard', $birthdayListener); - $dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::deleteCard', function ($event) use ($container) { - if ($event instanceof GenericEvent) { - /** @var BirthdayService $b */ - $b = $container->query(BirthdayService::class); - $b->onCardDeleted( - (int) $event->getArgument('addressBookId'), - (string) $event->getArgument('cardUri') - ); - } - }); - - $clearPhotoCache = function ($event) use ($container): void { - if ($event instanceof GenericEvent) { - /** @var PhotoCache $p */ - $p = $container->query(PhotoCache::class); - $p->delete( - $event->getArgument('addressBookId'), - $event->getArgument('cardUri') - ); - } - }; - $dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::updateCard', $clearPhotoCache); - $dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::deleteCard', $clearPhotoCache); - $dispatcher->addListener('OC\AccountManager::userUpdated', function (GenericEvent $event) use ($container) { $user = $event->getSubject(); /** @var SyncService $syncService */ @@ -254,70 +244,6 @@ class Application extends App implements IBootstrap { // Here we should recalculate if reminders should be sent to new or old sharees }); - $dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::publishCalendar', function (GenericEvent $event) use ($container) { - /** @var Backend $backend */ - $backend = $container->query(Backend::class); - $backend->onCalendarPublication( - $event->getArgument('calendarData'), - $event->getArgument('public') - ); - }); - - - $dispatcher->addListener('OCP\Federation\TrustedServerEvent::remove', - function (GenericEvent $event) { - /** @var CardDavBackend $cardDavBackend */ - $cardDavBackend = \OC::$server->query(CardDavBackend::class); - $addressBookUri = $event->getSubject(); - $addressBook = $cardDavBackend->getAddressBooksByUri('principals/system/system', $addressBookUri); - if (!is_null($addressBook)) { - $cardDavBackend->deleteAddressBook($addressBook['id']); - } - } - ); - - $dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::createSubscription', - function (GenericEvent $event) use ($container, $serverContainer) { - $jobList = $serverContainer->getJobList(); - $subscriptionData = $event->getArgument('subscriptionData'); - - /** - * Initial subscription refetch - * - * @var RefreshWebcalService $refreshWebcalService - */ - $refreshWebcalService = $container->query(RefreshWebcalService::class); - $refreshWebcalService->refreshSubscription( - (string) $subscriptionData['principaluri'], - (string) $subscriptionData['uri'] - ); - - $jobList->add(\OCA\DAV\BackgroundJob\RefreshWebcalJob::class, [ - 'principaluri' => $subscriptionData['principaluri'], - 'uri' => $subscriptionData['uri'] - ]); - } - ); - - $dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::deleteSubscription', - function (GenericEvent $event) use ($container, $serverContainer) { - $jobList = $serverContainer->getJobList(); - $subscriptionData = $event->getArgument('subscriptionData'); - - $jobList->remove(\OCA\DAV\BackgroundJob\RefreshWebcalJob::class, [ - 'principaluri' => $subscriptionData['principaluri'], - 'uri' => $subscriptionData['uri'] - ]); - - /** @var CalDavBackend $calDavBackend */ - $calDavBackend = $container->get(CalDavBackend::class); - $calDavBackend->purgeAllCachedEventsForSubscription($subscriptionData['id']); - /** @var ReminderBackend $calDavBackend */ - $reminderBackend = $container->get(ReminderBackend::class); - $reminderBackend->cleanRemindersForCalendar((int) $subscriptionData['id']); - } - ); - $eventHandler = function () use ($container, $serverContainer): void { try { /** @var UpdateCalendarResourcesRoomsBackgroundJob $job */ diff --git a/apps/dav/lib/BackgroundJob/UploadCleanup.php b/apps/dav/lib/BackgroundJob/UploadCleanup.php index f612f58cd7c..3a6f296deaf 100644 --- a/apps/dav/lib/BackgroundJob/UploadCleanup.php +++ b/apps/dav/lib/BackgroundJob/UploadCleanup.php @@ -37,15 +37,18 @@ use OCP\Files\File; use OCP\Files\Folder; use OCP\Files\IRootFolder; use OCP\Files\NotFoundException; +use Psr\Log\LoggerInterface; class UploadCleanup extends TimedJob { private IRootFolder $rootFolder; private IJobList $jobList; + private LoggerInterface $logger; - public function __construct(ITimeFactory $time, IRootFolder $rootFolder, IJobList $jobList) { + public function __construct(ITimeFactory $time, IRootFolder $rootFolder, IJobList $jobList, LoggerInterface $logger) { parent::__construct($time); $this->rootFolder = $rootFolder; $this->jobList = $jobList; + $this->logger = $logger; // Run once a day $this->setInterval(60 * 60 * 24); @@ -61,19 +64,27 @@ class UploadCleanup extends TimedJob { $userRoot = $userFolder->getParent(); /** @var Folder $uploads */ $uploads = $userRoot->get('uploads'); - /** @var Folder $uploadFolder */ $uploadFolder = $uploads->get($folder); } catch (NotFoundException | NoUserException $e) { $this->jobList->remove(self::class, $argument); return; } - /** @var File[] $files */ - $files = $uploadFolder->getDirectoryListing(); - // Remove if all files have an mtime of more than a day $time = $this->time->getTime() - 60 * 60 * 24; + if (!($uploadFolder instanceof Folder)) { + $this->logger->error("Found a file inside the uploads folder. Uid: " . $uid . ' folder: ' . $folder); + if ($uploadFolder->getMTime() < $time) { + $uploadFolder->delete(); + } + $this->jobList->remove(self::class, $argument); + return; + } + + /** @var File[] $files */ + $files = $uploadFolder->getDirectoryListing(); + // The folder has to be more than a day old $initial = $uploadFolder->getMTime() < $time; diff --git a/apps/dav/lib/BackgroundJob/UserStatusAutomation.php b/apps/dav/lib/BackgroundJob/UserStatusAutomation.php new file mode 100644 index 00000000000..bbd92d903ee --- /dev/null +++ b/apps/dav/lib/BackgroundJob/UserStatusAutomation.php @@ -0,0 +1,188 @@ +<?php + +declare(strict_types=1); +/** + * @copyright Copyright (c) 2022 Joas Schilling <coding@schilljs.com> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCA\DAV\BackgroundJob; + +use OCA\DAV\CalDAV\Schedule\Plugin; +use OCP\AppFramework\Utility\ITimeFactory; +use OCP\BackgroundJob\IJobList; +use OCP\BackgroundJob\TimedJob; +use OCP\DB\QueryBuilder\IQueryBuilder; +use OCP\IConfig; +use OCP\IDBConnection; +use OCP\UserStatus\IManager; +use OCP\UserStatus\IUserStatus; +use Psr\Log\LoggerInterface; +use Sabre\VObject\Component\Available; +use Sabre\VObject\Component\VAvailability; +use Sabre\VObject\Reader; +use Sabre\VObject\Recur\RRuleIterator; + +class UserStatusAutomation extends TimedJob { + protected IDBConnection $connection; + protected IJobList $jobList; + protected LoggerInterface $logger; + protected IManager $manager; + protected IConfig $config; + + public function __construct(ITimeFactory $timeFactory, + IDBConnection $connection, + IJobList $jobList, + LoggerInterface $logger, + IManager $manager, + IConfig $config) { + parent::__construct($timeFactory); + $this->connection = $connection; + $this->jobList = $jobList; + $this->logger = $logger; + $this->manager = $manager; + $this->config = $config; + + // Interval 0 might look weird, but the last_checked is always moved + // to the next time we need this and then it's 0 seconds ago. + $this->setInterval(0); + } + + /** + * @inheritDoc + */ + protected function run($argument) { + if (!isset($argument['userId'])) { + $this->jobList->remove(self::class, $argument); + $this->logger->info('Removing invalid ' . self::class . ' background job'); + return; + } + + $userId = $argument['userId']; + $automationEnabled = $this->config->getUserValue($userId, 'dav', 'user_status_automation', 'no') === 'yes'; + if (!$automationEnabled) { + $this->logger->info('Removing ' . self::class . ' background job for user "' . $userId . '" because the setting is disabled'); + $this->jobList->remove(self::class, $argument); + return; + } + + $property = $this->getAvailabilityFromPropertiesTable($userId); + + if (!$property) { + $this->logger->info('Removing ' . self::class . ' background job for user "' . $userId . '" because the user has no availability settings'); + $this->jobList->remove(self::class, $argument); + return; + } + + $isCurrentlyAvailable = false; + $nextPotentialToggles = []; + + $now = new \DateTime('now'); + $lastMidnight = (clone $now)->setTime(0, 0); + + $vObject = Reader::read($property); + foreach ($vObject->getComponents() as $component) { + if ($component->name !== 'VAVAILABILITY') { + continue; + } + /** @var VAvailability $component */ + $availables = $component->getComponents(); + foreach ($availables as $available) { + /** @var Available $available */ + if ($available->name === 'AVAILABLE') { + /** @var \DateTimeInterface $effectiveStart */ + /** @var \DateTimeInterface $effectiveEnd */ + [$effectiveStart, $effectiveEnd] = $available->getEffectiveStartEnd(); + + try { + $it = new RRuleIterator((string) $available->RRULE, $effectiveStart); + $it->fastForward($lastMidnight); + + $startToday = $it->current(); + if ($startToday && $startToday <= $now) { + $duration = $effectiveStart->diff($effectiveEnd); + $endToday = $startToday->add($duration); + if ($endToday > $now) { + // User is currently available + // Also queuing the end time as next status toggle + $isCurrentlyAvailable = true; + $nextPotentialToggles[] = $endToday->getTimestamp(); + } + + // Availability enabling already done for today, + // so jump to the next recurrence to find the next status toggle + $it->next(); + } + + if ($it->current()) { + $nextPotentialToggles[] = $it->current()->getTimestamp(); + } + } catch (\Exception $e) { + $this->logger->error($e->getMessage(), ['exception' => $e]); + } + } + } + } + + $nextAutomaticToggle = min($nextPotentialToggles); + $this->setLastRunToNextToggleTime($userId, $nextAutomaticToggle - 1); + + if ($isCurrentlyAvailable) { + $this->manager->revertUserStatus($userId, IUserStatus::MESSAGE_AVAILABILITY, IUserStatus::DND); + } else { + // The DND status automation is more important than the "Away - In call" so we also restore that one if it exists. + $this->manager->revertUserStatus($userId, IUserStatus::MESSAGE_CALL, IUserStatus::AWAY); + $this->manager->setUserStatus($userId, IUserStatus::MESSAGE_AVAILABILITY, IUserStatus::DND, true); + } + $this->logger->debug('User status automation ran'); + } + + protected function setLastRunToNextToggleTime(string $userId, int $timestamp): void { + $query = $this->connection->getQueryBuilder(); + + $query->update('jobs') + ->set('last_run', $query->createNamedParameter($timestamp, IQueryBuilder::PARAM_INT)) + ->where($query->expr()->eq('id', $query->createNamedParameter($this->getId(), IQueryBuilder::PARAM_INT))); + $query->executeStatement(); + + $this->logger->debug('Updated user status automation last_run to ' . $timestamp . ' for user ' . $userId); + } + + /** + * @param string $userId + * @return false|string + */ + protected function getAvailabilityFromPropertiesTable(string $userId) { + $propertyPath = 'calendars/' . $userId . '/inbox'; + $propertyName = '{' . Plugin::NS_CALDAV . '}calendar-availability'; + + $query = $this->connection->getQueryBuilder(); + $query->select('propertyvalue') + ->from('properties') + ->where($query->expr()->eq('userid', $query->createNamedParameter($userId))) + ->andWhere($query->expr()->eq('propertypath', $query->createNamedParameter($propertyPath))) + ->where($query->expr()->eq('propertyname', $query->createNamedParameter($propertyName))) + ->setMaxResults(1); + + $result = $query->executeQuery(); + $property = $result->fetchOne(); + $result->closeCursor(); + + return $property; + } +} diff --git a/apps/dav/lib/CalDAV/Activity/Backend.php b/apps/dav/lib/CalDAV/Activity/Backend.php index 84ba50b8c37..781a456b5b3 100644 --- a/apps/dav/lib/CalDAV/Activity/Backend.php +++ b/apps/dav/lib/CalDAV/Activity/Backend.php @@ -34,6 +34,7 @@ use OCP\App\IAppManager; use OCP\IGroup; use OCP\IGroupManager; use OCP\IUser; +use OCP\IUserManager; use OCP\IUserSession; use Sabre\VObject\Reader; @@ -56,11 +57,15 @@ class Backend { /** @var IAppManager */ protected $appManager; - public function __construct(IActivityManager $activityManager, IGroupManager $groupManager, IUserSession $userSession, IAppManager $appManager) { + /** @var IUserManager */ + protected $userManager; + + public function __construct(IActivityManager $activityManager, IGroupManager $groupManager, IUserSession $userSession, IAppManager $appManager, IUserManager $userManager) { $this->activityManager = $activityManager; $this->groupManager = $groupManager; $this->userSession = $userSession; $this->appManager = $appManager; + $this->userManager = $userManager; } /** @@ -119,7 +124,7 @@ class Backend { * @param array $calendarData * @param bool $publishStatus */ - public function onCalendarPublication(array $calendarData, $publishStatus) { + public function onCalendarPublication(array $calendarData, bool $publishStatus): void { $this->triggerCalendarActivity($publishStatus ? Calendar::SUBJECT_PUBLISH : Calendar::SUBJECT_UNPUBLISH, $calendarData); } @@ -165,6 +170,11 @@ class Backend { } foreach ($users as $user) { + if ($action === Calendar::SUBJECT_DELETE && !$this->userManager->userExists($user)) { + // Avoid creating calendar_delete activities for deleted users + continue; + } + $event->setAffectedUser($user) ->setSubject( $user === $currentUser ? $action . '_self' : $action, @@ -438,6 +448,11 @@ class Backend { $classification = $objectData['classification'] ?? CalDavBackend::CLASSIFICATION_PUBLIC; $object = $this->getObjectNameAndType($objectData); + + if (!$object) { + return; + } + $action = $action . '_' . $object['type']; if ($object['type'] === 'todo' && strpos($action, Event::SUBJECT_OBJECT_UPDATE) === 0 && $object['status'] === 'COMPLETED') { @@ -494,8 +509,103 @@ class Backend { } /** + * Creates activities when a calendar object was moved + */ + public function onMovedCalendarObject(array $sourceCalendarData, array $targetCalendarData, array $sourceShares, array $targetShares, array $objectData): void { + if (!isset($targetCalendarData['principaluri'])) { + return; + } + + $sourcePrincipal = explode('/', $sourceCalendarData['principaluri']); + $sourceOwner = array_pop($sourcePrincipal); + + $targetPrincipal = explode('/', $targetCalendarData['principaluri']); + $targetOwner = array_pop($targetPrincipal); + + if ($sourceOwner !== $targetOwner) { + $this->onTouchCalendarObject( + Event::SUBJECT_OBJECT_DELETE, + $sourceCalendarData, + $sourceShares, + $objectData + ); + $this->onTouchCalendarObject( + Event::SUBJECT_OBJECT_ADD, + $targetCalendarData, + $targetShares, + $objectData + ); + return; + } + + $currentUser = $this->userSession->getUser(); + if ($currentUser instanceof IUser) { + $currentUser = $currentUser->getUID(); + } else { + $currentUser = $targetOwner; + } + + $classification = $objectData['classification'] ?? CalDavBackend::CLASSIFICATION_PUBLIC; + $object = $this->getObjectNameAndType($objectData); + + if (!$object) { + return; + } + + $event = $this->activityManager->generateEvent(); + $event->setApp('dav') + ->setObject('calendar', (int) $targetCalendarData['id']) + ->setType($object['type'] === 'event' ? 'calendar_event' : 'calendar_todo') + ->setAuthor($currentUser); + + $users = $this->getUsersForShares(array_intersect($sourceShares, $targetShares)); + $users[] = $targetOwner; + + // Users for share can return the owner itself if the calendar is published + foreach (array_unique($users) as $user) { + if ($classification === CalDavBackend::CLASSIFICATION_PRIVATE && $user !== $targetOwner) { + // Private events are only shown to the owner + continue; + } + + $params = [ + 'actor' => $event->getAuthor(), + 'sourceCalendar' => [ + 'id' => (int) $sourceCalendarData['id'], + 'uri' => $sourceCalendarData['uri'], + 'name' => $sourceCalendarData['{DAV:}displayname'], + ], + 'targetCalendar' => [ + 'id' => (int) $targetCalendarData['id'], + 'uri' => $targetCalendarData['uri'], + 'name' => $targetCalendarData['{DAV:}displayname'], + ], + 'object' => [ + 'id' => $object['id'], + 'name' => $classification === CalDavBackend::CLASSIFICATION_CONFIDENTIAL && $user !== $targetOwner ? 'Busy' : $object['name'], + 'classified' => $classification === CalDavBackend::CLASSIFICATION_CONFIDENTIAL && $user !== $targetOwner, + ], + ]; + + if ($object['type'] === 'event' && $this->appManager->isEnabledForUser('calendar')) { + $params['object']['link']['object_uri'] = $objectData['uri']; + $params['object']['link']['calendar_uri'] = $targetCalendarData['uri']; + $params['object']['link']['owner'] = $targetOwner; + } + + $event->setAffectedUser($user) + ->setSubject( + $user === $currentUser ? Event::SUBJECT_OBJECT_MOVE . '_' . $object['type'] . '_self' : Event::SUBJECT_OBJECT_MOVE . '_' . $object['type'], + $params + ); + + $this->activityManager->publish($event); + } + } + + /** * @param array $objectData - * @return string[]|bool + * @return string[]|false */ protected function getObjectNameAndType(array $objectData) { $vObject = Reader::read($objectData['calendardata']); diff --git a/apps/dav/lib/CalDAV/Activity/Filter/Todo.php b/apps/dav/lib/CalDAV/Activity/Filter/Todo.php index f727c10befe..6f1dbbdcb5c 100644 --- a/apps/dav/lib/CalDAV/Activity/Filter/Todo.php +++ b/apps/dav/lib/CalDAV/Activity/Filter/Todo.php @@ -52,7 +52,7 @@ class Todo implements IFilter { * @since 11.0.0 */ public function getName() { - return $this->l->t('Todos'); + return $this->l->t('To-dos'); } /** diff --git a/apps/dav/lib/CalDAV/Activity/Provider/Event.php b/apps/dav/lib/CalDAV/Activity/Provider/Event.php index 3ed591219af..9ae04aadbba 100644 --- a/apps/dav/lib/CalDAV/Activity/Provider/Event.php +++ b/apps/dav/lib/CalDAV/Activity/Provider/Event.php @@ -40,6 +40,7 @@ use OCP\L10N\IFactory; class Event extends Base { public const SUBJECT_OBJECT_ADD = 'object_add'; public const SUBJECT_OBJECT_UPDATE = 'object_update'; + public const SUBJECT_OBJECT_MOVE = 'object_move'; public const SUBJECT_OBJECT_MOVE_TO_TRASH = 'object_move_to_trash'; public const SUBJECT_OBJECT_RESTORE = 'object_restore'; public const SUBJECT_OBJECT_DELETE = 'object_delete'; @@ -145,6 +146,10 @@ class Event extends Base { $subject = $this->l->t('{actor} updated event {event} in calendar {calendar}'); } elseif ($event->getSubject() === self::SUBJECT_OBJECT_UPDATE . '_event_self') { $subject = $this->l->t('You updated event {event} in calendar {calendar}'); + } elseif ($event->getSubject() === self::SUBJECT_OBJECT_MOVE . '_event') { + $subject = $this->l->t('{actor} moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}'); + } elseif ($event->getSubject() === self::SUBJECT_OBJECT_MOVE . '_event_self') { + $subject = $this->l->t('You moved event {event} from calendar {sourceCalendar} to calendar {targetCalendar}'); } elseif ($event->getSubject() === self::SUBJECT_OBJECT_MOVE_TO_TRASH . '_event') { $subject = $this->l->t('{actor} deleted event {event} from calendar {calendar}'); } elseif ($event->getSubject() === self::SUBJECT_OBJECT_MOVE_TO_TRASH . '_event_self') { @@ -198,6 +203,24 @@ class Event extends Base { } } + if (isset($parameters['sourceCalendar']) && isset($parameters['targetCalendar'])) { + switch ($subject) { + case self::SUBJECT_OBJECT_MOVE . '_event': + return [ + 'actor' => $this->generateUserParameter($parameters['actor']), + 'sourceCalendar' => $this->generateCalendarParameter($parameters['sourceCalendar'], $this->l), + 'targetCalendar' => $this->generateCalendarParameter($parameters['targetCalendar'], $this->l), + 'event' => $this->generateClassifiedObjectParameter($parameters['object']), + ]; + case self::SUBJECT_OBJECT_MOVE . '_event_self': + return [ + 'sourceCalendar' => $this->generateCalendarParameter($parameters['sourceCalendar'], $this->l), + 'targetCalendar' => $this->generateCalendarParameter($parameters['targetCalendar'], $this->l), + 'event' => $this->generateClassifiedObjectParameter($parameters['object']), + ]; + } + } + // Legacy - Do NOT Remove unless necessary // Removing this will break parsing of activities that were created on // Nextcloud 12, so we should keep this as long as it's acceptable. diff --git a/apps/dav/lib/CalDAV/Activity/Provider/Todo.php b/apps/dav/lib/CalDAV/Activity/Provider/Todo.php index a3ab81e38ae..e2ddb99a1af 100644 --- a/apps/dav/lib/CalDAV/Activity/Provider/Todo.php +++ b/apps/dav/lib/CalDAV/Activity/Provider/Todo.php @@ -50,25 +50,29 @@ class Todo extends Event { } if ($event->getSubject() === self::SUBJECT_OBJECT_ADD . '_todo') { - $subject = $this->l->t('{actor} created todo {todo} in list {calendar}'); + $subject = $this->l->t('{actor} created to-do {todo} in list {calendar}'); } elseif ($event->getSubject() === self::SUBJECT_OBJECT_ADD . '_todo_self') { - $subject = $this->l->t('You created todo {todo} in list {calendar}'); + $subject = $this->l->t('You created to-do {todo} in list {calendar}'); } elseif ($event->getSubject() === self::SUBJECT_OBJECT_DELETE . '_todo') { - $subject = $this->l->t('{actor} deleted todo {todo} from list {calendar}'); + $subject = $this->l->t('{actor} deleted to-do {todo} from list {calendar}'); } elseif ($event->getSubject() === self::SUBJECT_OBJECT_DELETE . '_todo_self') { - $subject = $this->l->t('You deleted todo {todo} from list {calendar}'); + $subject = $this->l->t('You deleted to-do {todo} from list {calendar}'); } elseif ($event->getSubject() === self::SUBJECT_OBJECT_UPDATE . '_todo') { - $subject = $this->l->t('{actor} updated todo {todo} in list {calendar}'); + $subject = $this->l->t('{actor} updated to-do {todo} in list {calendar}'); } elseif ($event->getSubject() === self::SUBJECT_OBJECT_UPDATE . '_todo_self') { - $subject = $this->l->t('You updated todo {todo} in list {calendar}'); + $subject = $this->l->t('You updated to-do {todo} in list {calendar}'); } elseif ($event->getSubject() === self::SUBJECT_OBJECT_UPDATE . '_todo_completed') { - $subject = $this->l->t('{actor} solved todo {todo} in list {calendar}'); + $subject = $this->l->t('{actor} solved to-do {todo} in list {calendar}'); } elseif ($event->getSubject() === self::SUBJECT_OBJECT_UPDATE . '_todo_completed_self') { - $subject = $this->l->t('You solved todo {todo} in list {calendar}'); + $subject = $this->l->t('You solved to-do {todo} in list {calendar}'); } elseif ($event->getSubject() === self::SUBJECT_OBJECT_UPDATE . '_todo_needs_action') { - $subject = $this->l->t('{actor} reopened todo {todo} in list {calendar}'); + $subject = $this->l->t('{actor} reopened to-do {todo} in list {calendar}'); } elseif ($event->getSubject() === self::SUBJECT_OBJECT_UPDATE . '_todo_needs_action_self') { - $subject = $this->l->t('You reopened todo {todo} in list {calendar}'); + $subject = $this->l->t('You reopened to-do {todo} in list {calendar}'); + } elseif ($event->getSubject() === self::SUBJECT_OBJECT_MOVE . '_todo') { + $subject = $this->l->t('{actor} moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}'); + } elseif ($event->getSubject() === self::SUBJECT_OBJECT_MOVE . '_todo_self') { + $subject = $this->l->t('You moved to-do {todo} from list {sourceCalendar} to list {targetCalendar}'); } else { throw new \InvalidArgumentException(); } @@ -114,6 +118,24 @@ class Todo extends Event { } } + if (isset($parameters['sourceCalendar']) && isset($parameters['targetCalendar'])) { + switch ($subject) { + case self::SUBJECT_OBJECT_MOVE . '_todo': + return [ + 'actor' => $this->generateUserParameter($parameters['actor']), + 'sourceCalendar' => $this->generateCalendarParameter($parameters['sourceCalendar'], $this->l), + 'targetCalendar' => $this->generateCalendarParameter($parameters['targetCalendar'], $this->l), + 'todo' => $this->generateObjectParameter($parameters['object']), + ]; + case self::SUBJECT_OBJECT_MOVE . '_todo_self': + return [ + 'sourceCalendar' => $this->generateCalendarParameter($parameters['sourceCalendar'], $this->l), + 'targetCalendar' => $this->generateCalendarParameter($parameters['targetCalendar'], $this->l), + 'todo' => $this->generateObjectParameter($parameters['object']), + ]; + } + } + // Legacy - Do NOT Remove unless necessary // Removing this will break parsing of activities that were created on // Nextcloud 12, so we should keep this as long as it's acceptable. diff --git a/apps/dav/lib/CalDAV/Activity/Setting/Todo.php b/apps/dav/lib/CalDAV/Activity/Setting/Todo.php index 7d27b30c4af..a4ac3f5d569 100644 --- a/apps/dav/lib/CalDAV/Activity/Setting/Todo.php +++ b/apps/dav/lib/CalDAV/Activity/Setting/Todo.php @@ -38,7 +38,7 @@ class Todo extends CalDAVSetting { * @since 11.0.0 */ public function getName() { - return $this->l->t('A calendar <strong>todo</strong> was modified'); + return $this->l->t('A calendar <strong>to-do</strong> was modified'); } /** diff --git a/apps/dav/lib/CalDAV/BirthdayService.php b/apps/dav/lib/CalDAV/BirthdayService.php index 1030768e26f..be6b0911538 100644 --- a/apps/dav/lib/CalDAV/BirthdayService.php +++ b/apps/dav/lib/CalDAV/BirthdayService.php @@ -14,6 +14,7 @@ declare(strict_types=1); * @author Sven Strickroth <email@cs-ware.de> * @author Thomas Müller <thomas.mueller@tmit.eu> * @author Valdnet <47037905+Valdnet@users.noreply.github.com> + * @author Cédric Neukom <github@webguy.ch> * * @license AGPL-3.0 * @@ -86,6 +87,9 @@ class BirthdayService { $targetPrincipals = $this->getAllAffectedPrincipals($addressBookId); $book = $this->cardDavBackEnd->getAddressBookById($addressBookId); + if ($book === null) { + return; + } $targetPrincipals[] = $book['principaluri']; $datesToSync = [ ['postfix' => '', 'field' => 'BDAY'], @@ -98,9 +102,14 @@ class BirthdayService { continue; } + $reminderOffset = $this->getReminderOffsetForUser($principalUri); + $calendar = $this->ensureCalendarExists($principalUri); + if ($calendar === null) { + return; + } foreach ($datesToSync as $type) { - $this->updateCalendar($cardUri, $cardData, $book, (int) $calendar['id'], $type); + $this->updateCalendar($cardUri, $cardData, $book, (int) $calendar['id'], $type, $reminderOffset); } } } @@ -148,12 +157,14 @@ class BirthdayService { * @param $cardData * @param $dateField * @param $postfix + * @param $reminderOffset * @return VCalendar|null * @throws InvalidDataException */ - public function buildDateFromContact(string $cardData, - string $dateField, - string $postfix):?VCalendar { + public function buildDateFromContact(string $cardData, + string $dateField, + string $postfix, + ?string $reminderOffset):?VCalendar { if (empty($cardData)) { return null; } @@ -258,11 +269,13 @@ class BirthdayService { if ($originalYear !== null) { $vEvent->{'X-NEXTCLOUD-BC-YEAR'} = (string) $originalYear; } - $alarm = $vCal->createComponent('VALARM'); - $alarm->add($vCal->createProperty('TRIGGER', '-PT0M', ['VALUE' => 'DURATION'])); - $alarm->add($vCal->createProperty('ACTION', 'DISPLAY')); - $alarm->add($vCal->createProperty('DESCRIPTION', $vEvent->{'SUMMARY'})); - $vEvent->add($alarm); + if ($reminderOffset) { + $alarm = $vCal->createComponent('VALARM'); + $alarm->add($vCal->createProperty('TRIGGER', $reminderOffset, ['VALUE' => 'DURATION'])); + $alarm->add($vCal->createProperty('ACTION', 'DISPLAY')); + $alarm->add($vCal->createProperty('DESCRIPTION', $vEvent->{'SUMMARY'})); + $vEvent->add($alarm); + } $vCal->add($vEvent); return $vCal; } @@ -273,6 +286,9 @@ class BirthdayService { public function resetForUser(string $user):void { $principal = 'principals/users/'.$user; $calendar = $this->calDavBackEnd->getCalendarByUri($principal, self::BIRTHDAY_CALENDAR_URI); + if (!$calendar) { + return; // The user's birthday calendar doesn't exist, no need to purge it + } $calendarObjects = $this->calDavBackEnd->getCalendarObjects($calendar['id'], CalDavBackend::CALENDAR_TYPE_CALENDAR); foreach ($calendarObjects as $calendarObject) { @@ -341,6 +357,7 @@ class BirthdayService { * @param array $book * @param int $calendarId * @param array $type + * @param string $reminderOffset * @throws InvalidDataException * @throws \Sabre\DAV\Exception\BadRequest */ @@ -348,9 +365,10 @@ class BirthdayService { string $cardData, array $book, int $calendarId, - array $type):void { + array $type, + ?string $reminderOffset):void { $objectUri = $book['uri'] . '-' . $cardUri . $type['postfix'] . '.ics'; - $calendarData = $this->buildDateFromContact($cardData, $type['field'], $type['postfix']); + $calendarData = $this->buildDateFromContact($cardData, $type['field'], $type['postfix'], $reminderOffset); $existing = $this->calDavBackEnd->getCalendarObject($calendarId, $objectUri); if ($calendarData === null) { if ($existing !== null) { @@ -391,14 +409,27 @@ class BirthdayService { } /** + * Extracts the userId part of a principal + * + * @param string $userPrincipal + * @return string|null + */ + private function principalToUserId(string $userPrincipal):?string { + if (substr($userPrincipal, 0, 17) === 'principals/users/') { + return substr($userPrincipal, 17); + } + return null; + } + + /** * Checks if the user opted-out of birthday calendars * * @param string $userPrincipal The user principal to check for * @return bool */ private function isUserEnabled(string $userPrincipal):bool { - if (strpos($userPrincipal, 'principals/users/') === 0) { - $userId = substr($userPrincipal, 17); + $userId = $this->principalToUserId($userPrincipal); + if ($userId !== null) { $isEnabled = $this->config->getUserValue($userId, 'dav', 'generateBirthdayCalendar', 'yes'); return $isEnabled === 'yes'; } @@ -408,6 +439,23 @@ class BirthdayService { } /** + * Get the reminder offset value for a user. This is a duration string (e.g. + * PT9H) or null if no reminder is wanted. + * + * @param string $userPrincipal + * @return string|null + */ + private function getReminderOffsetForUser(string $userPrincipal):?string { + $userId = $this->principalToUserId($userPrincipal); + if ($userId !== null) { + return $this->config->getUserValue($userId, 'dav', 'birthdayCalendarReminderOffset', 'PT9H') ?: null; + } + + // not sure how we got here, just be on the safe side and return the default value + return 'PT9H'; + } + + /** * Formats title of Birthday event * * @param string $field Field name like BDAY, ANNIVERSARY, ... diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index 8bdc084cd7b..2bbdc51f42e 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -52,6 +52,7 @@ use OCA\DAV\Events\CalendarDeletedEvent; use OCA\DAV\Events\CalendarMovedToTrashEvent; use OCA\DAV\Events\CalendarObjectCreatedEvent; use OCA\DAV\Events\CalendarObjectDeletedEvent; +use OCA\DAV\Events\CalendarObjectMovedEvent; use OCA\DAV\Events\CalendarObjectMovedToTrashEvent; use OCA\DAV\Events\CalendarObjectRestoredEvent; use OCA\DAV\Events\CalendarObjectUpdatedEvent; @@ -95,8 +96,6 @@ use Sabre\VObject\ParseException; use Sabre\VObject\Property; use Sabre\VObject\Reader; use Sabre\VObject\Recur\EventIterator; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; -use Symfony\Component\EventDispatcher\GenericEvent; use function array_column; use function array_merge; use function array_values; @@ -150,7 +149,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription * @var array * @psalm-var array<string, string[]> */ - public $propertyMap = [ + public array $propertyMap = [ '{DAV:}displayname' => ['displayname', 'string'], '{urn:ietf:params:xml:ns:caldav}calendar-description' => ['description', 'string'], '{urn:ietf:params:xml:ns:caldav}calendar-timezone' => ['timezone', 'string'], @@ -164,7 +163,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription * * @var array */ - public $subscriptionPropertyMap = [ + public array $subscriptionPropertyMap = [ '{DAV:}displayname' => ['displayname', 'string'], '{http://apple.com/ns/ical/}refreshrate' => ['refreshrate', 'string'], '{http://apple.com/ns/ical/}calendar-order' => ['calendarorder', 'int'], @@ -195,7 +194,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription ]; /** @var array parameters to index */ - public static $indexParameters = [ + public static array $indexParameters = [ 'ATTENDEE' => ['CN'], 'ORGANIZER' => ['CN'], ]; @@ -203,43 +202,19 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription /** * @var string[] Map of uid => display name */ - protected $userDisplayNames; - - /** @var IDBConnection */ - private $db; - - /** @var Backend */ - private $calendarSharingBackend; - - /** @var Principal */ - private $principalBackend; - - /** @var IUserManager */ - private $userManager; - - /** @var ISecureRandom */ - private $random; + protected array $userDisplayNames; + private IDBConnection $db; + private Backend $calendarSharingBackend; + private Principal $principalBackend; + private IUserManager $userManager; + private ISecureRandom $random; private LoggerInterface $logger; + private IEventDispatcher $dispatcher; + private IConfig $config; + private bool $legacyEndpoint; + private string $dbObjectPropertiesTable = 'calendarobjects_props'; - /** @var IEventDispatcher */ - private $dispatcher; - - /** @var EventDispatcherInterface */ - private $legacyDispatcher; - - /** @var IConfig */ - private $config; - - /** @var bool */ - private $legacyEndpoint; - - /** @var string */ - private $dbObjectPropertiesTable = 'calendarobjects_props'; - - /** - * CalDavBackend constructor. - */ public function __construct(IDBConnection $db, Principal $principalBackend, IUserManager $userManager, @@ -247,7 +222,6 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription ISecureRandom $random, LoggerInterface $logger, IEventDispatcher $dispatcher, - EventDispatcherInterface $legacyDispatcher, IConfig $config, bool $legacyEndpoint = false) { $this->db = $db; @@ -257,7 +231,6 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription $this->random = $random; $this->logger = $logger; $this->dispatcher = $dispatcher; - $this->legacyDispatcher = $legacyDispatcher; $this->config = $config; $this->legacyEndpoint = $legacyEndpoint; } @@ -701,10 +674,9 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription } /** - * @param $calendarId - * @return array|null + * @return array{id: int, uri: string, '{http://calendarserver.org/ns/}getctag': string, '{http://sabredav.org/ns}sync-token': int, '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set': SupportedCalendarComponentSet, '{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp': ScheduleCalendarTransp }|null */ - public function getCalendarById($calendarId) { + public function getCalendarById(int $calendarId): ?array { $fields = array_column($this->propertyMap, 0); $fields[] = 'id'; $fields[] = 'uri'; @@ -737,7 +709,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription 'uri' => $row['uri'], 'principaluri' => $this->convertPrincipal($row['principaluri'], !$this->legacyEndpoint), '{' . Plugin::NS_CALENDARSERVER . '}getctag' => 'http://sabre.io/ns/sync/' . ($row['synctoken']?$row['synctoken']:'0'), - '{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0', + '{http://sabredav.org/ns}sync-token' => $row['synctoken'] ?? 0, '{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet($components), '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'), ]; @@ -893,7 +865,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription $calendarData = $this->getCalendarById($calendarId); $shares = $this->getShares($calendarId); - $this->dispatcher->dispatchTyped(new CalendarUpdatedEvent((int)$calendarId, $calendarData, $shares, $mutations)); + $this->dispatcher->dispatchTyped(new CalendarUpdatedEvent($calendarId, $calendarData, $shares, $mutations)); return true; }); @@ -943,7 +915,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription // Only dispatch if we actually deleted anything if ($calendarData) { - $this->dispatcher->dispatchTyped(new CalendarDeletedEvent((int)$calendarId, $calendarData, $shares)); + $this->dispatcher->dispatchTyped(new CalendarDeletedEvent($calendarId, $calendarData, $shares)); } } else { $qbMarkCalendarDeleted = $this->db->getQueryBuilder(); @@ -956,7 +928,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription $shares = $this->getShares($calendarId); if ($calendarData) { $this->dispatcher->dispatchTyped(new CalendarMovedToTrashEvent( - (int)$calendarId, + $calendarId, $calendarData, $shares )); @@ -1292,24 +1264,17 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription $this->addChange($calendarId, $objectUri, 1, $calendarType); $objectRow = $this->getCalendarObject($calendarId, $objectUri, $calendarType); + assert($objectRow !== null); + if ($calendarType === self::CALENDAR_TYPE_CALENDAR) { $calendarRow = $this->getCalendarById($calendarId); $shares = $this->getShares($calendarId); - $this->dispatcher->dispatchTyped(new CalendarObjectCreatedEvent((int)$calendarId, $calendarRow, $shares, $objectRow)); + $this->dispatcher->dispatchTyped(new CalendarObjectCreatedEvent($calendarId, $calendarRow, $shares, $objectRow)); } else { $subscriptionRow = $this->getSubscriptionById($calendarId); - $this->dispatcher->dispatchTyped(new CachedCalendarObjectCreatedEvent((int)$calendarId, $subscriptionRow, [], $objectRow)); - $this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::createCachedCalendarObject', new GenericEvent( - '\OCA\DAV\CalDAV\CalDavBackend::createCachedCalendarObject', - [ - 'subscriptionId' => $calendarId, - 'calendarData' => $subscriptionRow, - 'shares' => [], - 'objectData' => $objectRow, - ] - )); + $this->dispatcher->dispatchTyped(new CachedCalendarObjectCreatedEvent($calendarId, $subscriptionRow, [], $objectRow)); } return '"' . $extraData['etag'] . '"'; @@ -1361,20 +1326,11 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription $calendarRow = $this->getCalendarById($calendarId); $shares = $this->getShares($calendarId); - $this->dispatcher->dispatchTyped(new CalendarObjectUpdatedEvent((int)$calendarId, $calendarRow, $shares, $objectRow)); + $this->dispatcher->dispatchTyped(new CalendarObjectUpdatedEvent($calendarId, $calendarRow, $shares, $objectRow)); } else { $subscriptionRow = $this->getSubscriptionById($calendarId); - $this->dispatcher->dispatchTyped(new CachedCalendarObjectUpdatedEvent((int)$calendarId, $subscriptionRow, [], $objectRow)); - $this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::updateCachedCalendarObject', new GenericEvent( - '\OCA\DAV\CalDAV\CalDavBackend::updateCachedCalendarObject', - [ - 'subscriptionId' => $calendarId, - 'calendarData' => $subscriptionRow, - 'shares' => [], - 'objectData' => $objectRow, - ] - )); + $this->dispatcher->dispatchTyped(new CachedCalendarObjectUpdatedEvent($calendarId, $subscriptionRow, [], $objectRow)); } } @@ -1387,13 +1343,14 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription * @param int $sourceCalendarId * @param int $targetCalendarId * @param int $objectId - * @param string $principalUri + * @param string $oldPrincipalUri + * @param string $newPrincipalUri * @param int $calendarType * @return bool * @throws Exception */ - public function moveCalendarObject(int $sourceCalendarId, int $targetCalendarId, int $objectId, string $principalUri, int $calendarType = self::CALENDAR_TYPE_CALENDAR): bool { - $object = $this->getCalendarObjectById($principalUri, $objectId); + public function moveCalendarObject(int $sourceCalendarId, int $targetCalendarId, int $objectId, string $oldPrincipalUri, string $newPrincipalUri, int $calendarType = self::CALENDAR_TYPE_CALENDAR): bool { + $object = $this->getCalendarObjectById($oldPrincipalUri, $objectId); if (empty($object)) { return false; } @@ -1411,21 +1368,23 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription $this->addChange($sourceCalendarId, $object['uri'], 1, $calendarType); $this->addChange($targetCalendarId, $object['uri'], 3, $calendarType); - $object = $this->getCalendarObjectById($principalUri, $objectId); + $object = $this->getCalendarObjectById($newPrincipalUri, $objectId); // Calendar Object wasn't found - possibly because it was deleted in the meantime by a different client if (empty($object)) { return false; } - $calendarRow = $this->getCalendarById($targetCalendarId); + $targetCalendarRow = $this->getCalendarById($targetCalendarId); // the calendar this event is being moved to does not exist any longer - if (empty($calendarRow)) { + if (empty($targetCalendarRow)) { return false; } if ($calendarType === self::CALENDAR_TYPE_CALENDAR) { - $shares = $this->getShares($targetCalendarId); - $this->dispatcher->dispatchTyped(new CalendarObjectUpdatedEvent($targetCalendarId, $calendarRow, $shares, $object)); + $sourceShares = $this->getShares($sourceCalendarId); + $targetShares = $this->getShares($targetCalendarId); + $sourceCalendarRow = $this->getCalendarById($sourceCalendarId); + $this->dispatcher->dispatchTyped(new CalendarObjectMovedEvent($sourceCalendarId, $sourceCalendarRow, $targetCalendarId, $targetCalendarRow, $sourceShares, $targetShares, $object)); } return true; } @@ -1477,20 +1436,11 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription $calendarRow = $this->getCalendarById($calendarId); $shares = $this->getShares($calendarId); - $this->dispatcher->dispatchTyped(new CalendarObjectDeletedEvent((int)$calendarId, $calendarRow, $shares, $data)); + $this->dispatcher->dispatchTyped(new CalendarObjectDeletedEvent($calendarId, $calendarRow, $shares, $data)); } else { $subscriptionRow = $this->getSubscriptionById($calendarId); - $this->dispatcher->dispatchTyped(new CachedCalendarObjectDeletedEvent((int)$calendarId, $subscriptionRow, [], $data)); - $this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::deleteCachedCalendarObject', new GenericEvent( - '\OCA\DAV\CalDAV\CalDavBackend::deleteCachedCalendarObject', - [ - 'subscriptionId' => $calendarId, - 'calendarData' => $subscriptionRow, - 'shares' => [], - 'objectData' => $data, - ] - )); + $this->dispatcher->dispatchTyped(new CachedCalendarObjectDeletedEvent($calendarId, $subscriptionRow, [], $data)); } } else { $pathInfo = pathinfo($data['uri']); @@ -1530,7 +1480,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription if ($calendarData !== null) { $this->dispatcher->dispatchTyped( new CalendarObjectMovedToTrashEvent( - (int)$calendarId, + $calendarId, $calendarData, $this->getShares($calendarId), $data @@ -1634,7 +1584,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription * Note that especially time-range-filters may be difficult to parse. A * time-range filter specified on a VEVENT must for instance also handle * recurrence rules correctly. - * A good example of how to interprete all these filters can also simply + * A good example of how to interpret all these filters can also simply * be found in Sabre\CalDAV\CalendarQueryFilter. This class is as correct * as possible, so it gives you a good idea on what type of stuff you need * to think of. @@ -2501,12 +2451,6 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription $subscriptionRow = $this->getSubscriptionById($subscriptionId); $this->dispatcher->dispatchTyped(new SubscriptionCreatedEvent($subscriptionId, $subscriptionRow)); - $this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::createSubscription', new GenericEvent( - '\OCA\DAV\CalDAV\CalDavBackend::createSubscription', - [ - 'subscriptionId' => $subscriptionId, - 'subscriptionData' => $subscriptionRow, - ])); return $subscriptionId; } @@ -2554,13 +2498,6 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription $subscriptionRow = $this->getSubscriptionById($subscriptionId); $this->dispatcher->dispatchTyped(new SubscriptionUpdatedEvent((int)$subscriptionId, $subscriptionRow, [], $mutations)); - $this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::updateSubscription', new GenericEvent( - '\OCA\DAV\CalDAV\CalDavBackend::updateSubscription', - [ - 'subscriptionId' => $subscriptionId, - 'subscriptionData' => $subscriptionRow, - 'propertyMutations' => $mutations, - ])); return true; }); @@ -2575,13 +2512,6 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription public function deleteSubscription($subscriptionId) { $subscriptionRow = $this->getSubscriptionById($subscriptionId); - $this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::deleteSubscription', new GenericEvent( - '\OCA\DAV\CalDAV\CalDavBackend::deleteSubscription', - [ - 'subscriptionId' => $subscriptionId, - 'subscriptionData' => $this->getSubscriptionById($subscriptionId), - ])); - $query = $this->db->getQueryBuilder(); $query->delete('calendarsubscriptions') ->where($query->expr()->eq('id', $query->createNamedParameter($subscriptionId))) @@ -2870,34 +2800,26 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription } /** - * @param IShareable $shareable - * @param array $add - * @param array $remove + * @param list<array{href: string, commonName: string, readOnly: bool}> $add + * @param list<string> $remove */ - public function updateShares($shareable, $add, $remove) { + public function updateShares(IShareable $shareable, array $add, array $remove): void { $calendarId = $shareable->getResourceId(); $calendarRow = $this->getCalendarById($calendarId); + if ($calendarRow === null) { + throw new \RuntimeException('Trying to update shares for innexistant calendar: ' . $calendarId); + } $oldShares = $this->getShares($calendarId); - $this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::updateShares', new GenericEvent( - '\OCA\DAV\CalDAV\CalDavBackend::updateShares', - [ - 'calendarId' => $calendarId, - 'calendarData' => $calendarRow, - 'shares' => $oldShares, - 'add' => $add, - 'remove' => $remove, - ])); $this->calendarSharingBackend->updateShares($shareable, $add, $remove); - $this->dispatcher->dispatchTyped(new CalendarShareUpdatedEvent((int)$calendarId, $calendarRow, $oldShares, $add, $remove)); + $this->dispatcher->dispatchTyped(new CalendarShareUpdatedEvent($calendarId, $calendarRow, $oldShares, $add, $remove)); } /** - * @param int $resourceId - * @return array + * @return list<array{href: string, commonName: string, status: int, readOnly: bool, '{http://owncloud.org/ns}principal': string, '{http://owncloud.org/ns}group-share': bool}> */ - public function getShares($resourceId) { + public function getShares(int $resourceId): array { return $this->calendarSharingBackend->getShares($resourceId); } @@ -2909,13 +2831,6 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription public function setPublishStatus($value, $calendar) { $calendarId = $calendar->getResourceId(); $calendarData = $this->getCalendarById($calendarId); - $this->legacyDispatcher->dispatch('\OCA\DAV\CalDAV\CalDavBackend::publishCalendar', new GenericEvent( - '\OCA\DAV\CalDAV\CalDavBackend::updateShares', - [ - 'calendarId' => $calendarId, - 'calendarData' => $calendarData, - 'public' => $value, - ])); $query = $this->db->getQueryBuilder(); if ($value) { @@ -2930,7 +2845,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription ]); $query->executeStatement(); - $this->dispatcher->dispatchTyped(new CalendarPublishedEvent((int)$calendarId, $calendarData, $publicUri)); + $this->dispatcher->dispatchTyped(new CalendarPublishedEvent($calendarId, $calendarData, $publicUri)); return $publicUri; } $query->delete('dav_shares') @@ -2938,7 +2853,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription ->andWhere($query->expr()->eq('access', $query->createNamedParameter(self::ACCESS_PUBLIC))); $query->executeStatement(); - $this->dispatcher->dispatchTyped(new CalendarUnpublishedEvent((int)$calendarId, $calendarData)); + $this->dispatcher->dispatchTyped(new CalendarUnpublishedEvent($calendarId, $calendarData)); return null; } @@ -2961,15 +2876,13 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription /** * @param int $resourceId - * @param array $acl - * @return array + * @param list<array{privilege: string, principal: string, protected: bool}> $acl + * @return list<array{privilege: string, principal: string, protected: bool}> */ - public function applyShareAcl($resourceId, $acl) { + public function applyShareAcl(int $resourceId, array $acl): array { return $this->calendarSharingBackend->applyShareAcl($resourceId, $acl); } - - /** * update properties table * diff --git a/apps/dav/lib/CalDAV/Calendar.php b/apps/dav/lib/CalDAV/Calendar.php index 75c815c3b0a..92ad3242d78 100644 --- a/apps/dav/lib/CalDAV/Calendar.php +++ b/apps/dav/lib/CalDAV/Calendar.php @@ -51,27 +51,11 @@ use Sabre\DAV\PropPatch; * @property CalDavBackend $caldavBackend */ class Calendar extends \Sabre\CalDAV\Calendar implements IRestorable, IShareable, IMoveTarget { + private IConfig $config; + protected IL10N $l10n; + private bool $useTrashbin = true; + private LoggerInterface $logger; - /** @var IConfig */ - private $config; - - /** @var IL10N */ - protected $l10n; - - /** @var bool */ - private $useTrashbin = true; - - /** @var LoggerInterface */ - private $logger; - - /** - * Calendar constructor. - * - * @param BackendInterface $caldavBackend - * @param $calendarInfo - * @param IL10N $l10n - * @param IConfig $config - */ public function __construct(BackendInterface $caldavBackend, $calendarInfo, IL10N $l10n, IConfig $config, LoggerInterface $logger) { // Convert deletion date to ISO8601 string if (isset($calendarInfo[TrashbinPlugin::PROPERTY_DELETED_AT])) { @@ -96,25 +80,10 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IRestorable, IShareable } /** - * Updates the list of shares. - * - * The first array is a list of people that are to be added to the - * resource. - * - * Every element in the add array has the following properties: - * * href - A url. Usually a mailto: address - * * commonName - Usually a first and last name, or false - * * summary - A description of the share, can also be false - * * readOnly - A boolean value - * - * Every element in the remove array is just the address string. - * - * @param array $add - * @param array $remove - * @return void + * {@inheritdoc} * @throws Forbidden */ - public function updateShares(array $add, array $remove) { + public function updateShares(array $add, array $remove): void { if ($this->isShared()) { throw new Forbidden(); } @@ -131,19 +100,16 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IRestorable, IShareable * * readOnly - boolean * * summary - Optional, a description for the share * - * @return array + * @return list<array{href: string, commonName: string, status: int, readOnly: bool, '{http://owncloud.org/ns}principal': string, '{http://owncloud.org/ns}group-share': bool}> */ - public function getShares() { + public function getShares(): array { if ($this->isShared()) { return []; } return $this->caldavBackend->getShares($this->getResourceId()); } - /** - * @return int - */ - public function getResourceId() { + public function getResourceId(): int { return $this->calendarInfo['id']; } @@ -155,7 +121,9 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IRestorable, IShareable } /** - * @return array + * @param int $resourceId + * @param list<array{privilege: string, principal: string, protected: bool}> $acl + * @return list<array{privilege: string, principal: ?string, protected: bool}> */ public function getACL() { $acl = [ @@ -246,16 +214,18 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IRestorable, IShareable parent::getOwner(), 'principals/system/public' ]; - return array_filter($acl, function ($rule) use ($allowedPrincipals) { + /** @var list<array{privilege: string, principal: string, protected: bool}> $acl */ + $acl = array_filter($acl, function (array $rule) use ($allowedPrincipals): bool { return \in_array($rule['principal'], $allowedPrincipals, true); }); + return $acl; } public function getChildACL() { return $this->getACL(); } - public function getOwner() { + public function getOwner(): ?string { if (isset($this->calendarInfo['{http://owncloud.org/ns}owner-principal'])) { return $this->calendarInfo['{http://owncloud.org/ns}owner-principal']; } @@ -400,7 +370,7 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IRestorable, IShareable return isset($this->calendarInfo['{http://owncloud.org/ns}public']); } - protected function isShared() { + public function isShared() { if (!isset($this->calendarInfo['{http://owncloud.org/ns}owner-principal'])) { return false; } @@ -412,6 +382,13 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IRestorable, IShareable return isset($this->calendarInfo['{http://calendarserver.org/ns/}source']); } + public function isDeleted(): bool { + if (!isset($this->calendarInfo[TrashbinPlugin::PROPERTY_DELETED_AT])) { + return false; + } + return $this->calendarInfo[TrashbinPlugin::PROPERTY_DELETED_AT] !== null; + } + /** * @inheritDoc */ @@ -443,7 +420,7 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IRestorable, IShareable } try { - return $this->caldavBackend->moveCalendarObject($sourceNode->getCalendarId(), (int)$this->calendarInfo['id'], $sourceNode->getId(), $sourceNode->getPrincipalUri()); + return $this->caldavBackend->moveCalendarObject($sourceNode->getCalendarId(), (int)$this->calendarInfo['id'], $sourceNode->getId(), $sourceNode->getOwner(), $this->getOwner()); } catch (Exception $e) { $this->logger->error('Could not move calendar object: ' . $e->getMessage(), ['exception' => $e]); return false; diff --git a/apps/dav/lib/CalDAV/CalendarImpl.php b/apps/dav/lib/CalDAV/CalendarImpl.php index 406389e3a3d..27a428a4075 100644 --- a/apps/dav/lib/CalDAV/CalendarImpl.php +++ b/apps/dav/lib/CalDAV/CalendarImpl.php @@ -138,7 +138,7 @@ class CalendarImpl implements ICreateFromString { * Create a new calendar event for this calendar * by way of an ICS string * - * @param string $name the file name - needs to contan the .ics ending + * @param string $name the file name - needs to contain the .ics ending * @param string $calendarData a string containing a valid VEVENT ics * * @throws CalendarException diff --git a/apps/dav/lib/CalDAV/CalendarObject.php b/apps/dav/lib/CalDAV/CalendarObject.php index c927254fba3..32bcff900c2 100644 --- a/apps/dav/lib/CalDAV/CalendarObject.php +++ b/apps/dav/lib/CalDAV/CalendarObject.php @@ -162,4 +162,11 @@ class CalendarObject extends \Sabre\CalDAV\CalendarObject { public function getPrincipalUri(): string { return $this->calendarInfo['principaluri']; } + + public function getOwner(): ?string { + if (isset($this->calendarInfo['{http://owncloud.org/ns}owner-principal'])) { + return $this->calendarInfo['{http://owncloud.org/ns}owner-principal']; + } + return parent::getOwner(); + } } diff --git a/apps/dav/lib/CalDAV/PublicCalendar.php b/apps/dav/lib/CalDAV/PublicCalendar.php index 4a29c8d237a..16c7f86917d 100644 --- a/apps/dav/lib/CalDAV/PublicCalendar.php +++ b/apps/dav/lib/CalDAV/PublicCalendar.php @@ -84,7 +84,7 @@ class PublicCalendar extends Calendar { * public calendars are always shared * @return bool */ - protected function isShared() { + public function isShared() { return true; } } diff --git a/apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php b/apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php index 35bce872bf8..cbff5e66a85 100644 --- a/apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php +++ b/apps/dav/lib/CalDAV/Publishing/Xml/Publisher.php @@ -55,7 +55,7 @@ class Publisher implements XmlSerializable { } /** - * The xmlSerialize metod is called during xml writing. + * The xmlSerialize method is called during xml writing. * * Use the $writer argument to write its own xml serialization. * diff --git a/apps/dav/lib/CalDAV/Schedule/Plugin.php b/apps/dav/lib/CalDAV/Schedule/Plugin.php index 96bacce4454..44517541faa 100644 --- a/apps/dav/lib/CalDAV/Schedule/Plugin.php +++ b/apps/dav/lib/CalDAV/Schedule/Plugin.php @@ -30,6 +30,7 @@ namespace OCA\DAV\CalDAV\Schedule; use DateTimeZone; use OCA\DAV\CalDAV\CalDavBackend; +use OCA\DAV\CalDAV\Calendar; use OCA\DAV\CalDAV\CalendarHome; use OCP\IConfig; use Sabre\CalDAV\ICalendar; @@ -178,7 +179,7 @@ class Plugin extends \Sabre\CalDAV\Schedule\Plugin { // If parent::scheduleLocalDelivery set scheduleStatus to 1.2, // it means that it was successfully delivered locally. - // Meaning that the ACL plugin is loaded and that a principial + // Meaning that the ACL plugin is loaded and that a principal // exists for the given recipient id, no need to double check /** @var \Sabre\DAVACL\Plugin $aclPlugin */ $aclPlugin = $this->server->getPlugin('acl'); @@ -299,12 +300,14 @@ EOF; return null; } + $isResourceOrRoom = strpos($principalUrl, 'principals/calendar-resources') === 0 || + strpos($principalUrl, 'principals/calendar-rooms') === 0; + if (strpos($principalUrl, 'principals/users') === 0) { [, $userId] = split($principalUrl); $uri = $this->config->getUserValue($userId, 'dav', 'defaultCalendar', CalDavBackend::PERSONAL_CALENDAR_URI); $displayName = CalDavBackend::PERSONAL_CALENDAR_NAME; - } elseif (strpos($principalUrl, 'principals/calendar-resources') === 0 || - strpos($principalUrl, 'principals/calendar-rooms') === 0) { + } elseif ($isResourceOrRoom) { $uri = CalDavBackend::RESOURCE_BOOKING_CALENDAR_URI; $displayName = CalDavBackend::RESOURCE_BOOKING_CALENDAR_NAME; } else { @@ -316,9 +319,40 @@ EOF; /** @var CalendarHome $calendarHome */ $calendarHome = $this->server->tree->getNodeForPath($calendarHomePath); if (!$calendarHome->childExists($uri)) { - $calendarHome->getCalDAVBackend()->createCalendar($principalUrl, $uri, [ - '{DAV:}displayname' => $displayName, - ]); + // If the default calendar doesn't exist + if ($isResourceOrRoom) { + $calendarHome->getCalDAVBackend()->createCalendar($principalUrl, $uri, [ + '{DAV:}displayname' => $displayName, + ]); + } else { + // And we're not handling scheduling on resource/room booking + $userCalendars = []; + /** + * If the default calendar of the user isn't set and the + * fallback doesn't match any of the user's calendar + * try to find the first "personal" calendar we can write to + * instead of creating a new one. + * A appropriate personal calendar to receive invites: + * - isn't a calendar subscription + * - user can write to it (no virtual/3rd-party calendars) + * - calendar isn't a share + */ + foreach ($calendarHome->getChildren() as $node) { + if ($node instanceof Calendar && !$node->isSubscription() && $node->canWrite() && !$node->isShared() && !$node->isDeleted()) { + $userCalendars[] = $node; + } + } + + if (count($userCalendars) > 0) { + // Calendar backend returns calendar by calendarorder property + $uri = $userCalendars[0]->getName(); + } else { + // Otherwise if we have really nothing, create a new calendar + $calendarHome->getCalDAVBackend()->createCalendar($principalUrl, $uri, [ + '{DAV:}displayname' => $displayName, + ]); + } + } } $result = $this->server->getPropertiesForPath($calendarHomePath . '/' . $uri, [], 1); @@ -533,7 +567,7 @@ EOF; } // If more than one Free-Busy property was returned, it means that an event - // starts or ends inside this time-range, so it's not availabe and we return false + // starts or ends inside this time-range, so it's not available and we return false if (count($freeBusyProperties) > 1) { return false; } diff --git a/apps/dav/lib/CalDAV/WebcalCaching/RefreshWebcalService.php b/apps/dav/lib/CalDAV/WebcalCaching/RefreshWebcalService.php index 0dbe7398f52..eadeea3457c 100644 --- a/apps/dav/lib/CalDAV/WebcalCaching/RefreshWebcalService.php +++ b/apps/dav/lib/CalDAV/WebcalCaching/RefreshWebcalService.php @@ -56,14 +56,15 @@ use function count; class RefreshWebcalService { /** @var CalDavBackend */ - private $calDavBackend; + private CalDavBackend $calDavBackend; /** @var IClientService */ - private $clientService; + private IClientService $clientService; /** @var IConfig */ - private $config; + private IConfig $config; + /** @var LoggerInterface */ private LoggerInterface $logger; public const REFRESH_RATE = '{http://apple.com/ns/ical/}refreshrate'; @@ -71,13 +72,7 @@ class RefreshWebcalService { public const STRIP_ATTACHMENTS = '{http://calendarserver.org/ns/}subscribed-strip-attachments'; public const STRIP_TODOS = '{http://calendarserver.org/ns/}subscribed-strip-todos'; - /** - * RefreshWebcalJob constructor. - */ - public function __construct(CalDavBackend $calDavBackend, - IClientService $clientService, - IConfig $config, - LoggerInterface $logger) { + public function __construct(CalDavBackend $calDavBackend, IClientService $clientService, IConfig $config, LoggerInterface $logger) { $this->calDavBackend = $calDavBackend; $this->clientService = $clientService; $this->config = $config; @@ -131,12 +126,12 @@ class RefreshWebcalService { continue; } - $uri = $this->getRandomCalendarObjectUri(); + $objectUri = $this->getRandomCalendarObjectUri(); $calendarData = $vObject->serialize(); try { - $this->calDavBackend->createCalendarObject($subscription['id'], $uri, $calendarData, CalDavBackend::CALENDAR_TYPE_SUBSCRIPTION); + $this->calDavBackend->createCalendarObject($subscription['id'], $objectUri, $calendarData, CalDavBackend::CALENDAR_TYPE_SUBSCRIPTION); } catch (NoInstancesException | BadRequest $ex) { - $this->logger->error($ex->getMessage(), ['exception' => $ex]); + $this->logger->error('Unable to create calendar object from subscription {subscriptionId}', ['exception' => $ex, 'subscriptionId' => $subscription['id'], 'source' => $subscription['source']]); } } @@ -147,20 +142,14 @@ class RefreshWebcalService { $this->updateSubscription($subscription, $mutations); } catch (ParseException $ex) { - $subscriptionId = $subscription['id']; - - $this->logger->error("Subscription $subscriptionId could not be refreshed due to a parsing error", ['exception' => $ex]); + $this->logger->error("Subscription {subscriptionId} could not be refreshed due to a parsing error", ['exception' => $ex, 'subscriptionId' => $subscription['id']]); } } /** * loads subscription from backend - * - * @param string $principalUri - * @param string $uri - * @return array|null */ - public function getSubscription(string $principalUri, string $uri) { + public function getSubscription(string $principalUri, string $uri): ?array { $subscriptions = array_values(array_filter( $this->calDavBackend->getSubscriptionsForUser($principalUri), function ($sub) use ($uri) { @@ -177,12 +166,8 @@ class RefreshWebcalService { /** * gets webcal feed from remote server - * - * @param array $subscription - * @param array &$mutations - * @return null|string */ - private function queryWebcalFeed(array $subscription, array &$mutations) { + private function queryWebcalFeed(array $subscription, array &$mutations): ?string { $client = $this->clientService->newClient(); $didBreak301Chain = false; @@ -244,7 +229,7 @@ class RefreshWebcalService { $jCalendar = Reader::readJson($body, Reader::OPTION_FORGIVING); } catch (Exception $ex) { // In case of a parsing error return null - $this->logger->debug("Subscription $subscriptionId could not be parsed"); + $this->logger->warning("Subscription $subscriptionId could not be parsed", ['exception' => $ex]); return null; } return $jCalendar->serialize(); @@ -254,7 +239,7 @@ class RefreshWebcalService { $xCalendar = Reader::readXML($body); } catch (Exception $ex) { // In case of a parsing error return null - $this->logger->debug("Subscription $subscriptionId could not be parsed"); + $this->logger->warning("Subscription $subscriptionId could not be parsed", ['exception' => $ex]); return null; } return $xCalendar->serialize(); @@ -265,7 +250,7 @@ class RefreshWebcalService { $vCalendar = Reader::read($body); } catch (Exception $ex) { // In case of a parsing error return null - $this->logger->debug("Subscription $subscriptionId could not be parsed"); + $this->logger->warning("Subscription $subscriptionId could not be parsed", ['exception' => $ex]); return null; } return $vCalendar->serialize(); @@ -291,11 +276,8 @@ class RefreshWebcalService { * - the webcal feed suggests a refreshrate * - return suggested refreshrate if user didn't set a custom one * - * @param array $subscription - * @param string $webcalData - * @return string|null */ - private function checkWebcalDataForRefreshRate($subscription, $webcalData) { + private function checkWebcalDataForRefreshRate(array $subscription, string $webcalData): ?string { // if there is no refreshrate stored in the database, check the webcal feed // whether it suggests any refresh rate and store that in the database if (isset($subscription[self::REFRESH_RATE]) && $subscription[self::REFRESH_RATE] !== null) { @@ -353,7 +335,7 @@ class RefreshWebcalService { * @param string $url * @return string|null */ - private function cleanURL(string $url) { + private function cleanURL(string $url): ?string { $parsed = parse_url($url); if ($parsed === false) { return null; diff --git a/apps/dav/lib/CardDAV/Activity/Backend.php b/apps/dav/lib/CardDAV/Activity/Backend.php index b713284e182..8c8c643e287 100644 --- a/apps/dav/lib/CardDAV/Activity/Backend.php +++ b/apps/dav/lib/CardDAV/Activity/Backend.php @@ -32,6 +32,7 @@ use OCP\App\IAppManager; use OCP\IGroup; use OCP\IGroupManager; use OCP\IUser; +use OCP\IUserManager; use OCP\IUserSession; use Sabre\CardDAV\Plugin; use Sabre\VObject\Reader; @@ -50,14 +51,19 @@ class Backend { /** @var IAppManager */ protected $appManager; + /** @var IUserManager */ + protected $userManager; + public function __construct(IActivityManager $activityManager, IGroupManager $groupManager, IUserSession $userSession, - IAppManager $appManager) { + IAppManager $appManager, + IUserManager $userManager) { $this->activityManager = $activityManager; $this->groupManager = $groupManager; $this->userSession = $userSession; $this->appManager = $appManager; + $this->userManager = $userManager; } /** @@ -103,7 +109,14 @@ class Backend { return; } - $principal = explode('/', $addressbookData['principaluri']); + $principalUri = $addressbookData['principaluri']; + + // We are not interested in changes from the system addressbook + if ($principalUri === 'principals/system/system') { + return; + } + + $principal = explode('/', $principalUri); $owner = array_pop($principal); $currentUser = $this->userSession->getUser(); @@ -132,6 +145,11 @@ class Backend { } foreach ($users as $user) { + if ($action === Addressbook::SUBJECT_DELETE && !$this->userManager->userExists($user)) { + // Avoid creating addressbook_delete activities for deleted users + continue; + } + $event->setAffectedUser($user) ->setSubject( $user === $currentUser ? $action . '_self' : $action, @@ -393,7 +411,14 @@ class Backend { return; } - $principal = explode('/', $addressbookData['principaluri']); + $principalUri = $addressbookData['principaluri']; + + // We are not interested in changes from the system addressbook + if ($principalUri === 'principals/system/system') { + return; + } + + $principal = explode('/', $principalUri); $owner = array_pop($principal); $currentUser = $this->userSession->getUser(); diff --git a/apps/dav/lib/CardDAV/AddressBook.php b/apps/dav/lib/CardDAV/AddressBook.php index 9bd24bedbac..bca478feec1 100644 --- a/apps/dav/lib/CardDAV/AddressBook.php +++ b/apps/dav/lib/CardDAV/AddressBook.php @@ -67,17 +67,15 @@ class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareable { * Every element in the add array has the following properties: * * href - A url. Usually a mailto: address * * commonName - Usually a first and last name, or false - * * summary - A description of the share, can also be false * * readOnly - A boolean value * * Every element in the remove array is just the address string. * - * @param array $add - * @param array $remove - * @return void + * @param list<array{href: string, commonName: string, readOnly: bool}> $add + * @param list<string> $remove * @throws Forbidden */ - public function updateShares(array $add, array $remove) { + public function updateShares(array $add, array $remove): void { if ($this->isShared()) { throw new Forbidden(); } @@ -92,11 +90,10 @@ class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareable { * * commonName - Optional, for example a first + last name * * status - See the Sabre\CalDAV\SharingPlugin::STATUS_ constants. * * readOnly - boolean - * * summary - Optional, a description for the share * - * @return array + * @return list<array{href: string, commonName: string, status: int, readOnly: bool, '{http://owncloud.org/ns}principal': string, '{http://owncloud.org/ns}group-share': bool}> */ - public function getShares() { + public function getShares(): array { if ($this->isShared()) { return []; } @@ -163,14 +160,11 @@ class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareable { return new Card($this->carddavBackend, $this->addressBookInfo, $obj); } - /** - * @return int - */ - public function getResourceId() { + public function getResourceId(): int { return $this->addressBookInfo['id']; } - public function getOwner() { + public function getOwner(): ?string { if (isset($this->addressBookInfo['{http://owncloud.org/ns}owner-principal'])) { return $this->addressBookInfo['{http://owncloud.org/ns}owner-principal']; } @@ -207,7 +201,7 @@ class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareable { return $this->carddavBackend->collectCardProperties($this->getResourceId(), 'CATEGORIES'); } - private function isShared() { + private function isShared(): bool { if (!isset($this->addressBookInfo['{http://owncloud.org/ns}owner-principal'])) { return false; } @@ -215,7 +209,7 @@ class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareable { return $this->addressBookInfo['{http://owncloud.org/ns}owner-principal'] !== $this->addressBookInfo['principaluri']; } - private function canWrite() { + private function canWrite(): bool { if (isset($this->addressBookInfo['{http://owncloud.org/ns}read-only'])) { return !$this->addressBookInfo['{http://owncloud.org/ns}read-only']; } diff --git a/apps/dav/lib/CardDAV/AddressBookImpl.php b/apps/dav/lib/CardDAV/AddressBookImpl.php index 3db20cb4220..2f7f0a22900 100644 --- a/apps/dav/lib/CardDAV/AddressBookImpl.php +++ b/apps/dav/lib/CardDAV/AddressBookImpl.php @@ -12,6 +12,7 @@ * @author Joas Schilling <coding@schilljs.com> * @author John Molakvoæ <skjnldsv@protonmail.com> * @author Julius Härtl <jus@bitgrid.net> + * @author Thomas Citharel <nextcloud@tcit.fr> * @author Thomas Müller <thomas.mueller@tmit.eu> * * @license AGPL-3.0 @@ -206,7 +207,7 @@ class AddressBookImpl implements IAddressBook { } /** - * @param object $id the unique identifier to a contact + * @param int $id the unique identifier to a contact * @return bool successful or not * @since 5.0.0 */ diff --git a/apps/dav/lib/CardDAV/CardDavBackend.php b/apps/dav/lib/CardDAV/CardDavBackend.php index 864f3da9367..a9ca2eb30a3 100644 --- a/apps/dav/lib/CardDAV/CardDavBackend.php +++ b/apps/dav/lib/CardDAV/CardDavBackend.php @@ -58,30 +58,19 @@ use Sabre\CardDAV\Plugin; use Sabre\DAV\Exception\BadRequest; use Sabre\VObject\Component\VCard; use Sabre\VObject\Reader; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; -use Symfony\Component\EventDispatcher\GenericEvent; class CardDavBackend implements BackendInterface, SyncSupport { public const PERSONAL_ADDRESSBOOK_URI = 'contacts'; public const PERSONAL_ADDRESSBOOK_NAME = 'Contacts'; - /** @var Principal */ - private $principalBackend; - - /** @var string */ - private $dbCardsTable = 'cards'; - - /** @var string */ - private $dbCardsPropertiesTable = 'cards_properties'; - - /** @var IDBConnection */ - private $db; - - /** @var Backend */ - private $sharingBackend; + private Principal $principalBackend; + private string $dbCardsTable = 'cards'; + private string $dbCardsPropertiesTable = 'cards_properties'; + private IDBConnection $db; + private Backend $sharingBackend; /** @var array properties to index */ - public static $indexProperties = [ + public static array $indexProperties = [ 'BDAY', 'UID', 'N', 'FN', 'TITLE', 'ROLE', 'NOTE', 'NICKNAME', 'ORG', 'CATEGORIES', 'EMAIL', 'TEL', 'IMPP', 'ADR', 'URL', 'GEO', 'CLOUD', 'X-SOCIALPROFILE']; @@ -89,18 +78,10 @@ class CardDavBackend implements BackendInterface, SyncSupport { /** * @var string[] Map of uid => display name */ - protected $userDisplayNames; - - /** @var IUserManager */ - private $userManager; - - /** @var IEventDispatcher */ - private $dispatcher; - - /** @var EventDispatcherInterface */ - private $legacyDispatcher; - - private $etagCache = []; + protected array $userDisplayNames; + private IUserManager $userManager; + private IEventDispatcher $dispatcher; + private array $etagCache = []; /** * CardDavBackend constructor. @@ -110,19 +91,16 @@ class CardDavBackend implements BackendInterface, SyncSupport { * @param IUserManager $userManager * @param IGroupManager $groupManager * @param IEventDispatcher $dispatcher - * @param EventDispatcherInterface $legacyDispatcher */ public function __construct(IDBConnection $db, Principal $principalBackend, IUserManager $userManager, IGroupManager $groupManager, - IEventDispatcher $dispatcher, - EventDispatcherInterface $legacyDispatcher) { + IEventDispatcher $dispatcher) { $this->db = $db; $this->principalBackend = $principalBackend; $this->userManager = $userManager; $this->dispatcher = $dispatcher; - $this->legacyDispatcher = $legacyDispatcher; $this->sharingBackend = new Backend($this->db, $this->userManager, $groupManager, $principalBackend, 'addressbook'); } @@ -318,18 +296,14 @@ class CardDavBackend implements BackendInterface, SyncSupport { return $addressBook; } - /** - * @param $addressBookUri - * @return array|null - */ - public function getAddressBooksByUri($principal, $addressBookUri) { + public function getAddressBooksByUri(string $principal, string $addressBookUri): ?array { $query = $this->db->getQueryBuilder(); $result = $query->select(['id', 'uri', 'displayname', 'principaluri', 'description', 'synctoken']) ->from('addressbooks') ->where($query->expr()->eq('uri', $query->createNamedParameter($addressBookUri))) ->andWhere($query->expr()->eq('principaluri', $query->createNamedParameter($principal))) ->setMaxResults(1) - ->execute(); + ->executeQuery(); $row = $result->fetch(); $result->closeCursor(); @@ -393,12 +367,12 @@ class CardDavBackend implements BackendInterface, SyncSupport { $query->set($key, $query->createNamedParameter($value)); } $query->where($query->expr()->eq('id', $query->createNamedParameter($addressBookId))) - ->execute(); + ->executeStatement(); $this->addChange($addressBookId, "", 2); $addressBookRow = $this->getAddressBookById((int)$addressBookId); - $shares = $this->getShares($addressBookId); + $shares = $this->getShares((int)$addressBookId); $this->dispatcher->dispatchTyped(new AddressBookUpdatedEvent((int)$addressBookId, $addressBookRow, $shares, $mutations)); return true; @@ -468,30 +442,31 @@ class CardDavBackend implements BackendInterface, SyncSupport { * @return void */ public function deleteAddressBook($addressBookId) { + $addressBookId = (int)$addressBookId; $addressBookData = $this->getAddressBookById($addressBookId); $shares = $this->getShares($addressBookId); $query = $this->db->getQueryBuilder(); $query->delete($this->dbCardsTable) ->where($query->expr()->eq('addressbookid', $query->createParameter('addressbookid'))) - ->setParameter('addressbookid', $addressBookId) - ->execute(); + ->setParameter('addressbookid', $addressBookId, IQueryBuilder::PARAM_INT) + ->executeStatement(); $query->delete('addressbookchanges') ->where($query->expr()->eq('addressbookid', $query->createParameter('addressbookid'))) - ->setParameter('addressbookid', $addressBookId) - ->execute(); + ->setParameter('addressbookid', $addressBookId, IQueryBuilder::PARAM_INT) + ->executeStatement(); $query->delete('addressbooks') ->where($query->expr()->eq('id', $query->createParameter('id'))) - ->setParameter('id', $addressBookId) - ->execute(); + ->setParameter('id', $addressBookId, IQueryBuilder::PARAM_INT) + ->executeStatement(); $this->sharingBackend->deleteAllShares($addressBookId); $query->delete($this->dbCardsPropertiesTable) - ->where($query->expr()->eq('addressbookid', $query->createNamedParameter($addressBookId))) - ->execute(); + ->where($query->expr()->eq('addressbookid', $query->createNamedParameter($addressBookId, IQueryBuilder::PARAM_INT))) + ->executeStatement(); if ($addressBookData) { $this->dispatcher->dispatchTyped(new AddressBookDeletedEvent($addressBookId, $addressBookData, $shares)); @@ -511,7 +486,7 @@ class CardDavBackend implements BackendInterface, SyncSupport { * * size - The size of the card in bytes. * * If these last two properties are provided, less time will be spent - * calculating them. If they are specified, you can also ommit carddata. + * calculating them. If they are specified, you can also omit carddata. * This may speed up certain requests, especially with large cards. * * @param mixed $addressbookId @@ -692,11 +667,6 @@ class CardDavBackend implements BackendInterface, SyncSupport { $shares = $this->getShares($addressBookId); $objectRow = $this->getCard($addressBookId, $cardUri); $this->dispatcher->dispatchTyped(new CardCreatedEvent($addressBookId, $addressBookData, $shares, $objectRow)); - $this->legacyDispatcher->dispatch('\OCA\DAV\CardDAV\CardDavBackend::createCard', - new GenericEvent(null, [ - 'addressBookId' => $addressBookId, - 'cardUri' => $cardUri, - 'cardData' => $cardData])); return '"' . $etag . '"'; } @@ -756,12 +726,6 @@ class CardDavBackend implements BackendInterface, SyncSupport { $shares = $this->getShares($addressBookId); $objectRow = $this->getCard($addressBookId, $cardUri); $this->dispatcher->dispatchTyped(new CardUpdatedEvent($addressBookId, $addressBookData, $shares, $objectRow)); - $this->legacyDispatcher->dispatch('\OCA\DAV\CardDAV\CardDavBackend::updateCard', - new GenericEvent(null, [ - 'addressBookId' => $addressBookId, - 'cardUri' => $cardUri, - 'cardData' => $cardData])); - return '"' . $etag . '"'; } @@ -793,11 +757,6 @@ class CardDavBackend implements BackendInterface, SyncSupport { if ($ret === 1) { if ($cardId !== null) { $this->dispatcher->dispatchTyped(new CardDeletedEvent($addressBookId, $addressBookData, $shares, $objectRow)); - $this->legacyDispatcher->dispatch('\OCA\DAV\CardDAV\CardDavBackend::deleteCard', - new GenericEvent(null, [ - 'addressBookId' => $addressBookId, - 'cardUri' => $cardUri])); - $this->purgeProperties($addressBookId, $cardId); } return true; @@ -1002,11 +961,10 @@ class CardDavBackend implements BackendInterface, SyncSupport { } /** - * @param IShareable $shareable - * @param string[] $add - * @param string[] $remove + * @param list<array{href: string, commonName: string, readOnly: bool}> $add + * @param list<string> $remove */ - public function updateShares(IShareable $shareable, $add, $remove) { + public function updateShares(IShareable $shareable, array $add, array $remove): void { $addressBookId = $shareable->getResourceId(); $addressBookData = $this->getAddressBookById($addressBookId); $oldShares = $this->getShares($addressBookId); @@ -1237,11 +1195,10 @@ class CardDavBackend implements BackendInterface, SyncSupport { * * commonName - Optional, for example a first + last name * * status - See the Sabre\CalDAV\SharingPlugin::STATUS_ constants. * * readOnly - boolean - * * summary - Optional, a description for the share * - * @return array + * @return list<array{href: string, commonName: string, status: int, readOnly: bool, '{http://owncloud.org/ns}principal': string, '{http://owncloud.org/ns}group-share': bool}> */ - public function getShares($addressBookId) { + public function getShares(int $addressBookId): array { return $this->sharingBackend->getShares($addressBookId); } @@ -1321,13 +1278,9 @@ class CardDavBackend implements BackendInterface, SyncSupport { } /** - * get ID from a given contact - * - * @param int $addressBookId - * @param string $uri - * @return int + * Get ID from a given contact */ - protected function getCardId($addressBookId, $uri) { + protected function getCardId(int $addressBookId, string $uri): int { $query = $this->db->getQueryBuilder(); $query->select('id')->from($this->dbCardsTable) ->where($query->expr()->eq('uri', $query->createNamedParameter($uri))) @@ -1347,15 +1300,15 @@ class CardDavBackend implements BackendInterface, SyncSupport { /** * For shared address books the sharee is set in the ACL of the address book * - * @param $addressBookId - * @param $acl - * @return array + * @param int $addressBookId + * @param list<array{privilege: string, principal: string, protected: bool}> $acl + * @return list<array{privilege: string, principal: string, protected: bool}> */ - public function applyShareAcl($addressBookId, $acl) { + public function applyShareAcl(int $addressBookId, array $acl): array { return $this->sharingBackend->applyShareAcl($addressBookId, $acl); } - private function convertPrincipal($principalUri, $toV2) { + private function convertPrincipal(string $principalUri, bool $toV2): string { if ($this->principalBackend->getPrincipalPrefix() === 'principals') { [, $name] = \Sabre\Uri\split($principalUri); if ($toV2 === true) { @@ -1366,7 +1319,7 @@ class CardDavBackend implements BackendInterface, SyncSupport { return $principalUri; } - private function addOwnerPrincipal(&$addressbookInfo) { + private function addOwnerPrincipal(array &$addressbookInfo): void { $ownerPrincipalKey = '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal'; $displaynameKey = '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_NEXTCLOUD . '}owner-displayname'; if (isset($addressbookInfo[$ownerPrincipalKey])) { @@ -1386,10 +1339,10 @@ class CardDavBackend implements BackendInterface, SyncSupport { * * @param string $cardData the vcard raw data * @return string the uid - * @throws BadRequest if no UID is available + * @throws BadRequest if no UID is available or vcard is empty */ - private function getUID($cardData) { - if ($cardData != '') { + private function getUID(string $cardData): string { + if ($cardData !== '') { $vCard = Reader::read($cardData); if ($vCard->UID) { $uid = $vCard->UID->getValue(); diff --git a/apps/dav/lib/CardDAV/SyncService.php b/apps/dav/lib/CardDAV/SyncService.php index 169dbc79e0f..5094b7f3f5c 100644 --- a/apps/dav/lib/CardDAV/SyncService.php +++ b/apps/dav/lib/CardDAV/SyncService.php @@ -40,27 +40,13 @@ use Sabre\HTTP\ClientHttpException; use Sabre\VObject\Reader; class SyncService { - - /** @var CardDavBackend */ - private $backend; - - /** @var IUserManager */ - private $userManager; - + private CardDavBackend $backend; + private IUserManager $userManager; private LoggerInterface $logger; + private ?array $localSystemAddressBook = null; + private Converter $converter; + protected string $certPath; - /** @var array */ - private $localSystemAddressBook; - - /** @var Converter */ - private $converter; - - /** @var string */ - protected $certPath; - - /** - * SyncService constructor. - */ public function __construct(CardDavBackend $backend, IUserManager $userManager, LoggerInterface $logger, @@ -73,20 +59,11 @@ class SyncService { } /** - * @param string $url - * @param string $userName - * @param string $addressBookUrl - * @param string $sharedSecret - * @param string $syncToken - * @param int $targetBookId - * @param string $targetPrincipal - * @param array $targetProperties - * @return string * @throws \Exception */ - public function syncRemoteAddressBook($url, $userName, $addressBookUrl, $sharedSecret, $syncToken, $targetBookId, $targetPrincipal, $targetProperties) { + public function syncRemoteAddressBook(string $url, string $userName, string $addressBookUrl, string $sharedSecret, ?string $syncToken, string $targetBookHash, string $targetPrincipal, array $targetProperties): string { // 1. create addressbook - $book = $this->ensureSystemAddressBookExists($targetPrincipal, (string)$targetBookId, $targetProperties); + $book = $this->ensureSystemAddressBookExists($targetPrincipal, $targetBookHash, $targetProperties); $addressBookId = $book['id']; // 2. query changes @@ -122,28 +99,23 @@ class SyncService { } /** - * @param string $principal - * @param string $id - * @param array $properties - * @return array|null * @throws \Sabre\DAV\Exception\BadRequest */ - public function ensureSystemAddressBookExists($principal, $id, $properties) { - $book = $this->backend->getAddressBooksByUri($principal, $id); + public function ensureSystemAddressBookExists(string $principal, string $uri, array $properties): ?array { + $book = $this->backend->getAddressBooksByUri($principal, $uri); if (!is_null($book)) { return $book; } - $this->backend->createAddressBook($principal, $id, $properties); + // FIXME This might break in clustered DB setup + $this->backend->createAddressBook($principal, $uri, $properties); - return $this->backend->getAddressBooksByUri($principal, $id); + return $this->backend->getAddressBooksByUri($principal, $uri); } /** * Check if there is a valid certPath we should use - * - * @return string */ - protected function getCertPath() { + protected function getCertPath(): string { // we already have a valid certPath if ($this->certPath !== '') { @@ -159,14 +131,7 @@ class SyncService { return $this->certPath; } - /** - * @param string $url - * @param string $userName - * @param string $addressBookUrl - * @param string $sharedSecret - * @return Client - */ - protected function getClient($url, $userName, $sharedSecret) { + protected function getClient(string $url, string $userName, string $sharedSecret): Client { $settings = [ 'baseUri' => $url . '/', 'userName' => $userName, @@ -183,15 +148,7 @@ class SyncService { return $client; } - /** - * @param string $url - * @param string $userName - * @param string $addressBookUrl - * @param string $sharedSecret - * @param string $syncToken - * @return array - */ - protected function requestSyncReport($url, $userName, $addressBookUrl, $sharedSecret, $syncToken) { + protected function requestSyncReport(string $url, string $userName, string $addressBookUrl, string $sharedSecret, ?string $syncToken): array { $client = $this->getClient($url, $userName, $sharedSecret); $body = $this->buildSyncCollectionRequestBody($syncToken); @@ -203,23 +160,12 @@ class SyncService { return $this->parseMultiStatus($response['body']); } - /** - * @param string $url - * @param string $userName - * @param string $sharedSecret - * @param string $resourcePath - * @return array - */ - protected function download($url, $userName, $sharedSecret, $resourcePath) { + protected function download(string $url, string $userName, string $sharedSecret, string $resourcePath): array { $client = $this->getClient($url, $userName, $sharedSecret); return $client->request('GET', $resourcePath); } - /** - * @param string|null $syncToken - * @return string - */ - private function buildSyncCollectionRequestBody($syncToken) { + private function buildSyncCollectionRequestBody(?string $syncToken): string { $dom = new \DOMDocument('1.0', 'UTF-8'); $dom->formatOutput = true; $root = $dom->createElementNS('DAV:', 'd:sync-collection'); diff --git a/apps/dav/lib/Command/CreateCalendar.php b/apps/dav/lib/Command/CreateCalendar.php index 2bea82a345e..08f937dff9d 100644 --- a/apps/dav/lib/Command/CreateCalendar.php +++ b/apps/dav/lib/Command/CreateCalendar.php @@ -29,6 +29,7 @@ use OC\KnownUser\KnownUserService; use OCA\DAV\CalDAV\CalDavBackend; use OCA\DAV\CalDAV\Proxy\ProxyMapper; use OCA\DAV\Connector\Sabre\Principal; +use OCP\Accounts\IAccountManager; use OCP\EventDispatcher\IEventDispatcher; use OCP\IConfig; use OCP\IDBConnection; @@ -83,6 +84,7 @@ class CreateCalendar extends Command { $principalBackend = new Principal( $this->userManager, $this->groupManager, + \OC::$server->get(IAccountManager::class), \OC::$server->getShareManager(), \OC::$server->getUserSession(), \OC::$server->getAppManager(), @@ -94,7 +96,6 @@ class CreateCalendar extends Command { $random = \OC::$server->getSecureRandom(); $logger = \OC::$server->get(LoggerInterface::class); $dispatcher = \OC::$server->get(IEventDispatcher::class); - $legacyDispatcher = \OC::$server->getEventDispatcher(); $config = \OC::$server->get(IConfig::class); $name = $input->getArgument('name'); @@ -106,7 +107,6 @@ class CreateCalendar extends Command { $random, $logger, $dispatcher, - $legacyDispatcher, $config ); $caldav->createCalendar("principals/users/$user", $name, []); diff --git a/apps/dav/lib/Command/MoveCalendar.php b/apps/dav/lib/Command/MoveCalendar.php index 320fe8aeac6..9272b20b10d 100644 --- a/apps/dav/lib/Command/MoveCalendar.php +++ b/apps/dav/lib/Command/MoveCalendar.php @@ -42,41 +42,17 @@ use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; class MoveCalendar extends Command { - - /** @var IUserManager */ - private $userManager; - - /** @var IGroupManager */ - private $groupManager; - - /** @var IShareManager */ - private $shareManager; - - /** @var IConfig $config */ - private $config; - - /** @var IL10N */ - private $l10n; - - /** @var SymfonyStyle */ - private $io; - - /** @var CalDavBackend */ - private $calDav; - - /** @var LoggerInterface */ - private $logger; + private IUserManager $userManager; + private IGroupManager $groupManager; + private IShareManager $shareManager; + private IConfig $config; + private IL10N $l10n; + private ?SymfonyStyle $io = null; + private CalDavBackend $calDav; + private LoggerInterface $logger; public const URI_USERS = 'principals/users/'; - /** - * @param IUserManager $userManager - * @param IGroupManager $groupManager - * @param IShareManager $shareManager - * @param IConfig $config - * @param IL10N $l10n - * @param CalDavBackend $calDav - */ public function __construct( IUserManager $userManager, IGroupManager $groupManager, @@ -224,7 +200,7 @@ class MoveCalendar extends Command { */ if ($this->shareManager->shareWithGroupMembersOnly() === true && 'groups' === $prefix && !$this->groupManager->isInGroup($userDestination, $userOrGroup)) { if ($force) { - $this->calDav->updateShares(new Calendar($this->calDav, $calendar, $this->l10n, $this->config, $this->logger), [], ['href' => 'principal:principals/groups/' . $userOrGroup]); + $this->calDav->updateShares(new Calendar($this->calDav, $calendar, $this->l10n, $this->config, $this->logger), [], ['principal:principals/groups/' . $userOrGroup]); } else { throw new \InvalidArgumentException("User <$userDestination> is not part of the group <$userOrGroup> with whom the calendar <" . $calendar['uri'] . "> was shared. You may use -f to move the calendar while deleting this share."); } @@ -235,7 +211,7 @@ class MoveCalendar extends Command { */ if ($userOrGroup === $userDestination) { if ($force) { - $this->calDav->updateShares(new Calendar($this->calDav, $calendar, $this->l10n, $this->config, $this->logger), [], ['href' => 'principal:principals/users/' . $userOrGroup]); + $this->calDav->updateShares(new Calendar($this->calDav, $calendar, $this->l10n, $this->config, $this->logger), [], ['principal:principals/users/' . $userOrGroup]); } else { throw new \InvalidArgumentException("The calendar <" . $calendar['uri'] . "> is already shared to user <$userDestination>.You may use -f to move the calendar while deleting this share."); } diff --git a/apps/dav/lib/Connector/Sabre/ChecksumList.php b/apps/dav/lib/Connector/Sabre/ChecksumList.php index 344e6a4ab3c..44573de03c8 100644 --- a/apps/dav/lib/Connector/Sabre/ChecksumList.php +++ b/apps/dav/lib/Connector/Sabre/ChecksumList.php @@ -42,7 +42,7 @@ class ChecksumList implements XmlSerializable { } /** - * The xmlSerialize metod is called during xml writing. + * The xmlSerialize method is called during xml writing. * * Use the $writer argument to write its own xml serialization. * diff --git a/apps/dav/lib/Connector/Sabre/Directory.php b/apps/dav/lib/Connector/Sabre/Directory.php index 5280511d5be..b575a051b2a 100644 --- a/apps/dav/lib/Connector/Sabre/Directory.php +++ b/apps/dav/lib/Connector/Sabre/Directory.php @@ -66,7 +66,7 @@ class Directory extends \OCA\DAV\Connector\Sabre\Node implements \Sabre\DAV\ICol /** Cached quota info */ private ?array $quotaInfo = null; - private ?ObjectTree $tree = null; + private ?CachingTree $tree = null; /** @var array<string, array<int, FileMetadata>> */ private array $metadata = []; @@ -74,7 +74,7 @@ class Directory extends \OCA\DAV\Connector\Sabre\Node implements \Sabre\DAV\ICol /** * Sets up the node, expects a full path name */ - public function __construct(View $view, FileInfo $info, ?ObjectTree $tree = null, IShareManager $shareManager = null) { + public function __construct(View $view, FileInfo $info, ?CachingTree $tree = null, IShareManager $shareManager = null) { parent::__construct($view, $info, $shareManager); $this->tree = $tree; } diff --git a/apps/dav/lib/Connector/Sabre/ExceptionLoggerPlugin.php b/apps/dav/lib/Connector/Sabre/ExceptionLoggerPlugin.php index ea94b5c8933..ebf3e4021eb 100644 --- a/apps/dav/lib/Connector/Sabre/ExceptionLoggerPlugin.php +++ b/apps/dav/lib/Connector/Sabre/ExceptionLoggerPlugin.php @@ -29,6 +29,7 @@ namespace OCA\DAV\Connector\Sabre; use OCA\DAV\Connector\Sabre\Exception\FileLocked; use OCA\DAV\Connector\Sabre\Exception\PasswordLoginForbidden; +use OCA\DAV\Exception\ServerMaintenanceMode; use OCP\Files\StorageNotAvailableException; use Psr\Log\LoggerInterface; use Sabre\DAV\Exception\BadRequest; @@ -81,6 +82,7 @@ class ExceptionLoggerPlugin extends \Sabre\DAV\ServerPlugin { FileLocked::class => true, // An invalid range is requested RequestedRangeNotSatisfiable::class => true, + ServerMaintenanceMode::class => true, ]; private string $appName; @@ -114,17 +116,12 @@ class ExceptionLoggerPlugin extends \Sabre\DAV\ServerPlugin { */ public function logException(\Throwable $ex) { $exceptionClass = get_class($ex); - if (isset($this->nonFatalExceptions[$exceptionClass]) || - ( - $exceptionClass === ServiceUnavailable::class && - $ex->getMessage() === 'System in maintenance mode.' - ) - ) { + if (isset($this->nonFatalExceptions[$exceptionClass])) { $this->logger->debug($ex->getMessage(), [ 'app' => $this->appName, 'exception' => $ex, ]); - return; + return; } $this->logger->critical($ex->getMessage(), [ diff --git a/apps/dav/lib/Connector/Sabre/File.php b/apps/dav/lib/Connector/Sabre/File.php index ebcfdabc6b3..94632b265db 100644 --- a/apps/dav/lib/Connector/Sabre/File.php +++ b/apps/dav/lib/Connector/Sabre/File.php @@ -553,7 +553,7 @@ class File extends Node implements IFile { * @return array|bool */ public function getDirectDownload() { - if (\OCP\App::isEnabled('encryption')) { + if (\OCP\Server::get(\OCP\App\IAppManager::class)->isEnabledForUser('encryption')) { return []; } /** @var \OCP\Files\Storage $storage */ diff --git a/apps/dav/lib/Connector/Sabre/FilesPlugin.php b/apps/dav/lib/Connector/Sabre/FilesPlugin.php index b784764f8fe..e9d27d4e7f6 100644 --- a/apps/dav/lib/Connector/Sabre/FilesPlugin.php +++ b/apps/dav/lib/Connector/Sabre/FilesPlugin.php @@ -65,6 +65,7 @@ class FilesPlugin extends ServerPlugin { public const PERMISSIONS_PROPERTYNAME = '{http://owncloud.org/ns}permissions'; public const SHARE_PERMISSIONS_PROPERTYNAME = '{http://open-collaboration-services.org/ns}share-permissions'; public const OCM_SHARE_PERMISSIONS_PROPERTYNAME = '{http://open-cloud-mesh.org/ns}share-permissions'; + public const SHARE_ATTRIBUTES_PROPERTYNAME = '{http://nextcloud.org/ns}share-attributes'; public const DOWNLOADURL_PROPERTYNAME = '{http://owncloud.org/ns}downloadURL'; public const SIZE_PROPERTYNAME = '{http://owncloud.org/ns}size'; public const GETETAG_PROPERTYNAME = '{DAV:}getetag'; @@ -134,6 +135,7 @@ class FilesPlugin extends ServerPlugin { $server->protectedProperties[] = self::PERMISSIONS_PROPERTYNAME; $server->protectedProperties[] = self::SHARE_PERMISSIONS_PROPERTYNAME; $server->protectedProperties[] = self::OCM_SHARE_PERMISSIONS_PROPERTYNAME; + $server->protectedProperties[] = self::SHARE_ATTRIBUTES_PROPERTYNAME; $server->protectedProperties[] = self::SIZE_PROPERTYNAME; $server->protectedProperties[] = self::DOWNLOADURL_PROPERTYNAME; $server->protectedProperties[] = self::OWNER_ID_PROPERTYNAME; @@ -321,6 +323,10 @@ class FilesPlugin extends ServerPlugin { return json_encode($ocmPermissions); }); + $propFind->handle(self::SHARE_ATTRIBUTES_PROPERTYNAME, function () use ($node, $httpRequest) { + return json_encode($node->getShareAttributes()); + }); + $propFind->handle(self::GETETAG_PROPERTYNAME, function () use ($node): string { return $node->getETag(); }); diff --git a/apps/dav/lib/Connector/Sabre/MaintenancePlugin.php b/apps/dav/lib/Connector/Sabre/MaintenancePlugin.php index e7e3b273b98..1fc02320805 100644 --- a/apps/dav/lib/Connector/Sabre/MaintenancePlugin.php +++ b/apps/dav/lib/Connector/Sabre/MaintenancePlugin.php @@ -27,6 +27,7 @@ */ namespace OCA\DAV\Connector\Sabre; +use OCA\DAV\Exception\ServerMaintenanceMode; use OCP\IConfig; use OCP\IL10N; use OCP\Util; @@ -82,10 +83,10 @@ class MaintenancePlugin extends ServerPlugin { */ public function checkMaintenanceMode() { if ($this->config->getSystemValueBool('maintenance')) { - throw new ServiceUnavailable($this->l10n->t('System is in maintenance mode.')); + throw new ServerMaintenanceMode($this->l10n->t('System is in maintenance mode.')); } if (Util::needUpgrade()) { - throw new ServiceUnavailable($this->l10n->t('Upgrade needed')); + throw new ServerMaintenanceMode($this->l10n->t('Upgrade needed')); } return true; diff --git a/apps/dav/lib/Connector/Sabre/Node.php b/apps/dav/lib/Connector/Sabre/Node.php index e4517068f42..87f2fea394f 100644 --- a/apps/dav/lib/Connector/Sabre/Node.php +++ b/apps/dav/lib/Connector/Sabre/Node.php @@ -38,6 +38,7 @@ namespace OCA\DAV\Connector\Sabre; use OC\Files\Mount\MoveableMount; use OC\Files\Node\File; use OC\Files\Node\Folder; +use OC\Files\Storage\Wrapper\Wrapper; use OC\Files\View; use OCA\DAV\Connector\Sabre\Exception\InvalidPath; use OCP\Files\FileInfo; @@ -323,6 +324,31 @@ abstract class Node implements \Sabre\DAV\INode { } /** + * @return array + */ + public function getShareAttributes(): array { + $attributes = []; + + try { + $storage = $this->info->getStorage(); + } catch (StorageNotAvailableException $e) { + $storage = null; + } + + if ($storage && $storage->instanceOfStorage(\OCA\Files_Sharing\SharedStorage::class)) { + /** @var \OCA\Files_Sharing\SharedStorage $storage */ + $attributes = $storage->getShare()->getAttributes(); + if ($attributes === null) { + return []; + } else { + return $attributes->toArray(); + } + } + + return $attributes; + } + + /** * @param string $user * @return string */ diff --git a/apps/dav/lib/Connector/Sabre/Principal.php b/apps/dav/lib/Connector/Sabre/Principal.php index 94e3978e67d..75bee4e7b42 100644 --- a/apps/dav/lib/Connector/Sabre/Principal.php +++ b/apps/dav/lib/Connector/Sabre/Principal.php @@ -41,6 +41,9 @@ use OC\KnownUser\KnownUserService; use OCA\Circles\Exceptions\CircleNotFoundException; use OCA\DAV\CalDAV\Proxy\ProxyMapper; use OCA\DAV\Traits\PrincipalProxyTrait; +use OCP\Accounts\IAccountManager; +use OCP\Accounts\IAccountProperty; +use OCP\Accounts\PropertyDoesNotExistException; use OCP\App\IAppManager; use OCP\AppFramework\QueryException; use OCP\Constants; @@ -64,6 +67,9 @@ class Principal implements BackendInterface { /** @var IGroupManager */ private $groupManager; + /** @var IAccountManager */ + private $accountManager; + /** @var IShareManager */ private $shareManager; @@ -95,6 +101,7 @@ class Principal implements BackendInterface { public function __construct(IUserManager $userManager, IGroupManager $groupManager, + IAccountManager $accountManager, IShareManager $shareManager, IUserSession $userSession, IAppManager $appManager, @@ -105,6 +112,7 @@ class Principal implements BackendInterface { string $principalPrefix = 'principals/users/') { $this->userManager = $userManager; $this->groupManager = $groupManager; + $this->accountManager = $accountManager; $this->shareManager = $shareManager; $this->userSession = $userSession; $this->appManager = $appManager; @@ -506,6 +514,7 @@ class Principal implements BackendInterface { /** * @param IUser $user * @return array + * @throws PropertyDoesNotExistException */ protected function userToPrincipal($user) { $userId = $user->getUID(); @@ -517,11 +526,18 @@ class Principal implements BackendInterface { '{http://nextcloud.com/ns}language' => $this->languageFactory->getUserLanguage($user), ]; + $account = $this->accountManager->getAccount($user); + $alternativeEmails = array_map(fn (IAccountProperty $property) => 'mailto:' . $property->getValue(), $account->getPropertyCollection(IAccountManager::COLLECTION_EMAIL)->getProperties()); + $email = $user->getSystemEMailAddress(); if (!empty($email)) { $principal['{http://sabredav.org/ns}email-address'] = $email; } + if (!empty($alternativeEmails)) { + $principal['{DAV:}alternate-URI-set'] = $alternativeEmails; + } + return $principal; } diff --git a/apps/dav/lib/Connector/Sabre/ServerFactory.php b/apps/dav/lib/Connector/Sabre/ServerFactory.php index 8f1f710ca5e..4c57f3412e3 100644 --- a/apps/dav/lib/Connector/Sabre/ServerFactory.php +++ b/apps/dav/lib/Connector/Sabre/ServerFactory.php @@ -33,6 +33,7 @@ namespace OCA\DAV\Connector\Sabre; use OCP\Files\Folder; use OCA\DAV\AppInfo\PluginManager; +use OCA\DAV\DAV\ViewOnlyPlugin; use OCA\DAV\Files\BrowserErrorPagePlugin; use OCP\Files\Mount\IMountManager; use OCP\IConfig; @@ -158,6 +159,11 @@ class ServerFactory { $server->addPlugin(new \OCA\DAV\Connector\Sabre\QuotaPlugin($view, true)); $server->addPlugin(new \OCA\DAV\Connector\Sabre\ChecksumUpdatePlugin()); + // Allow view-only plugin for webdav requests + $server->addPlugin(new ViewOnlyPlugin( + $this->logger + )); + if ($this->userSession->isLoggedIn()) { $server->addPlugin(new \OCA\DAV\Connector\Sabre\TagsPlugin($objectTree, $this->tagManager)); $server->addPlugin(new \OCA\DAV\Connector\Sabre\SharesPlugin( diff --git a/apps/dav/lib/Connector/Sabre/ShareTypeList.php b/apps/dav/lib/Connector/Sabre/ShareTypeList.php index 6fbae0dee4a..bacbdc99a73 100644 --- a/apps/dav/lib/Connector/Sabre/ShareTypeList.php +++ b/apps/dav/lib/Connector/Sabre/ShareTypeList.php @@ -79,7 +79,7 @@ class ShareTypeList implements Element { } /** - * The xmlSerialize metod is called during xml writing. + * The xmlSerialize method is called during xml writing. * * @param Writer $writer * @return void diff --git a/apps/dav/lib/Connector/Sabre/ShareeList.php b/apps/dav/lib/Connector/Sabre/ShareeList.php index db8c011cc45..e43f552a8cc 100644 --- a/apps/dav/lib/Connector/Sabre/ShareeList.php +++ b/apps/dav/lib/Connector/Sabre/ShareeList.php @@ -45,7 +45,7 @@ class ShareeList implements XmlSerializable { } /** - * The xmlSerialize metod is called during xml writing. + * The xmlSerialize method is called during xml writing. * * @param Writer $writer * @return void diff --git a/apps/dav/lib/Connector/Sabre/TagList.php b/apps/dav/lib/Connector/Sabre/TagList.php index bbb938fb27d..86006cd3404 100644 --- a/apps/dav/lib/Connector/Sabre/TagList.php +++ b/apps/dav/lib/Connector/Sabre/TagList.php @@ -95,7 +95,7 @@ class TagList implements Element { } /** - * The xmlSerialize metod is called during xml writing. + * The xmlSerialize method is called during xml writing. * * Use the $writer argument to write its own xml serialization. * diff --git a/apps/dav/lib/Controller/DirectController.php b/apps/dav/lib/Controller/DirectController.php index 955400998cf..f9c83488935 100644 --- a/apps/dav/lib/Controller/DirectController.php +++ b/apps/dav/lib/Controller/DirectController.php @@ -31,8 +31,12 @@ use OCA\DAV\Db\DirectMapper; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\OCS\OCSBadRequestException; use OCP\AppFramework\OCS\OCSNotFoundException; +use OCP\AppFramework\OCS\OCSForbiddenException; use OCP\AppFramework\OCSController; use OCP\AppFramework\Utility\ITimeFactory; +use OCP\EventDispatcher\GenericEvent; +use OCP\EventDispatcher\IEventDispatcher; +use OCP\Files\Events\BeforeDirectFileDownloadEvent; use OCP\Files\File; use OCP\Files\IRootFolder; use OCP\IRequest; @@ -59,6 +63,8 @@ class DirectController extends OCSController { /** @var IURLGenerator */ private $urlGenerator; + /** @var IEventDispatcher */ + private $eventDispatcher; public function __construct(string $appName, IRequest $request, @@ -67,7 +73,8 @@ class DirectController extends OCSController { DirectMapper $mapper, ISecureRandom $random, ITimeFactory $timeFactory, - IURLGenerator $urlGenerator) { + IURLGenerator $urlGenerator, + IEventDispatcher $eventDispatcher) { parent::__construct($appName, $request); $this->rootFolder = $rootFolder; @@ -76,6 +83,7 @@ class DirectController extends OCSController { $this->random = $random; $this->timeFactory = $timeFactory; $this->urlGenerator = $urlGenerator; + $this->eventDispatcher = $eventDispatcher; } /** @@ -99,6 +107,13 @@ class DirectController extends OCSController { throw new OCSBadRequestException('Direct download only works for files'); } + $event = new BeforeDirectFileDownloadEvent($userFolder->getRelativePath($file->getPath())); + $this->eventDispatcher->dispatchTyped($event); + + if ($event->isSuccessful() === false) { + throw new OCSForbiddenException('Permission denied to download file'); + } + //TODO: at some point we should use the directdownlaod function of storages $direct = new Direct(); $direct->setUserId($this->userId); diff --git a/apps/dav/lib/DAV/CustomPropertiesBackend.php b/apps/dav/lib/DAV/CustomPropertiesBackend.php index acee65cd00d..0110990a408 100644 --- a/apps/dav/lib/DAV/CustomPropertiesBackend.php +++ b/apps/dav/lib/DAV/CustomPropertiesBackend.php @@ -24,13 +24,15 @@ */ namespace OCA\DAV\DAV; -use OCA\DAV\Connector\Sabre\Node; +use Exception; +use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\IDBConnection; use OCP\IUser; use Sabre\DAV\PropertyStorage\Backend\BackendInterface; use Sabre\DAV\PropFind; use Sabre\DAV\PropPatch; use Sabre\DAV\Tree; +use Sabre\DAV\Xml\Property\Complex; use function array_intersect; class CustomPropertiesBackend implements BackendInterface { @@ -39,6 +41,21 @@ class CustomPropertiesBackend implements BackendInterface { private const TABLE_NAME = 'properties'; /** + * Value is stored as string. + */ + public const PROPERTY_TYPE_STRING = 1; + + /** + * Value is stored as XML fragment. + */ + public const PROPERTY_TYPE_XML = 2; + + /** + * Value is stored as a property object. + */ + public const PROPERTY_TYPE_OBJECT = 3; + + /** * Ignored properties * * @var string[] @@ -239,7 +256,7 @@ class CustomPropertiesBackend implements BackendInterface { $result = $qb->executeQuery(); $props = []; while ($row = $result->fetch()) { - $props[$row['propertyname']] = $row['propertyvalue']; + $props[$row['propertyname']] = $this->decodeValueFromDatabase($row['propertyvalue'], $row['valuetype']); } $result->closeCursor(); return $props; @@ -282,7 +299,7 @@ class CustomPropertiesBackend implements BackendInterface { $props = []; while ($row = $result->fetch()) { - $props[$row['propertyname']] = $row['propertyvalue']; + $props[$row['propertyname']] = $this->decodeValueFromDatabase($row['propertyvalue'], $row['valuetype']); } $result->closeCursor(); @@ -292,68 +309,54 @@ class CustomPropertiesBackend implements BackendInterface { } /** - * Update properties - * - * @param string $path path for which to update properties - * @param array $properties array of properties to update - * - * @return bool + * @throws Exception */ - private function updateProperties(string $path, array $properties) { - $deleteStatement = 'DELETE FROM `*PREFIX*properties`' . - ' WHERE `userid` = ? AND `propertypath` = ? AND `propertyname` = ?'; - - $insertStatement = 'INSERT INTO `*PREFIX*properties`' . - ' (`userid`,`propertypath`,`propertyname`,`propertyvalue`) VALUES(?,?,?,?)'; - - $updateStatement = 'UPDATE `*PREFIX*properties` SET `propertyvalue` = ?' . - ' WHERE `userid` = ? AND `propertypath` = ? AND `propertyname` = ?'; - + private function updateProperties(string $path, array $properties): bool { // TODO: use "insert or update" strategy ? $existing = $this->getUserProperties($path, []); - $this->connection->beginTransaction(); - foreach ($properties as $propertyName => $propertyValue) { - // If it was null, we need to delete the property - if (is_null($propertyValue)) { - if (array_key_exists($propertyName, $existing)) { - $this->connection->executeUpdate($deleteStatement, - [ - $this->user->getUID(), - $this->formatPath($path), - $propertyName, - ] - ); - } - } else { - if ($propertyValue instanceOf \Sabre\DAV\Xml\Property\Complex) { - $propertyValue = $propertyValue->getXml(); - } elseif (!is_string($propertyValue)) { - $propertyValue = (string)$propertyValue; - } - if (!array_key_exists($propertyName, $existing)) { - $this->connection->executeUpdate($insertStatement, - [ - $this->user->getUID(), - $this->formatPath($path), - $propertyName, - $propertyValue, - ] - ); + try { + $this->connection->beginTransaction(); + foreach ($properties as $propertyName => $propertyValue) { + // common parameters for all queries + $dbParameters = [ + 'userid' => $this->user->getUID(), + 'propertyPath' => $this->formatPath($path), + 'propertyName' => $propertyName + ]; + + // If it was null, we need to delete the property + if (is_null($propertyValue)) { + if (array_key_exists($propertyName, $existing)) { + $deleteQuery = $deleteQuery ?? $this->createDeleteQuery(); + $deleteQuery + ->setParameters($dbParameters) + ->executeStatement(); + } } else { - $this->connection->executeUpdate($updateStatement, - [ - $propertyValue, - $this->user->getUID(), - $this->formatPath($path), - $propertyName, - ] - ); + [$value, $valueType] = $this->encodeValueForDatabase($propertyValue); + $dbParameters['propertyValue'] = $value; + $dbParameters['valueType'] = $valueType; + + if (!array_key_exists($propertyName, $existing)) { + $insertQuery = $insertQuery ?? $this->createInsertQuery(); + $insertQuery + ->setParameters($dbParameters) + ->executeStatement(); + } else { + $updateQuery = $updateQuery ?? $this->createUpdateQuery(); + $updateQuery + ->setParameters($dbParameters) + ->executeStatement(); + } } } - } - $this->connection->commit(); - unset($this->userCache[$path]); + $this->connection->commit(); + unset($this->userCache[$path]); + } catch (Exception $e) { + $this->connection->rollBack(); + throw $e; + } return true; } @@ -367,8 +370,73 @@ class CustomPropertiesBackend implements BackendInterface { private function formatPath(string $path): string { if (strlen($path) > 250) { return sha1($path); + } + + return $path; + } + + /** + * @param mixed $value + * @return array + */ + private function encodeValueForDatabase($value): array { + if (is_scalar($value)) { + $valueType = self::PROPERTY_TYPE_STRING; + } elseif ($value instanceof Complex) { + $valueType = self::PROPERTY_TYPE_XML; + $value = $value->getXml(); } else { - return $path; + $valueType = self::PROPERTY_TYPE_OBJECT; + $value = serialize($value); + } + return [$value, $valueType]; + } + + /** + * @return mixed|Complex|string + */ + private function decodeValueFromDatabase(string $value, int $valueType) { + switch ($valueType) { + case self::PROPERTY_TYPE_XML: + return new Complex($value); + case self::PROPERTY_TYPE_OBJECT: + return unserialize($value); + case self::PROPERTY_TYPE_STRING: + default: + return $value; } } + + private function createDeleteQuery(): IQueryBuilder { + $deleteQuery = $this->connection->getQueryBuilder(); + $deleteQuery->delete('properties') + ->where($deleteQuery->expr()->eq('userid', $deleteQuery->createParameter('userid'))) + ->andWhere($deleteQuery->expr()->eq('propertypath', $deleteQuery->createParameter('propertyPath'))) + ->andWhere($deleteQuery->expr()->eq('propertyname', $deleteQuery->createParameter('propertyName'))); + return $deleteQuery; + } + + private function createInsertQuery(): IQueryBuilder { + $insertQuery = $this->connection->getQueryBuilder(); + $insertQuery->insert('properties') + ->values([ + 'userid' => $insertQuery->createParameter('userid'), + 'propertypath' => $insertQuery->createParameter('propertyPath'), + 'propertyname' => $insertQuery->createParameter('propertyName'), + 'propertyvalue' => $insertQuery->createParameter('propertyValue'), + 'valuetype' => $insertQuery->createParameter('valueType'), + ]); + return $insertQuery; + } + + private function createUpdateQuery(): IQueryBuilder { + $updateQuery = $this->connection->getQueryBuilder(); + $updateQuery->update('properties') + ->set('propertyvalue', $updateQuery->createParameter('propertyValue')) + ->set('valuetype', $updateQuery->createParameter('valueType')) + ->where($updateQuery->expr()->eq('userid', $updateQuery->createParameter('userid'))) + ->andWhere($updateQuery->expr()->eq('propertypath', $updateQuery->createParameter('propertyPath'))) + ->andWhere($updateQuery->expr()->eq('propertyname', $updateQuery->createParameter('propertyName'))); + return $updateQuery; + } } diff --git a/apps/dav/lib/DAV/Sharing/Backend.php b/apps/dav/lib/DAV/Sharing/Backend.php index 0f675ea4c15..90d2c7ebf82 100644 --- a/apps/dav/lib/DAV/Sharing/Backend.php +++ b/apps/dav/lib/DAV/Sharing/Backend.php @@ -32,32 +32,20 @@ use OCA\DAV\Connector\Sabre\Principal; use OCP\IDBConnection; use OCP\IGroupManager; use OCP\IUserManager; +use OCP\DB\QueryBuilder\IQueryBuilder; class Backend { - - /** @var IDBConnection */ - private $db; - /** @var IUserManager */ - private $userManager; - /** @var IGroupManager */ - private $groupManager; - /** @var Principal */ - private $principalBackend; - /** @var string */ - private $resourceType; + private IDBConnection $db; + private IUserManager $userManager; + private IGroupManager $groupManager; + private Principal $principalBackend; + private string $resourceType; public const ACCESS_OWNER = 1; public const ACCESS_READ_WRITE = 2; public const ACCESS_READ = 3; - /** - * @param IDBConnection $db - * @param IUserManager $userManager - * @param IGroupManager $groupManager - * @param Principal $principalBackend - * @param string $resourceType - */ - public function __construct(IDBConnection $db, IUserManager $userManager, IGroupManager $groupManager, Principal $principalBackend, $resourceType) { + public function __construct(IDBConnection $db, IUserManager $userManager, IGroupManager $groupManager, Principal $principalBackend, string $resourceType) { $this->db = $db; $this->userManager = $userManager; $this->groupManager = $groupManager; @@ -66,11 +54,10 @@ class Backend { } /** - * @param IShareable $shareable - * @param string[] $add - * @param string[] $remove + * @param list<array{href: string, commonName: string, readOnly: bool}> $add + * @param list<string> $remove */ - public function updateShares(IShareable $shareable, array $add, array $remove) { + public function updateShares(IShareable $shareable, array $add, array $remove): void { foreach ($add as $element) { $principal = $this->principalBackend->findByUri($element['href'], ''); if ($principal !== '') { @@ -86,10 +73,9 @@ class Backend { } /** - * @param IShareable $shareable - * @param string $element + * @param array{href: string, commonName: string, readOnly: bool} $element */ - private function shareWith($shareable, $element) { + private function shareWith(IShareable $shareable, array $element): void { $user = $element['href']; $parts = explode(':', $user, 2); if ($parts[0] !== 'principal') { @@ -129,33 +115,26 @@ class Backend { 'access' => $query->createNamedParameter($access), 'resourceid' => $query->createNamedParameter($shareable->getResourceId()) ]); - $query->execute(); + $query->executeStatement(); } - /** - * @param $resourceId - */ - public function deleteAllShares($resourceId) { + public function deleteAllShares(int $resourceId): void { $query = $this->db->getQueryBuilder(); $query->delete('dav_shares') ->where($query->expr()->eq('resourceid', $query->createNamedParameter($resourceId))) ->andWhere($query->expr()->eq('type', $query->createNamedParameter($this->resourceType))) - ->execute(); + ->executeStatement(); } - public function deleteAllSharesByUser($principaluri) { + public function deleteAllSharesByUser(string $principaluri): void { $query = $this->db->getQueryBuilder(); $query->delete('dav_shares') ->where($query->expr()->eq('principaluri', $query->createNamedParameter($principaluri))) ->andWhere($query->expr()->eq('type', $query->createNamedParameter($this->resourceType))) - ->execute(); + ->executeStatement(); } - /** - * @param IShareable $shareable - * @param string $element - */ - private function unshare($shareable, $element) { + private function unshare(IShareable $shareable, string $element): void { $parts = explode(':', $element, 2); if ($parts[0] !== 'principal') { return; @@ -172,7 +151,7 @@ class Backend { ->andWhere($query->expr()->eq('type', $query->createNamedParameter($this->resourceType))) ->andWhere($query->expr()->eq('principaluri', $query->createNamedParameter($parts[1]))) ; - $query->execute(); + $query->executeStatement(); } /** @@ -183,29 +162,28 @@ class Backend { * * commonName - Optional, for example a first + last name * * status - See the Sabre\CalDAV\SharingPlugin::STATUS_ constants. * * readOnly - boolean - * * summary - Optional, a description for the share * * @param int $resourceId - * @return array + * @return list<array{href: string, commonName: string, status: int, readOnly: bool, '{http://owncloud.org/ns}principal': string, '{http://owncloud.org/ns}group-share': bool}> */ - public function getShares($resourceId) { + public function getShares(int $resourceId): array { $query = $this->db->getQueryBuilder(); $result = $query->select(['principaluri', 'access']) ->from('dav_shares') - ->where($query->expr()->eq('resourceid', $query->createNamedParameter($resourceId))) + ->where($query->expr()->eq('resourceid', $query->createNamedParameter($resourceId, IQueryBuilder::PARAM_INT))) ->andWhere($query->expr()->eq('type', $query->createNamedParameter($this->resourceType))) ->groupBy(['principaluri', 'access']) - ->execute(); + ->executeQuery(); $shares = []; while ($row = $result->fetch()) { $p = $this->principalBackend->getPrincipalByPath($row['principaluri']); $shares[] = [ - 'href' => "principal:${row['principaluri']}", - 'commonName' => isset($p['{DAV:}displayname']) ? $p['{DAV:}displayname'] : '', + 'href' => "principal:{$row['principaluri']}", + 'commonName' => isset($p['{DAV:}displayname']) ? (string)$p['{DAV:}displayname'] : '', 'status' => 1, 'readOnly' => (int) $row['access'] === self::ACCESS_READ, - '{http://owncloud.org/ns}principal' => $row['principaluri'], + '{http://owncloud.org/ns}principal' => (string)$row['principaluri'], '{http://owncloud.org/ns}group-share' => is_null($p) ]; } @@ -217,10 +195,10 @@ class Backend { * For shared resources the sharee is set in the ACL of the resource * * @param int $resourceId - * @param array $acl - * @return array + * @param list<array{privilege: string, principal: string, protected: bool}> $acl + * @return list<array{privilege: string, principal: string, protected: bool}> */ - public function applyShareAcl($resourceId, $acl) { + public function applyShareAcl(int $resourceId, array $acl): array { $shares = $this->getShares($resourceId); foreach ($shares as $share) { $acl[] = [ diff --git a/apps/dav/lib/DAV/Sharing/IShareable.php b/apps/dav/lib/DAV/Sharing/IShareable.php index 3833e026696..759981af078 100644 --- a/apps/dav/lib/DAV/Sharing/IShareable.php +++ b/apps/dav/lib/DAV/Sharing/IShareable.php @@ -40,16 +40,14 @@ interface IShareable extends INode { * Every element in the add array has the following properties: * * href - A url. Usually a mailto: address * * commonName - Usually a first and last name, or false - * * summary - A description of the share, can also be false * * readOnly - A boolean value * * Every element in the remove array is just the address string. * - * @param array $add - * @param array $remove - * @return void + * @param list<array{href: string, commonName: string, readOnly: bool}> $add + * @param list<string> $remove */ - public function updateShares(array $add, array $remove); + public function updateShares(array $add, array $remove): void; /** * Returns the list of people whom this resource is shared with. @@ -59,19 +57,15 @@ interface IShareable extends INode { * * commonName - Optional, for example a first + last name * * status - See the Sabre\CalDAV\SharingPlugin::STATUS_ constants. * * readOnly - boolean - * * summary - Optional, a description for the share * - * @return array + * @return list<array{href: string, commonName: string, status: int, readOnly: bool, '{http://owncloud.org/ns}principal': string, '{http://owncloud.org/ns}group-share': bool}> */ - public function getShares(); + public function getShares(): array; - /** - * @return int - */ - public function getResourceId(); + public function getResourceId(): int; /** - * @return string + * @return ?string */ public function getOwner(); } diff --git a/apps/dav/lib/DAV/Sharing/Xml/Invite.php b/apps/dav/lib/DAV/Sharing/Xml/Invite.php index 161a8dd0ebf..e6219f2bbfe 100644 --- a/apps/dav/lib/DAV/Sharing/Xml/Invite.php +++ b/apps/dav/lib/DAV/Sharing/Xml/Invite.php @@ -100,7 +100,7 @@ class Invite implements XmlSerializable { } /** - * The xmlSerialize metod is called during xml writing. + * The xmlSerialize method is called during xml writing. * * Use the $writer argument to write its own xml serialization. * diff --git a/apps/dav/lib/DAV/SystemPrincipalBackend.php b/apps/dav/lib/DAV/SystemPrincipalBackend.php index e5b9a20037f..07431feb6dd 100644 --- a/apps/dav/lib/DAV/SystemPrincipalBackend.php +++ b/apps/dav/lib/DAV/SystemPrincipalBackend.php @@ -87,7 +87,7 @@ class SystemPrincipalBackend extends AbstractBackend { } /** - * Updates one ore more webdav properties on a principal. + * Updates one or more webdav properties on a principal. * * The list of mutations is stored in a Sabre\DAV\PropPatch object. * To do the actual updates, you must tell this object which properties diff --git a/apps/dav/lib/DAV/ViewOnlyPlugin.php b/apps/dav/lib/DAV/ViewOnlyPlugin.php new file mode 100644 index 00000000000..1504969b5b4 --- /dev/null +++ b/apps/dav/lib/DAV/ViewOnlyPlugin.php @@ -0,0 +1,108 @@ +<?php +/** + * @author Piotr Mrowczynski piotr@owncloud.com + * + * @copyright Copyright (c) 2019, ownCloud GmbH + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + +namespace OCA\DAV\DAV; + +use OCA\DAV\Connector\Sabre\Exception\Forbidden; +use OCA\DAV\Connector\Sabre\File as DavFile; +use OCA\DAV\Meta\MetaFile; +use OCP\Files\FileInfo; +use OCP\Files\NotFoundException; +use Psr\Log\LoggerInterface; +use Sabre\DAV\Server; +use Sabre\DAV\ServerPlugin; +use Sabre\HTTP\RequestInterface; +use Sabre\DAV\Exception\NotFound; + +/** + * Sabre plugin for restricting file share receiver download: + */ +class ViewOnlyPlugin extends ServerPlugin { + + private ?Server $server = null; + private LoggerInterface $logger; + + public function __construct(LoggerInterface $logger) { + $this->logger = $logger; + } + + /** + * This initializes the plugin. + * + * This function is called by Sabre\DAV\Server, after + * addPlugin is called. + * + * This method should set up the required event subscriptions. + */ + public function initialize(Server $server): void { + $this->server = $server; + //priority 90 to make sure the plugin is called before + //Sabre\DAV\CorePlugin::httpGet + $this->server->on('method:GET', [$this, 'checkViewOnly'], 90); + } + + /** + * Disallow download via DAV Api in case file being received share + * and having special permission + * + * @throws Forbidden + * @throws NotFoundException + */ + public function checkViewOnly(RequestInterface $request): bool { + $path = $request->getPath(); + + try { + assert($this->server !== null); + $davNode = $this->server->tree->getNodeForPath($path); + if (!($davNode instanceof DavFile)) { + return true; + } + // Restrict view-only to nodes which are shared + $node = $davNode->getNode(); + + $storage = $node->getStorage(); + + if (!$storage->instanceOfStorage(\OCA\Files_Sharing\SharedStorage::class)) { + return true; + } + // Extract extra permissions + /** @var \OCA\Files_Sharing\SharedStorage $storage */ + $share = $storage->getShare(); + + $attributes = $share->getAttributes(); + if ($attributes === null) { + return true; + } + + // Check if read-only and on whether permission can download is both set and disabled. + $canDownload = $attributes->getAttribute('permissions', 'download'); + if ($canDownload !== null && !$canDownload) { + throw new Forbidden('Access to this resource has been denied because it is in view-only mode.'); + } + } catch (NotFound $e) { + $this->logger->warning($e->getMessage(), [ + 'exception' => $e, + ]); + } + + return true; + } +} diff --git a/apps/dav/lib/Direct/DirectHome.php b/apps/dav/lib/Direct/DirectHome.php index a385cd8f39d..5453a61ed46 100644 --- a/apps/dav/lib/Direct/DirectHome.php +++ b/apps/dav/lib/Direct/DirectHome.php @@ -91,7 +91,7 @@ class DirectHome implements ICollection { return new DirectFile($direct, $this->rootFolder, $this->eventDispatcher); } catch (DoesNotExistException $e) { - // Since the token space is so huge only throttle on non exsisting token + // Since the token space is so huge only throttle on non-existing token $this->throttler->registerAttempt('directlink', $this->request->getRemoteAddress()); $this->throttler->sleepDelay($this->request->getRemoteAddress(), 'directlink'); diff --git a/apps/dav/lib/Events/CalendarObjectMovedEvent.php b/apps/dav/lib/Events/CalendarObjectMovedEvent.php new file mode 100644 index 00000000000..0143dad9a96 --- /dev/null +++ b/apps/dav/lib/Events/CalendarObjectMovedEvent.php @@ -0,0 +1,120 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2020, Georg Ehrke + * + * @author Georg Ehrke <oc.list@georgehrke.com> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +namespace OCA\DAV\Events; + +use OCP\EventDispatcher\Event; + +/** + * Class CalendarObjectMovedEvent + * + * @package OCA\DAV\Events + * @since 25.0.0 + */ +class CalendarObjectMovedEvent extends Event { + private int $sourceCalendarId; + private array $sourceCalendarData; + private int $targetCalendarId; + private array $targetCalendarData; + private array $sourceShares; + private array $targetShares; + private array $objectData; + + /** + * @since 25.0.0 + */ + public function __construct(int $sourceCalendarId, + array $sourceCalendarData, + int $targetCalendarId, + array $targetCalendarData, + array $sourceShares, + array $targetShares, + array $objectData) { + parent::__construct(); + $this->sourceCalendarId = $sourceCalendarId; + $this->sourceCalendarData = $sourceCalendarData; + $this->targetCalendarId = $targetCalendarId; + $this->targetCalendarData = $targetCalendarData; + $this->sourceShares = $sourceShares; + $this->targetShares = $targetShares; + $this->objectData = $objectData; + } + + /** + * @return int + * @since 25.0.0 + */ + public function getSourceCalendarId(): int { + return $this->sourceCalendarId; + } + + /** + * @return array + * @since 25.0.0 + */ + public function getSourceCalendarData(): array { + return $this->sourceCalendarData; + } + + /** + * @return int + * @since 25.0.0 + */ + public function getTargetCalendarId(): int { + return $this->targetCalendarId; + } + + /** + * @return array + * @since 25.0.0 + */ + public function getTargetCalendarData(): array { + return $this->targetCalendarData; + } + + /** + * @return array + * @since 25.0.0 + */ + public function getSourceShares(): array { + return $this->sourceShares; + } + + /** + * @return array + * @since 25.0.0 + */ + public function getTargetShares(): array { + return $this->targetShares; + } + + /** + * @return array + * @since 25.0.0 + */ + public function getObjectData(): array { + return $this->objectData; + } +} diff --git a/apps/dav/lib/Events/CalendarPublishedEvent.php b/apps/dav/lib/Events/CalendarPublishedEvent.php index 7b3b95f2f77..a95e9f294c1 100644 --- a/apps/dav/lib/Events/CalendarPublishedEvent.php +++ b/apps/dav/lib/Events/CalendarPublishedEvent.php @@ -6,6 +6,7 @@ declare(strict_types=1); * @copyright Copyright (c) 2020, Georg Ehrke * * @author Georg Ehrke <oc.list@georgehrke.com> + * @author Thomas Citharel <nextcloud@tcit.fr> * * @license GNU AGPL version 3 or any later version * @@ -34,15 +35,9 @@ use OCP\EventDispatcher\Event; * @since 20.0.0 */ class CalendarPublishedEvent extends Event { - - /** @var int */ - private $calendarId; - - /** @var array */ - private $calendarData; - - /** @var string */ - private $publicUri; + private int $calendarId; + private array $calendarData; + private string $publicUri; /** * CalendarPublishedEvent constructor. diff --git a/apps/dav/lib/Events/CalendarShareUpdatedEvent.php b/apps/dav/lib/Events/CalendarShareUpdatedEvent.php index a9011bc0273..d5a568d149b 100644 --- a/apps/dav/lib/Events/CalendarShareUpdatedEvent.php +++ b/apps/dav/lib/Events/CalendarShareUpdatedEvent.php @@ -26,6 +26,8 @@ declare(strict_types=1); namespace OCA\DAV\Events; use OCP\EventDispatcher\Event; +use Sabre\CalDAV\Xml\Property\ScheduleCalendarTransp; +use Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet; /** * Class CalendarShareUpdatedEvent @@ -34,30 +36,28 @@ use OCP\EventDispatcher\Event; * @since 20.0.0 */ class CalendarShareUpdatedEvent extends Event { + private int $calendarId; - /** @var int */ - private $calendarId; + /** @var array{id: int, uri: string, '{http://calendarserver.org/ns/}getctag': string, '{http://sabredav.org/ns}sync-token': int, '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set': SupportedCalendarComponentSet, '{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp': ScheduleCalendarTransp } */ + private array $calendarData; - /** @var array */ - private $calendarData; + /** @var list<array{href: string, commonName: string, status: int, readOnly: bool, '{http://owncloud.org/ns}principal': string, '{http://owncloud.org/ns}group-share': bool}> */ + private array $oldShares; - /** @var array */ - private $oldShares; + /** @var list<array{href: string, commonName: string, readOnly: bool}> */ + private array $added; - /** @var array */ - private $added; - - /** @var array */ - private $removed; + /** @var list<string> */ + private array $removed; /** * CalendarShareUpdatedEvent constructor. * * @param int $calendarId - * @param array $calendarData - * @param array $oldShares - * @param array $added - * @param array $removed + * @param array{id: int, uri: string, '{http://calendarserver.org/ns/}getctag': string, '{http://sabredav.org/ns}sync-token': int, '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set': SupportedCalendarComponentSet, '{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp': ScheduleCalendarTransp } $calendarData + * @param list<array{href: string, commonName: string, status: int, readOnly: bool, '{http://owncloud.org/ns}principal': string, '{http://owncloud.org/ns}group-share': bool}> $oldShares + * @param list<array{href: string, commonName: string, readOnly: bool}> $added + * @param list<string> $removed * @since 20.0.0 */ public function __construct(int $calendarId, @@ -74,7 +74,6 @@ class CalendarShareUpdatedEvent extends Event { } /** - * @return int * @since 20.0.0 */ public function getCalendarId(): int { @@ -82,7 +81,7 @@ class CalendarShareUpdatedEvent extends Event { } /** - * @return array + * @return array{id: int, uri: string, '{http://calendarserver.org/ns/}getctag': string, '{http://sabredav.org/ns}sync-token': int, '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set': SupportedCalendarComponentSet, '{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp': ScheduleCalendarTransp } * @since 20.0.0 */ public function getCalendarData(): array { @@ -90,7 +89,7 @@ class CalendarShareUpdatedEvent extends Event { } /** - * @return array + * @return list<array{href: string, commonName: string, status: int, readOnly: bool, '{http://owncloud.org/ns}principal': string, '{http://owncloud.org/ns}group-share': bool}> * @since 20.0.0 */ public function getOldShares(): array { @@ -98,7 +97,7 @@ class CalendarShareUpdatedEvent extends Event { } /** - * @return array + * @return list<array{href: string, commonName: string, readOnly: bool}> * @since 20.0.0 */ public function getAdded(): array { @@ -106,7 +105,7 @@ class CalendarShareUpdatedEvent extends Event { } /** - * @return array + * @return list<string> * @since 20.0.0 */ public function getRemoved(): array { diff --git a/apps/dav/lib/Events/CalendarUnpublishedEvent.php b/apps/dav/lib/Events/CalendarUnpublishedEvent.php index 0cea53c6f0d..b2536fc7aef 100644 --- a/apps/dav/lib/Events/CalendarUnpublishedEvent.php +++ b/apps/dav/lib/Events/CalendarUnpublishedEvent.php @@ -6,6 +6,7 @@ declare(strict_types=1); * @copyright Copyright (c) 2020, Georg Ehrke * * @author Georg Ehrke <oc.list@georgehrke.com> + * @author Thomas Citharel <nextcloud@tcit.fr> * * @license GNU AGPL version 3 or any later version * @@ -34,12 +35,8 @@ use OCP\EventDispatcher\Event; * @since 20.0.0 */ class CalendarUnpublishedEvent extends Event { - - /** @var int */ - private $calendarId; - - /** @var array */ - private $calendarData; + private int $calendarId; + private array $calendarData; /** * CalendarUnpublishedEvent constructor. diff --git a/apps/dav/lib/Exception/ServerMaintenanceMode.php b/apps/dav/lib/Exception/ServerMaintenanceMode.php new file mode 100644 index 00000000000..9dad9f2d4d1 --- /dev/null +++ b/apps/dav/lib/Exception/ServerMaintenanceMode.php @@ -0,0 +1,31 @@ +<?php + +declare(strict_types=1); +/** + * @copyright Copyright (c) 2022 Joas Schilling <coding@schilljs.com> + * + * @author Joas Schilling <coding@schilljs.com> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +namespace OCA\DAV\Exception; + +use Sabre\DAV\Exception\ServiceUnavailable; + +class ServerMaintenanceMode extends ServiceUnavailable { + +} diff --git a/apps/dav/lib/Listener/ActivityUpdaterListener.php b/apps/dav/lib/Listener/ActivityUpdaterListener.php index 371912ff035..ea3ec49c14d 100644 --- a/apps/dav/lib/Listener/ActivityUpdaterListener.php +++ b/apps/dav/lib/Listener/ActivityUpdaterListener.php @@ -32,6 +32,7 @@ use OCA\DAV\Events\CalendarDeletedEvent; use OCA\DAV\Events\CalendarMovedToTrashEvent; use OCA\DAV\Events\CalendarObjectCreatedEvent; use OCA\DAV\Events\CalendarObjectDeletedEvent; +use OCA\DAV\Events\CalendarObjectMovedEvent; use OCA\DAV\Events\CalendarObjectMovedToTrashEvent; use OCA\DAV\Events\CalendarObjectRestoredEvent; use OCA\DAV\Events\CalendarObjectUpdatedEvent; @@ -173,7 +174,26 @@ class ActivityUpdaterListener implements IEventListener { ); $this->logger->debug( - sprintf('Activity generated for deleted calendar object %d', $event->getCalendarId()) + sprintf('Activity generated for updated calendar object in calendar %d', $event->getCalendarId()) + ); + } catch (Throwable $e) { + // Any error with activities shouldn't abort the calendar deletion, so we just log it + $this->logger->error('Error generating activity for a deleted calendar object: ' . $e->getMessage(), [ + 'exception' => $e, + ]); + } + } elseif ($event instanceof CalendarObjectMovedEvent) { + try { + $this->activityBackend->onMovedCalendarObject( + $event->getSourceCalendarData(), + $event->getTargetCalendarData(), + $event->getSourceShares(), + $event->getTargetShares(), + $event->getObjectData() + ); + + $this->logger->debug( + sprintf('Activity generated for moved calendar object from calendar %d to calendar %d', $event->getSourceCalendarId(), $event->getTargetCalendarId()) ); } catch (Throwable $e) { // Any error with activities shouldn't abort the calendar deletion, so we just log it diff --git a/apps/dav/lib/Listener/BirthdayListener.php b/apps/dav/lib/Listener/BirthdayListener.php new file mode 100644 index 00000000000..43ad782fa9e --- /dev/null +++ b/apps/dav/lib/Listener/BirthdayListener.php @@ -0,0 +1,54 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright 2022 Thomas Citharel <nextcloud@tcit.fr> + * + * @author Thomas Citharel <nextcloud@tcit.fr> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +namespace OCA\DAV\Listener; + +use OCA\DAV\CalDAV\BirthdayService; +use OCA\DAV\Events\CardCreatedEvent; +use OCA\DAV\Events\CardDeletedEvent; +use OCA\DAV\Events\CardUpdatedEvent; +use OCP\EventDispatcher\Event; +use OCP\EventDispatcher\IEventListener; + +class BirthdayListener implements IEventListener { + private BirthdayService $birthdayService; + + public function __construct(BirthdayService $birthdayService) { + $this->birthdayService = $birthdayService; + } + + public function handle(Event $event): void { + if ($event instanceof CardCreatedEvent || $event instanceof CardUpdatedEvent) { + $cardData = $event->getCardData(); + + $this->birthdayService->onCardChanged($event->getAddressBookId(), $cardData['uri'], $cardData['carddata']); + } + + if ($event instanceof CardDeletedEvent) { + $cardData = $event->getCardData(); + $this->birthdayService->onCardDeleted($event->getAddressBookId(), $cardData['uri']); + } + } +} diff --git a/apps/dav/lib/Listener/CalendarPublicationListener.php b/apps/dav/lib/Listener/CalendarPublicationListener.php new file mode 100644 index 00000000000..1453694d6fb --- /dev/null +++ b/apps/dav/lib/Listener/CalendarPublicationListener.php @@ -0,0 +1,65 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright 2022 Thomas Citharel <nextcloud@tcit.fr> + * + * @author Thomas Citharel <nextcloud@tcit.fr> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +namespace OCA\DAV\Listener; + +use OCA\DAV\CalDAV\Activity\Backend; +use OCA\DAV\Events\CalendarPublishedEvent; +use OCA\DAV\Events\CalendarUnpublishedEvent; +use OCP\EventDispatcher\Event; +use OCP\EventDispatcher\IEventListener; +use Psr\Log\LoggerInterface; + +class CalendarPublicationListener implements IEventListener { + private Backend $activityBackend; + private LoggerInterface $logger; + + public function __construct(Backend $activityBackend, + LoggerInterface $logger) { + $this->activityBackend = $activityBackend; + $this->logger = $logger; + } + + /** + * In case the user has set their default calendar to the deleted one + */ + public function handle(Event $event): void { + if ($event instanceof CalendarPublishedEvent) { + $this->logger->debug('Creating activity for Calendar being published'); + + $this->activityBackend->onCalendarPublication( + $event->getCalendarData(), + true + ); + } elseif ($event instanceof CalendarUnpublishedEvent) { + $this->logger->debug('Creating activity for Calendar being unpublished'); + + $this->activityBackend->onCalendarPublication( + $event->getCalendarData(), + false + ); + } + } +} diff --git a/apps/dav/lib/Listener/CalendarShareUpdateListener.php b/apps/dav/lib/Listener/CalendarShareUpdateListener.php new file mode 100644 index 00000000000..88865759162 --- /dev/null +++ b/apps/dav/lib/Listener/CalendarShareUpdateListener.php @@ -0,0 +1,62 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright 2022 Thomas Citharel <nextcloud@tcit.fr> + * + * @author Thomas Citharel <nextcloud@tcit.fr> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +namespace OCA\DAV\Listener; + +use OCA\DAV\CalDAV\Activity\Backend; +use OCA\DAV\Events\CalendarShareUpdatedEvent; +use OCP\EventDispatcher\Event; +use OCP\EventDispatcher\IEventListener; +use Psr\Log\LoggerInterface; + +class CalendarShareUpdateListener implements IEventListener { + private Backend $activityBackend; + private LoggerInterface $logger; + + public function __construct(Backend $activityBackend, + LoggerInterface $logger) { + $this->activityBackend = $activityBackend; + $this->logger = $logger; + } + + /** + * In case the user has set their default calendar to the deleted one + */ + public function handle(Event $event): void { + if (!($event instanceof CalendarShareUpdatedEvent)) { + // Not what we subscribed to + return; + } + + $this->logger->debug("Creating activity for Calendar having it's shares updated"); + + $this->activityBackend->onCalendarUpdateShares( + $event->getCalendarData(), + $event->getOldShares(), + $event->getAdded(), + $event->getRemoved() + ); + } +} diff --git a/apps/dav/lib/Listener/ClearPhotoCacheListener.php b/apps/dav/lib/Listener/ClearPhotoCacheListener.php new file mode 100644 index 00000000000..ed02770e35d --- /dev/null +++ b/apps/dav/lib/Listener/ClearPhotoCacheListener.php @@ -0,0 +1,48 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright 2022 Thomas Citharel <nextcloud@tcit.fr> + * + * @author Thomas Citharel <nextcloud@tcit.fr> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +namespace OCA\DAV\Listener; + +use OCA\DAV\CardDAV\PhotoCache; +use OCA\DAV\Events\CardDeletedEvent; +use OCA\DAV\Events\CardUpdatedEvent; +use OCP\EventDispatcher\Event; +use OCP\EventDispatcher\IEventListener; + +class ClearPhotoCacheListener implements IEventListener { + private PhotoCache $photoCache; + + public function __construct(PhotoCache $photoCache) { + $this->photoCache = $photoCache; + } + + public function handle(Event $event): void { + if ($event instanceof CardUpdatedEvent || $event instanceof CardDeletedEvent) { + $cardData = $event->getCardData(); + + $this->photoCache->delete($event->getAddressBookId(), $cardData['uri']); + } + } +} diff --git a/apps/dav/lib/Listener/SubscriptionListener.php b/apps/dav/lib/Listener/SubscriptionListener.php new file mode 100644 index 00000000000..36db234aa05 --- /dev/null +++ b/apps/dav/lib/Listener/SubscriptionListener.php @@ -0,0 +1,85 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright 2022 Thomas Citharel <nextcloud@tcit.fr> + * + * @author Thomas Citharel <nextcloud@tcit.fr> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +namespace OCA\DAV\Listener; + +use OCA\DAV\BackgroundJob\RefreshWebcalJob; +use OCA\DAV\CalDAV\Reminder\Backend as ReminderBackend; +use OCA\DAV\CalDAV\WebcalCaching\RefreshWebcalService; +use OCA\DAV\Events\SubscriptionCreatedEvent; +use OCA\DAV\Events\SubscriptionDeletedEvent; +use OCP\BackgroundJob\IJobList; +use OCP\EventDispatcher\Event; +use OCP\EventDispatcher\IEventListener; +use Psr\Log\LoggerInterface; + +class SubscriptionListener implements IEventListener { + private IJobList $jobList; + private RefreshWebcalService $refreshWebcalService; + private ReminderBackend $reminderBackend; + private LoggerInterface $logger; + + public function __construct(IJobList $jobList, RefreshWebcalService $refreshWebcalService, ReminderBackend $reminderBackend, + LoggerInterface $logger) { + $this->jobList = $jobList; + $this->refreshWebcalService = $refreshWebcalService; + $this->reminderBackend = $reminderBackend; + $this->logger = $logger; + } + + /** + * In case the user has set their default calendar to the deleted one + */ + public function handle(Event $event): void { + if ($event instanceof SubscriptionCreatedEvent) { + $subscriptionId = $event->getSubscriptionId(); + $subscriptionData = $event->getSubscriptionData(); + + $this->logger->debug('Refreshing webcal data for subscription ' . $subscriptionId); + $this->refreshWebcalService->refreshSubscription( + (string)$subscriptionData['principaluri'], + (string)$subscriptionData['uri'] + ); + + $this->logger->debug('Scheduling webcal data refreshment for subscription ' . $subscriptionId); + $this->jobList->add(RefreshWebcalJob::class, [ + 'principaluri' => $subscriptionData['principaluri'], + 'uri' => $subscriptionData['uri'] + ]); + } elseif ($event instanceof SubscriptionDeletedEvent) { + $subscriptionId = $event->getSubscriptionId(); + $subscriptionData = $event->getSubscriptionData(); + + $this->logger->debug('Removing refresh webcal job for subscription ' . $subscriptionId); + $this->jobList->remove(RefreshWebcalJob::class, [ + 'principaluri' => $subscriptionData['principaluri'], + 'uri' => $subscriptionData['uri'] + ]); + + $this->logger->debug('Cleaning all reminders for subscription ' . $subscriptionId); + $this->reminderBackend->cleanRemindersForCalendar($subscriptionId); + } + } +} diff --git a/apps/dav/lib/Listener/TrustedServerRemovedListener.php b/apps/dav/lib/Listener/TrustedServerRemovedListener.php new file mode 100644 index 00000000000..29ff050983b --- /dev/null +++ b/apps/dav/lib/Listener/TrustedServerRemovedListener.php @@ -0,0 +1,50 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright 2022 Carl Schwan <carl@carlschwan.eu> + * + * @author Carl Schwan <carl@carlschwan.eu> + * + * @license AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +namespace OCA\DAV\Listener; + +use OCA\DAV\CardDAV\CardDavBackend; +use OCP\EventDispatcher\Event; +use OCP\EventDispatcher\IEventListener; +use OCP\Federation\Events\TrustedServerRemovedEvent; + +class TrustedServerRemovedListener implements IEventListener { + private CardDavBackend $cardDavBackend; + + public function __construct(CardDavBackend $cardDavBackend) { + $this->cardDavBackend = $cardDavBackend; + } + + public function handle(Event $event): void { + if (!$event instanceof TrustedServerRemovedEvent) { + return; + } + $addressBookUri = $event->getUrlHash(); + $addressBook = $this->cardDavBackend->getAddressBooksByUri('principals/system/system', $addressBookUri); + if (!is_null($addressBook)) { + $this->cardDavBackend->deleteAddressBook($addressBook['id']); + } + } +} diff --git a/apps/dav/lib/Listener/UserPreferenceListener.php b/apps/dav/lib/Listener/UserPreferenceListener.php new file mode 100644 index 00000000000..947f6d3fd01 --- /dev/null +++ b/apps/dav/lib/Listener/UserPreferenceListener.php @@ -0,0 +1,59 @@ +<?php + +declare(strict_types=1); +/** + * @copyright Copyright (c) 2022 Joas Schilling <coding@schilljs.com> + * + * @author Joas Schilling <coding@schilljs.com> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +namespace OCA\DAV\Listener; + +use OCA\DAV\BackgroundJob\UserStatusAutomation; +use OCP\BackgroundJob\IJobList; +use OCP\Config\BeforePreferenceDeletedEvent; +use OCP\Config\BeforePreferenceSetEvent; +use OCP\EventDispatcher\Event; +use OCP\EventDispatcher\IEventListener; + +class UserPreferenceListener implements IEventListener { + + protected IJobList $jobList; + + public function __construct(IJobList $jobList) { + $this->jobList = $jobList; + } + + public function handle(Event $event): void { + if ($event instanceof BeforePreferenceSetEvent) { + if ($event->getAppId() === 'dav' && $event->getConfigKey() === 'user_status_automation' && $event->getConfigValue() === 'yes') { + $event->setValid(true); + + // Not the cleanest way, but we just add the job in the before event. + // If something ever turns wrong the first execution will remove the job again. + // We also first delete the current job, so the next run time is reset. + $this->jobList->remove(UserStatusAutomation::class, ['userId' => $event->getUserId()]); + $this->jobList->add(UserStatusAutomation::class, ['userId' => $event->getUserId()]); + } + } elseif ($event instanceof BeforePreferenceDeletedEvent) { + if ($event->getAppId() === 'dav' && $event->getConfigKey() === 'user_status_automation') { + $event->setValid(true); + } + } + } +} diff --git a/apps/dav/lib/Migration/RemoveObjectProperties.php b/apps/dav/lib/Migration/RemoveObjectProperties.php new file mode 100644 index 00000000000..c72dfbebfea --- /dev/null +++ b/apps/dav/lib/Migration/RemoveObjectProperties.php @@ -0,0 +1,65 @@ +<?php +/** + * @copyright Copyright (c) 2021, Thomas Citharel <nextcloud@tcit.fr>. + * + * @author Thomas Citharel <nextcloud@tcit.fr> + * + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ +namespace OCA\DAV\Migration; + +use OCP\DB\QueryBuilder\IQueryBuilder; +use OCP\IDBConnection; +use OCP\Migration\IOutput; +use OCP\Migration\IRepairStep; + +class RemoveObjectProperties implements IRepairStep { + private const RESOURCE_TYPE_PROPERTY = '{DAV:}resourcetype'; + private const ME_CARD_PROPERTY = '{http://calendarserver.org/ns/}me-card'; + private const CALENDAR_TRANSP_PROPERTY = '{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp'; + + /** @var IDBConnection */ + private $connection; + + /** + * RemoveObjectProperties constructor. + * + * @param IDBConnection $connection + */ + public function __construct(IDBConnection $connection) { + $this->connection = $connection; + } + + /** + * @inheritdoc + */ + public function getName() { + return 'Remove invalid object properties'; + } + + /** + * @inheritdoc + */ + public function run(IOutput $output) { + $query = $this->connection->getQueryBuilder(); + $updated = $query->delete('properties') + ->where($query->expr()->in('propertyname', $query->createNamedParameter([self::RESOURCE_TYPE_PROPERTY, self::ME_CARD_PROPERTY, self::CALENDAR_TRANSP_PROPERTY], IQueryBuilder::PARAM_STR_ARRAY))) + ->andWhere($query->expr()->eq('propertyvalue', $query->createNamedParameter('Object'))) + ->executeStatement(); + + $output->info("$updated invalid object properties removed."); + } +} diff --git a/apps/dav/lib/Migration/Version1024Date20211221144219.php b/apps/dav/lib/Migration/Version1024Date20211221144219.php new file mode 100644 index 00000000000..b93f8ac801e --- /dev/null +++ b/apps/dav/lib/Migration/Version1024Date20211221144219.php @@ -0,0 +1,58 @@ +<?php + +declare(strict_types=1); + +namespace OCA\DAV\Migration; + +use Closure; +use Doctrine\DBAL\Schema\SchemaException; +use OCA\DAV\DAV\CustomPropertiesBackend; +use OCP\DB\ISchemaWrapper; +use OCP\DB\Types; +use OCP\Migration\IOutput; +use OCP\Migration\SimpleMigrationStep; + +/** + * Auto-generated migration step: Please modify to your needs! + */ +class Version1024Date20211221144219 extends SimpleMigrationStep { + + /** + * @param IOutput $output + * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` + * @param array $options + */ + public function preSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void { + } + + /** + * @param IOutput $output + * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` + * @param array $options + * @return null|ISchemaWrapper + * @throws SchemaException + */ + public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper { + /** @var ISchemaWrapper $schema */ + $schema = $schemaClosure(); + $propertiesTable = $schema->getTable('properties'); + + if ($propertiesTable->hasColumn('valuetype')) { + return null; + } + $propertiesTable->addColumn('valuetype', Types::SMALLINT, [ + 'notnull' => false, + 'default' => CustomPropertiesBackend::PROPERTY_TYPE_STRING + ]); + + return $schema; + } + + /** + * @param IOutput $output + * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` + * @param array $options + */ + public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void { + } +} diff --git a/apps/dav/lib/RootCollection.php b/apps/dav/lib/RootCollection.php index 8a11a676609..29ab65d46a9 100644 --- a/apps/dav/lib/RootCollection.php +++ b/apps/dav/lib/RootCollection.php @@ -7,6 +7,7 @@ * @author Georg Ehrke <oc.list@georgehrke.com> * @author Joas Schilling <coding@schilljs.com> * @author Roeland Jago Douma <roeland@famdouma.nl> + * @author Thomas Citharel <nextcloud@tcit.fr> * @author Thomas Müller <thomas.mueller@tmit.eu> * @author Vincent Petry <vincent@nextcloud.com> * @@ -43,6 +44,7 @@ use OCA\DAV\DAV\GroupPrincipalBackend; use OCA\DAV\DAV\SystemPrincipalBackend; use OCA\DAV\Provisioning\Apple\AppleProvisioningNode; use OCA\DAV\Upload\CleanupService; +use OCP\Accounts\IAccountManager; use OCP\App\IAppManager; use OCP\AppFramework\Utility\ITimeFactory; use OCP\EventDispatcher\IEventDispatcher; @@ -61,13 +63,13 @@ class RootCollection extends SimpleCollection { $shareManager = \OC::$server->getShareManager(); $db = \OC::$server->getDatabaseConnection(); $dispatcher = \OC::$server->get(IEventDispatcher::class); - $legacyDispatcher = \OC::$server->getEventDispatcher(); $config = \OC::$server->get(IConfig::class); $proxyMapper = \OC::$server->query(ProxyMapper::class); $userPrincipalBackend = new Principal( $userManager, $groupManager, + \OC::$server->get(IAccountManager::class), $shareManager, \OC::$server->getUserSession(), \OC::$server->getAppManager(), @@ -105,7 +107,6 @@ class RootCollection extends SimpleCollection { $random, $logger, $dispatcher, - $legacyDispatcher, $config ); $userCalendarRoot = new CalendarRoot($userPrincipalBackend, $caldavBackend, 'principals/users', $logger); @@ -140,11 +141,11 @@ class RootCollection extends SimpleCollection { ); $pluginManager = new PluginManager(\OC::$server, \OC::$server->query(IAppManager::class)); - $usersCardDavBackend = new CardDavBackend($db, $userPrincipalBackend, $userManager, $groupManager, $dispatcher, $legacyDispatcher); + $usersCardDavBackend = new CardDavBackend($db, $userPrincipalBackend, $userManager, $groupManager, $dispatcher); $usersAddressBookRoot = new AddressBookRoot($userPrincipalBackend, $usersCardDavBackend, $pluginManager, 'principals/users'); $usersAddressBookRoot->disableListing = $disableListing; - $systemCardDavBackend = new CardDavBackend($db, $userPrincipalBackend, $userManager, $groupManager, $dispatcher, $legacyDispatcher); + $systemCardDavBackend = new CardDavBackend($db, $userPrincipalBackend, $userManager, $groupManager, $dispatcher); $systemAddressBookRoot = new AddressBookRoot(new SystemPrincipalBackend(), $systemCardDavBackend, $pluginManager, 'principals/system'); $systemAddressBookRoot->disableListing = $disableListing; diff --git a/apps/dav/lib/Server.php b/apps/dav/lib/Server.php index 5b532465aba..2cfcb3f5393 100644 --- a/apps/dav/lib/Server.php +++ b/apps/dav/lib/Server.php @@ -62,6 +62,7 @@ use OCA\DAV\Connector\Sabre\SharesPlugin; use OCA\DAV\Connector\Sabre\TagsPlugin; use OCA\DAV\DAV\CustomPropertiesBackend; use OCA\DAV\DAV\PublicAuth; +use OCA\DAV\DAV\ViewOnlyPlugin; use OCA\DAV\Events\SabrePluginAuthInitEvent; use OCA\DAV\Files\BrowserErrorPagePlugin; use OCA\DAV\Files\LazySearchBackend; @@ -229,6 +230,11 @@ class Server { $this->server->addPlugin(new FakeLockerPlugin()); } + // Allow view-only plugin for webdav requests + $this->server->addPlugin(new ViewOnlyPlugin( + $logger + )); + if (BrowserErrorPagePlugin::isBrowserRequest($request)) { $this->server->addPlugin(new BrowserErrorPagePlugin()); } diff --git a/apps/dav/lib/Settings/AvailabilitySettings.php b/apps/dav/lib/Settings/AvailabilitySettings.php index 9a163e21edb..d2b75ba4866 100644 --- a/apps/dav/lib/Settings/AvailabilitySettings.php +++ b/apps/dav/lib/Settings/AvailabilitySettings.php @@ -27,10 +27,34 @@ namespace OCA\DAV\Settings; use OCA\DAV\AppInfo\Application; use OCP\AppFramework\Http\TemplateResponse; +use OCP\AppFramework\Services\IInitialState; +use OCP\IConfig; use OCP\Settings\ISettings; class AvailabilitySettings implements ISettings { + protected IConfig $config; + protected IInitialState $initialState; + protected ?string $userId; + + public function __construct(IConfig $config, + IInitialState $initialState, + ?string $userId) { + $this->config = $config; + $this->initialState = $initialState; + $this->userId = $userId; + } + public function getForm(): TemplateResponse { + $this->initialState->provideInitialState( + 'user_status_automation', + $this->config->getUserValue( + $this->userId, + 'dav', + 'user_status_automation', + 'no' + ) + ); + return new TemplateResponse(Application::APP_ID, 'settings-personal-availability'); } diff --git a/apps/dav/lib/UserMigration/ContactsMigrator.php b/apps/dav/lib/UserMigration/ContactsMigrator.php index ae1a61ce4f4..d2ba82eb2e5 100644 --- a/apps/dav/lib/UserMigration/ContactsMigrator.php +++ b/apps/dav/lib/UserMigration/ContactsMigrator.php @@ -131,6 +131,10 @@ class ContactsMigrator implements IMigrator, ISizeEstimationMigrator { } } + if (count($vCards) === 0) { + throw new InvalidAddressBookException(); + } + return [ 'name' => $addressBookNode->getName(), 'displayName' => $addressBookInfo['{DAV:}displayname'], diff --git a/apps/dav/src/service/PreferenceService.js b/apps/dav/src/service/PreferenceService.js new file mode 100644 index 00000000000..6b8d29029b5 --- /dev/null +++ b/apps/dav/src/service/PreferenceService.js @@ -0,0 +1,50 @@ +/** + * @copyright 2022 Joas Schilling <coding@schilljs.com> + * + * @author Joas Schilling <coding@schilljs.com> + * + * @license AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +import axios from '@nextcloud/axios' +import { generateOcsUrl } from '@nextcloud/router' + +/** + * Enable user status automation based on availability + */ +export async function enableUserStatusAutomation() { + return await axios.post( + generateOcsUrl('/apps/provisioning_api/api/v1/config/users/{appId}/{configKey}', { + appId: 'dav', + configKey: 'user_status_automation', + }), + { + configValue: 'yes', + } + ) +} + +/** + * Disable user status automation based on availability + */ +export async function disableUserStatusAutomation() { + return await axios.delete( + generateOcsUrl('/apps/provisioning_api/api/v1/config/users/{appId}/{configKey}', { + appId: 'dav', + configKey: 'user_status_automation', + }) + ) +} diff --git a/apps/dav/src/views/Availability.vue b/apps/dav/src/views/Availability.vue index f3b3ec34bd2..515b3a3b63a 100644 --- a/apps/dav/src/views/Availability.vue +++ b/apps/dav/src/views/Availability.vue @@ -24,6 +24,10 @@ :l10n-saturday="$t('dav', 'Saturday')" :l10n-sunday="$t('dav', 'Sunday')" /> + <CheckboxRadioSwitch :checked.sync="automated"> + {{ $t('dav', 'Automatically set user status to "Do not disturb" outside of availability to mute all notifications.') }} + </CheckboxRadioSwitch> + <Button :disabled="loading || saving" type="primary" @click="save"> @@ -34,6 +38,7 @@ <script> import { CalendarAvailability } from '@nextcloud/calendar-availability-vue' +import { loadState } from '@nextcloud/initial-state' import { showError, showSuccess, @@ -43,8 +48,13 @@ import { getEmptySlots, saveScheduleInboxAvailability, } from '../service/CalendarService' +import { + enableUserStatusAutomation, + disableUserStatusAutomation, +} from '../service/PreferenceService' import jstz from 'jstimezonedetect' import Button from '@nextcloud/vue/dist/Components/Button' +import CheckboxRadioSwitch from '@nextcloud/vue/dist/Components/CheckboxRadioSwitch' import SettingsSection from '@nextcloud/vue/dist/Components/SettingsSection' import TimezonePicker from '@nextcloud/vue/dist/Components/TimezonePicker' @@ -52,6 +62,7 @@ export default { name: 'Availability', components: { Button, + CheckboxRadioSwitch, CalendarAvailability, SettingsSection, TimezonePicker, @@ -66,6 +77,7 @@ export default { saving: false, timezone: defaultTimezoneId, slots: getEmptySlots(), + automated: loadState('dav', 'user_status_automation') === 'yes', } }, async mounted() { @@ -96,6 +108,11 @@ export default { this.saving = true await saveScheduleInboxAvailability(this.slots, this.timezone) + if (this.automated) { + await enableUserStatusAutomation() + } else { + await disableUserStatusAutomation() + } showSuccess(t('dav', 'Saved availability')) } catch (e) { diff --git a/apps/dav/src/views/__snapshots__/CalDavSettings.spec.js.snap b/apps/dav/src/views/__snapshots__/CalDavSettings.spec.js.snap index fa101948bd6..18d953a174c 100644 --- a/apps/dav/src/views/__snapshots__/CalDavSettings.spec.js.snap +++ b/apps/dav/src/views/__snapshots__/CalDavSettings.spec.js.snap @@ -4,28 +4,26 @@ exports[`CalDavSettings interactions 1`] = ` <div> <div class="settings-section" - data-v-548823d7="" + data-v-4115f3cb="" > <h2 class="settings-section__title" - data-v-548823d7="" + data-v-4115f3cb="" > Calendar server <a class="settings-section__info" - data-v-548823d7="" + data-v-4115f3cb="" href="https://docs.nextcloud.com/server/23/go.php?to=user-sync-calendars" role="note" title="External documentation for Calendar server" > <span aria-hidden="true" - aria-label="" class="material-design-icon help-circle-icon" - data-v-548823d7="" - decorative="" + data-v-4115f3cb="" role="img" > <svg @@ -49,7 +47,7 @@ exports[`CalDavSettings interactions 1`] = ` <p class="settings-hint" - data-v-548823d7="" + data-v-4115f3cb="" > Also install the <a @@ -70,17 +68,17 @@ exports[`CalDavSettings interactions 1`] = ` </p> <p - data-v-548823d7="" + data-v-4115f3cb="" > <span class="checkbox-radio-switch checkbox-radio-switch-switch checkbox-radio-switch--checked" - data-v-036397c2="" - data-v-548823d7="" + data-v-4115f3cb="" + data-v-797e24c1="" style="--icon-size: 36px;" > <input class="checkbox-radio-switch__input" - data-v-036397c2="" + data-v-797e24c1="" id="caldavSendInvitations" type="checkbox" value="" @@ -88,15 +86,13 @@ exports[`CalDavSettings interactions 1`] = ` <label class="checkbox-radio-switch__label" - data-v-036397c2="" + data-v-797e24c1="" for="caldavSendInvitations" > <span aria-hidden="true" - aria-label="" class="material-design-icon toggle-switch-icon checkbox-radio-switch__icon" - data-v-036397c2="" - decorative="" + data-v-797e24c1="" role="img" > <svg @@ -120,7 +116,7 @@ exports[`CalDavSettings interactions 1`] = ` </span> <em - data-v-548823d7="" + data-v-4115f3cb="" > Please make sure to properly set up <a @@ -133,17 +129,17 @@ exports[`CalDavSettings interactions 1`] = ` </p> <p - data-v-548823d7="" + data-v-4115f3cb="" > <span class="checkbox-radio-switch checkbox checkbox-radio-switch-switch checkbox-radio-switch--checked" - data-v-036397c2="" - data-v-548823d7="" + data-v-4115f3cb="" + data-v-797e24c1="" style="--icon-size: 36px;" > <input class="checkbox-radio-switch__input" - data-v-036397c2="" + data-v-797e24c1="" id="caldavGenerateBirthdayCalendar" type="checkbox" value="" @@ -151,15 +147,13 @@ exports[`CalDavSettings interactions 1`] = ` <label class="checkbox-radio-switch__label" - data-v-036397c2="" + data-v-797e24c1="" for="caldavGenerateBirthdayCalendar" > <span aria-hidden="true" - aria-label="" class="material-design-icon toggle-switch-icon checkbox-radio-switch__icon" - data-v-036397c2="" - decorative="" + data-v-797e24c1="" role="img" > <svg @@ -183,7 +177,7 @@ exports[`CalDavSettings interactions 1`] = ` </span> <em - data-v-548823d7="" + data-v-4115f3cb="" > Birthday calendars will be generated by a background job. @@ -191,11 +185,11 @@ exports[`CalDavSettings interactions 1`] = ` </em> <br - data-v-548823d7="" + data-v-4115f3cb="" /> <em - data-v-548823d7="" + data-v-4115f3cb="" > Hence they will not be available immediately after enabling but will show up after some time. @@ -204,17 +198,17 @@ exports[`CalDavSettings interactions 1`] = ` </p> <p - data-v-548823d7="" + data-v-4115f3cb="" > <span class="checkbox-radio-switch checkbox-radio-switch-switch checkbox-radio-switch--checked" - data-v-036397c2="" - data-v-548823d7="" + data-v-4115f3cb="" + data-v-797e24c1="" style="--icon-size: 36px;" > <input class="checkbox-radio-switch__input" - data-v-036397c2="" + data-v-797e24c1="" id="caldavSendEventReminders" type="checkbox" value="" @@ -222,15 +216,13 @@ exports[`CalDavSettings interactions 1`] = ` <label class="checkbox-radio-switch__label" - data-v-036397c2="" + data-v-797e24c1="" for="caldavSendEventReminders" > <span aria-hidden="true" - aria-label="" class="material-design-icon toggle-switch-icon checkbox-radio-switch__icon" - data-v-036397c2="" - decorative="" + data-v-797e24c1="" role="img" > <svg @@ -254,7 +246,7 @@ exports[`CalDavSettings interactions 1`] = ` </span> <em - data-v-548823d7="" + data-v-4115f3cb="" > Please make sure to properly set up <a @@ -266,11 +258,11 @@ exports[`CalDavSettings interactions 1`] = ` </em> <br - data-v-548823d7="" + data-v-4115f3cb="" /> <em - data-v-548823d7="" + data-v-4115f3cb="" > Notifications are sent via background jobs, so these must occur often enough. @@ -280,17 +272,17 @@ exports[`CalDavSettings interactions 1`] = ` <p class="indented" - data-v-548823d7="" + data-v-4115f3cb="" > <span class="checkbox-radio-switch checkbox-radio-switch-switch checkbox-radio-switch--checked" - data-v-036397c2="" - data-v-548823d7="" + data-v-4115f3cb="" + data-v-797e24c1="" style="--icon-size: 36px;" > <input class="checkbox-radio-switch__input" - data-v-036397c2="" + data-v-797e24c1="" id="caldavSendEventRemindersToSharedGroupMembers" type="checkbox" value="" @@ -298,15 +290,13 @@ exports[`CalDavSettings interactions 1`] = ` <label class="checkbox-radio-switch__label" - data-v-036397c2="" + data-v-797e24c1="" for="caldavSendEventRemindersToSharedGroupMembers" > <span aria-hidden="true" - aria-label="" class="material-design-icon toggle-switch-icon checkbox-radio-switch__icon" - data-v-036397c2="" - decorative="" + data-v-797e24c1="" role="img" > <svg @@ -330,7 +320,7 @@ exports[`CalDavSettings interactions 1`] = ` </span> <em - data-v-548823d7="" + data-v-4115f3cb="" > Reminders are always sent to organizers and attendees. @@ -340,17 +330,17 @@ exports[`CalDavSettings interactions 1`] = ` <p class="indented" - data-v-548823d7="" + data-v-4115f3cb="" > <span class="checkbox-radio-switch checkbox-radio-switch-switch checkbox-radio-switch--checked" - data-v-036397c2="" - data-v-548823d7="" + data-v-4115f3cb="" + data-v-797e24c1="" style="--icon-size: 36px;" > <input class="checkbox-radio-switch__input" - data-v-036397c2="" + data-v-797e24c1="" id="caldavSendEventRemindersPush" type="checkbox" value="" @@ -358,15 +348,13 @@ exports[`CalDavSettings interactions 1`] = ` <label class="checkbox-radio-switch__label" - data-v-036397c2="" + data-v-797e24c1="" for="caldavSendEventRemindersPush" > <span aria-hidden="true" - aria-label="" class="material-design-icon toggle-switch-icon checkbox-radio-switch__icon" - data-v-036397c2="" - decorative="" + data-v-797e24c1="" role="img" > <svg diff --git a/apps/dav/templates/schedule-response-error.php b/apps/dav/templates/schedule-response-error.php index 010ea2ed6cb..ff6ae19fb1f 100644 --- a/apps/dav/templates/schedule-response-error.php +++ b/apps/dav/templates/schedule-response-error.php @@ -1,7 +1,15 @@ -<div class="update"> - <p class="message"><?php p($l->t('There was an error updating your attendance status.'));?></p> - <p class="message"><?php p($l->t('Please contact the organizer directly.'));?></p> - <?php if (isset($_['organizer'])): ?> - <p class="message"><a href="<?php p($_['organizer']) ?>"><?php p(substr($_['organizer'], 7)) ?></a></p> - <?php endif; ?> +<?php +// SPDX-FileCopyrightText: 2018 Georg Ehrke <oc.list@georgehrke.com> +// SPDX-FileCopyrightText: 2020 Christoph Wurst <christoph@winzerhof-wurst.at> +// SPDX-FileCopyrightText: 2022 Carl Schwan <carl@carlschwan.eu> +// SPDX-License-Identifier: AGPL-3.0-or-later +?> +<div class="guest-box"> + <div class="notecard error"> + <p><?php p($l->t('There was an error updating your attendance status.'));?></p> + <p><?php p($l->t('Please contact the organizer directly.'));?></p> + <?php if (isset($_['organizer'])): ?> + <p><a href="<?php p($_['organizer']) ?>"><?php p(substr($_['organizer'], 7)) ?></a></p> + <?php endif; ?> + </div> </div> diff --git a/apps/dav/templates/schedule-response-options.php b/apps/dav/templates/schedule-response-options.php index f5ebb46cb26..fe12ea96c79 100644 --- a/apps/dav/templates/schedule-response-options.php +++ b/apps/dav/templates/schedule-response-options.php @@ -1,8 +1,10 @@ <?php -style('dav', 'schedule-response'); +// SPDX-FileCopyrightText: 2018 Georg Ehrke <oc.list@georgehrke.com> +// SPDX-License-Identifier: AGPL-3.0-or-later +\OCP\Util::addStyle('dav', 'schedule-response'); ?> -<div class="update"> +<div class="guest-box"> <form action="" method="post"> <fieldset id="partStat"> <h2><?php p($l->t('Are you accepting the invitation?')); ?></h2> diff --git a/apps/dav/templates/schedule-response-success.php b/apps/dav/templates/schedule-response-success.php index f60cb1e0fa9..fa217164035 100644 --- a/apps/dav/templates/schedule-response-success.php +++ b/apps/dav/templates/schedule-response-success.php @@ -1,4 +1,9 @@ -<div class="update" style="justify-content: space-around; display: flex;"> - <span class="icon icon-checkmark-white"></span> +<?php +// SPDX-FileCopyrightText: 2020 Christoph Wurst <christoph@winzerhof-wurst.at> +// SPDX-FileCopyrightText: 2022 Carl Schwan <carl@carlschwan.eu> +// SPDX-License-Identifier: AGPL-3.0-or-later +?> +<div class="guest-box"> + <div class="icon icon-checkmark"></div> <p class="message"><?php p($l->t('Your attendance was updated successfully.'));?></p> </div> diff --git a/apps/dav/tests/travis/caldavtest/serverinfo-new-endpoint.xml b/apps/dav/tests/travis/caldavtest/serverinfo-new-endpoint.xml index c3ba99ee03d..1542047ff02 100644 --- a/apps/dav/tests/travis/caldavtest/serverinfo-new-endpoint.xml +++ b/apps/dav/tests/travis/caldavtest/serverinfo-new-endpoint.xml @@ -183,7 +183,7 @@ <value>$root:principals/</value> </substitution> - <!-- the core recored type collections--> + <!-- the core record type collections--> <substitution> <key>$uidstype:</key> <value>__uids__</value> diff --git a/apps/dav/tests/travis/caldavtest/serverinfo-old-caldav-endpoint.xml b/apps/dav/tests/travis/caldavtest/serverinfo-old-caldav-endpoint.xml index 8ac822d8e4e..3469e36b4a3 100644 --- a/apps/dav/tests/travis/caldavtest/serverinfo-old-caldav-endpoint.xml +++ b/apps/dav/tests/travis/caldavtest/serverinfo-old-caldav-endpoint.xml @@ -183,7 +183,7 @@ <value>$root:principals/</value> </substitution> - <!-- the core recored type collections--> + <!-- the core record type collections--> <substitution> <key>$uidstype:</key> <value>__uids__</value> diff --git a/apps/dav/tests/travis/caldavtest/serverinfo-old-carddav-endpoint.xml b/apps/dav/tests/travis/caldavtest/serverinfo-old-carddav-endpoint.xml index bd9f83a4814..36af27de3a1 100644 --- a/apps/dav/tests/travis/caldavtest/serverinfo-old-carddav-endpoint.xml +++ b/apps/dav/tests/travis/caldavtest/serverinfo-old-carddav-endpoint.xml @@ -183,7 +183,7 @@ <value>$root:principals/</value> </substitution> - <!-- the core recored type collections--> + <!-- the core record type collections--> <substitution> <key>$uidstype:</key> <value>__uids__</value> diff --git a/apps/dav/tests/unit/BackgroundJob/CleanupInvitationTokenJobTest.php b/apps/dav/tests/unit/BackgroundJob/CleanupInvitationTokenJobTest.php index 6233980edbb..8f1a2a1378f 100644 --- a/apps/dav/tests/unit/BackgroundJob/CleanupInvitationTokenJobTest.php +++ b/apps/dav/tests/unit/BackgroundJob/CleanupInvitationTokenJobTest.php @@ -32,6 +32,7 @@ namespace OCA\DAV\Tests\unit\BackgroundJob; use OCA\DAV\BackgroundJob\CleanupInvitationTokenJob; use OCP\AppFramework\Utility\ITimeFactory; use OCP\DB\QueryBuilder\IQueryBuilder; +use OCP\DB\QueryBuilder\IQueryFunction; use OCP\IDBConnection; use Test\TestCase; @@ -77,10 +78,11 @@ class CleanupInvitationTokenJobTest extends TestCase { [1337, \PDO::PARAM_STR, null, 'namedParameter1337'] ]); + $function = $this->createMock(IQueryFunction::class); $expr->expects($this->once()) ->method('lt') ->with('expiration', 'namedParameter1337') - ->willReturn('LT STATEMENT'); + ->willReturn($function); $this->dbConnection->expects($this->once()) ->method('getQueryBuilder') @@ -93,7 +95,7 @@ class CleanupInvitationTokenJobTest extends TestCase { ->willReturn($queryBuilder); $queryBuilder->expects($this->at(3)) ->method('where') - ->with('LT STATEMENT') + ->with($function) ->willReturn($queryBuilder); $queryBuilder->expects($this->at(4)) ->method('execute') diff --git a/apps/dav/tests/unit/CalDAV/AbstractCalDavBackend.php b/apps/dav/tests/unit/CalDAV/AbstractCalDavBackend.php index ec966248e01..73d21746b64 100644 --- a/apps/dav/tests/unit/CalDAV/AbstractCalDavBackend.php +++ b/apps/dav/tests/unit/CalDAV/AbstractCalDavBackend.php @@ -7,6 +7,7 @@ * @author Joas Schilling <coding@schilljs.com> * @author Morris Jobke <hey@morrisjobke.de> * @author Roeland Jago Douma <roeland@famdouma.nl> + * @author Thomas Citharel <nextcloud@tcit.fr> * @author Thomas Müller <thomas.mueller@tmit.eu> * * @license AGPL-3.0 @@ -26,10 +27,10 @@ */ namespace OCA\DAV\Tests\unit\CalDAV; -use OC\KnownUser\KnownUserService; use OCA\DAV\CalDAV\CalDavBackend; use OCA\DAV\CalDAV\Proxy\ProxyMapper; use OCA\DAV\Connector\Sabre\Principal; +use OCP\Accounts\IAccountManager; use OCP\App\IAppManager; use OCP\EventDispatcher\IEventDispatcher; use OCP\IConfig; @@ -39,10 +40,11 @@ use OCP\IUserSession; use OCP\L10N\IFactory; use OCP\Security\ISecureRandom; use OCP\Share\IManager as ShareManager; +use OC\KnownUser\KnownUserService; +use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; use Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet; use Sabre\DAV\Xml\Property\Href; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Test\TestCase; /** @@ -57,17 +59,18 @@ abstract class AbstractCalDavBackend extends TestCase { /** @var CalDavBackend */ protected $backend; - /** @var Principal | \PHPUnit\Framework\MockObject\MockObject */ + /** @var Principal | MockObject */ protected $principal; - /** @var IUserManager|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IUserManager|MockObject */ protected $userManager; - /** @var IGroupManager|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IGroupManager|MockObject */ protected $groupManager; - /** @var IEventDispatcher|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IEventDispatcher|MockObject */ protected $dispatcher; - /** @var EventDispatcherInterface|\PHPUnit\Framework\MockObject\MockObject */ - protected $legacyDispatcher; + + /** @var IConfig | MockObject */ + private $config; /** @var ISecureRandom */ private $random; /** @var LoggerInterface*/ @@ -84,11 +87,11 @@ abstract class AbstractCalDavBackend extends TestCase { $this->userManager = $this->createMock(IUserManager::class); $this->groupManager = $this->createMock(IGroupManager::class); $this->dispatcher = $this->createMock(IEventDispatcher::class); - $this->legacyDispatcher = $this->createMock(EventDispatcherInterface::class); $this->principal = $this->getMockBuilder(Principal::class) ->setConstructorArgs([ $this->userManager, $this->groupManager, + $this->createMock(IAccountManager::class), $this->createMock(ShareManager::class), $this->createMock(IUserSession::class), $this->createMock(IAppManager::class), @@ -120,7 +123,6 @@ abstract class AbstractCalDavBackend extends TestCase { $this->random, $this->logger, $this->dispatcher, - $this->legacyDispatcher, $this->config ); @@ -147,8 +149,6 @@ abstract class AbstractCalDavBackend extends TestCase { $calendars = $this->backend->getCalendarsForUser($principal); $this->dispatcher->expects(self::any()) ->method('dispatchTyped'); - $this->legacyDispatcher->expects(self::any()) - ->method('dispatch'); foreach ($calendars as $calendar) { $this->backend->deleteCalendar($calendar['id'], true); } diff --git a/apps/dav/tests/unit/CalDAV/Activity/BackendTest.php b/apps/dav/tests/unit/CalDAV/Activity/BackendTest.php index 21cbbd169ff..1ad6da177ca 100644 --- a/apps/dav/tests/unit/CalDAV/Activity/BackendTest.php +++ b/apps/dav/tests/unit/CalDAV/Activity/BackendTest.php @@ -33,6 +33,7 @@ use OCP\App\IAppManager; use OCP\IGroup; use OCP\IGroupManager; use OCP\IUser; +use OCP\IUserManager; use OCP\IUserSession; use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; @@ -51,12 +52,16 @@ class BackendTest extends TestCase { /** @var IAppManager|MockObject */ protected $appManager; + /** @var IUserManager|MockObject */ + protected $userManager; + protected function setUp(): void { parent::setUp(); $this->activityManager = $this->createMock(IManager::class); $this->groupManager = $this->createMock(IGroupManager::class); $this->userSession = $this->createMock(IUserSession::class); $this->appManager = $this->createMock(IAppManager::class); + $this->userManager = $this->createMock(IUserManager::class); } /** @@ -69,7 +74,8 @@ class BackendTest extends TestCase { $this->activityManager, $this->groupManager, $this->userSession, - $this->appManager + $this->appManager, + $this->userManager ); } else { return $this->getMockBuilder(Backend::class) @@ -78,8 +84,9 @@ class BackendTest extends TestCase { $this->groupManager, $this->userSession, $this->appManager, + $this->userManager ]) - ->setMethods($methods) + ->onlyMethods($methods) ->getMock(); } } @@ -252,6 +259,10 @@ class BackendTest extends TestCase { ->with($author) ->willReturnSelf(); + $this->userManager->expects($action === Calendar::SUBJECT_DELETE ? $this->exactly(sizeof($users)) : $this->never()) + ->method('userExists') + ->willReturn(true); + $event->expects($this->exactly(sizeof($users))) ->method('setAffectedUser') ->willReturnSelf(); @@ -269,6 +280,24 @@ class BackendTest extends TestCase { $this->invokePrivate($backend, 'triggerCalendarActivity', [$action, $data, $shares, $changedProperties]); } + public function testUserDeletionDoesNotCreateActivity() { + $backend = $this->getBackend(); + + $this->userManager->expects($this->once()) + ->method('userExists') + ->willReturn(false); + + $this->activityManager->expects($this->never()) + ->method('publish'); + + $this->invokePrivate($backend, 'triggerCalendarActivity', [Calendar::SUBJECT_DELETE, [ + 'principaluri' => 'principal/user/admin', + 'id' => 42, + 'uri' => 'this-uri', + '{DAV:}displayname' => 'Name of calendar', + ], [], []]); + } + public function dataGetUsersForShares() { return [ [ diff --git a/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php b/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php index a6439ee6d2b..13025415f2a 100644 --- a/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php +++ b/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php @@ -151,9 +151,6 @@ class CalDavBackendTest extends AbstractCalDavBackend { $calendars = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER); $this->assertCount(1, $calendars); $calendar = new Calendar($this->backend, $calendars[0], $l10n, $config, $logger); - $this->legacyDispatcher->expects($this->at(0)) - ->method('dispatch') - ->with('\OCA\DAV\CalDAV\CalDavBackend::updateShares'); $this->backend->updateShares($calendar, $add, []); $calendars = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER1); $this->assertCount(1, $calendars); diff --git a/apps/dav/tests/unit/CalDAV/Integration/ExternalCalendarTest.php b/apps/dav/tests/unit/CalDAV/Integration/ExternalCalendarTest.php index 0131ab443a8..d2dbdeac493 100644 --- a/apps/dav/tests/unit/CalDAV/Integration/ExternalCalendarTest.php +++ b/apps/dav/tests/unit/CalDAV/Integration/ExternalCalendarTest.php @@ -40,13 +40,13 @@ class ExternalCalendarTest extends TestCase { $this->assertEquals('app-generated--example-app-id--calendar-uri-in-backend', $this->abstractExternalCalendar->getName()); - // Check that the method is final and can't be overriden by other classes + // Check that the method is final and can't be overridden by other classes $reflectionMethod = new \ReflectionMethod(ExternalCalendar::class, 'getName'); $this->assertTrue($reflectionMethod->isFinal()); } public function testSetName():void { - // Check that the method is final and can't be overriden by other classes + // Check that the method is final and can't be overridden by other classes $reflectionMethod = new \ReflectionMethod(ExternalCalendar::class, 'setName'); $this->assertTrue($reflectionMethod->isFinal()); @@ -57,7 +57,7 @@ class ExternalCalendarTest extends TestCase { } public function createDirectory():void { - // Check that the method is final and can't be overriden by other classes + // Check that the method is final and can't be overridden by other classes $reflectionMethod = new \ReflectionMethod(ExternalCalendar::class, 'createDirectory'); $this->assertTrue($reflectionMethod->isFinal()); diff --git a/apps/dav/tests/unit/CalDAV/Listener/CalendarPublicationListenerTest.php b/apps/dav/tests/unit/CalDAV/Listener/CalendarPublicationListenerTest.php new file mode 100644 index 00000000000..c42fca1a1cf --- /dev/null +++ b/apps/dav/tests/unit/CalDAV/Listener/CalendarPublicationListenerTest.php @@ -0,0 +1,79 @@ +<?php +/** + * @copyright 2022 Thomas Citharel <nextcloud@tcit.fr> + * + * @author Thomas Citharel <nextcloud@tcit.fr> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +namespace OCA\DAV\Tests\unit\CalDAV\Listeners; + +use OCA\DAV\CalDAV\Activity\Backend; +use OCA\DAV\Events\CalendarPublishedEvent; +use OCA\DAV\Events\CalendarUnpublishedEvent; +use OCA\DAV\Listener\CalendarPublicationListener; +use OCP\EventDispatcher\Event; +use PHPUnit\Framework\MockObject\MockObject; +use Psr\Log\LoggerInterface; +use Test\TestCase; + +class CalendarPublicationListenerTest extends TestCase { + + /** @var Backend|MockObject */ + private $activityBackend; + + /** @var LoggerInterface|MockObject */ + private $logger; + + private CalendarPublicationListener $calendarPublicationListener; + + /** @var CalendarPublishedEvent|MockObject */ + private $publicationEvent; + + /** @var CalendarUnpublishedEvent|MockObject */ + private $unpublicationEvent; + + protected function setUp(): void { + parent::setUp(); + + $this->activityBackend = $this->createMock(Backend::class); + $this->logger = $this->createMock(LoggerInterface::class); + $this->publicationEvent = $this->createMock(CalendarPublishedEvent::class); + $this->unpublicationEvent = $this->createMock(CalendarUnpublishedEvent::class); + $this->calendarPublicationListener = new CalendarPublicationListener($this->activityBackend, $this->logger); + } + + public function testInvalidEvent(): void { + $this->activityBackend->expects($this->never())->method('onCalendarPublication'); + $this->logger->expects($this->never())->method('debug'); + $this->calendarPublicationListener->handle(new Event()); + } + + public function testPublicationEvent(): void { + $this->publicationEvent->expects($this->once())->method('getCalendarData')->with()->willReturn([]); + $this->activityBackend->expects($this->once())->method('onCalendarPublication')->with([], true); + $this->logger->expects($this->once())->method('debug'); + $this->calendarPublicationListener->handle($this->publicationEvent); + } + + public function testUnPublicationEvent(): void { + $this->unpublicationEvent->expects($this->once())->method('getCalendarData')->with()->willReturn([]); + $this->activityBackend->expects($this->once())->method('onCalendarPublication')->with([], false); + $this->logger->expects($this->once())->method('debug'); + $this->calendarPublicationListener->handle($this->unpublicationEvent); + } +} diff --git a/apps/dav/tests/unit/CalDAV/Listener/CalendarShareUpdateListenerTest.php b/apps/dav/tests/unit/CalDAV/Listener/CalendarShareUpdateListenerTest.php new file mode 100644 index 00000000000..0252cffd5a0 --- /dev/null +++ b/apps/dav/tests/unit/CalDAV/Listener/CalendarShareUpdateListenerTest.php @@ -0,0 +1,70 @@ +<?php +/** + * @copyright 2022 Thomas Citharel <nextcloud@tcit.fr> + * + * @author Thomas Citharel <nextcloud@tcit.fr> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +namespace OCA\DAV\Tests\unit\CalDAV\Listeners; + +use OCA\DAV\CalDAV\Activity\Backend; +use OCA\DAV\Events\CalendarShareUpdatedEvent; +use OCA\DAV\Listener\CalendarShareUpdateListener; +use OCP\EventDispatcher\Event; +use PHPUnit\Framework\MockObject\MockObject; +use Psr\Log\LoggerInterface; +use Test\TestCase; + +class CalendarShareUpdateListenerTest extends TestCase { + + /** @var Backend|MockObject */ + private $activityBackend; + + /** @var LoggerInterface|MockObject */ + private $logger; + + private CalendarShareUpdateListener $calendarPublicationListener; + + /** @var CalendarShareUpdatedEvent|MockObject */ + private $event; + + protected function setUp(): void { + parent::setUp(); + + $this->activityBackend = $this->createMock(Backend::class); + $this->logger = $this->createMock(LoggerInterface::class); + $this->event = $this->createMock(CalendarShareUpdatedEvent::class); + $this->calendarPublicationListener = new CalendarShareUpdateListener($this->activityBackend, $this->logger); + } + + public function testInvalidEvent(): void { + $this->activityBackend->expects($this->never())->method('onCalendarUpdateShares'); + $this->logger->expects($this->never())->method('debug'); + $this->calendarPublicationListener->handle(new Event()); + } + + public function testEvent(): void { + $this->event->expects($this->once())->method('getCalendarData')->with()->willReturn([]); + $this->event->expects($this->once())->method('getOldShares')->with()->willReturn([]); + $this->event->expects($this->once())->method('getAdded')->with()->willReturn([]); + $this->event->expects($this->once())->method('getRemoved')->with()->willReturn([]); + $this->activityBackend->expects($this->once())->method('onCalendarUpdateShares')->with([], [], [], []); + $this->logger->expects($this->once())->method('debug'); + $this->calendarPublicationListener->handle($this->event); + } +} diff --git a/apps/dav/tests/unit/CalDAV/Listener/SubscriptionListenerTest.php b/apps/dav/tests/unit/CalDAV/Listener/SubscriptionListenerTest.php new file mode 100644 index 00000000000..709ebdac7af --- /dev/null +++ b/apps/dav/tests/unit/CalDAV/Listener/SubscriptionListenerTest.php @@ -0,0 +1,95 @@ +<?php +/** + * @copyright 2022 Thomas Citharel <nextcloud@tcit.fr> + * + * @author Thomas Citharel <nextcloud@tcit.fr> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +namespace OCA\DAV\Tests\unit\CalDAV\Listeners; + +use OCA\DAV\BackgroundJob\RefreshWebcalJob; +use OCA\DAV\CalDAV\Reminder\Backend; +use OCA\DAV\CalDAV\WebcalCaching\RefreshWebcalService; +use OCA\DAV\Events\SubscriptionCreatedEvent; +use OCA\DAV\Events\SubscriptionDeletedEvent; +use OCA\DAV\Listener\SubscriptionListener; +use OCP\BackgroundJob\IJobList; +use OCP\EventDispatcher\Event; +use PHPUnit\Framework\MockObject\MockObject; +use Psr\Log\LoggerInterface; +use Test\TestCase; + +class SubscriptionListenerTest extends TestCase { + + /** @var RefreshWebcalService|MockObject */ + private $refreshWebcalService; + + /** @var Backend|MockObject */ + private $reminderBackend; + + /** @var IJobList|MockObject */ + private $jobList; + + /** @var LoggerInterface|MockObject */ + private $logger; + + private SubscriptionListener $calendarPublicationListener; + + /** @var SubscriptionCreatedEvent|MockObject */ + private $subscriptionCreatedEvent; + + /** @var SubscriptionDeletedEvent|MockObject */ + private $subscriptionDeletedEvent; + + protected function setUp(): void { + parent::setUp(); + + $this->refreshWebcalService = $this->createMock(RefreshWebcalService::class); + $this->reminderBackend = $this->createMock(Backend::class); + $this->jobList = $this->createMock(IJobList::class); + $this->logger = $this->createMock(LoggerInterface::class); + $this->subscriptionCreatedEvent = $this->createMock(SubscriptionCreatedEvent::class); + $this->subscriptionDeletedEvent = $this->createMock(SubscriptionDeletedEvent::class); + $this->calendarPublicationListener = new SubscriptionListener($this->jobList, $this->refreshWebcalService, $this->reminderBackend, $this->logger); + } + + public function testInvalidEvent(): void { + $this->refreshWebcalService->expects($this->never())->method('refreshSubscription'); + $this->jobList->expects($this->never())->method('add'); + $this->logger->expects($this->never())->method('debug'); + $this->calendarPublicationListener->handle(new Event()); + } + + public function testCreateSubscriptionEvent(): void { + $this->subscriptionCreatedEvent->expects($this->once())->method('getSubscriptionId')->with()->willReturn(5); + $this->subscriptionCreatedEvent->expects($this->once())->method('getSubscriptionData')->with()->willReturn(['principaluri' => 'principaluri', 'uri' => 'uri']); + $this->refreshWebcalService->expects($this->once())->method('refreshSubscription')->with('principaluri', 'uri'); + $this->jobList->expects($this->once())->method('add')->with(RefreshWebcalJob::class, ['principaluri' => 'principaluri', 'uri' => 'uri']); + $this->logger->expects($this->exactly(2))->method('debug'); + $this->calendarPublicationListener->handle($this->subscriptionCreatedEvent); + } + + public function testDeleteSubscriptionEvent(): void { + $this->subscriptionDeletedEvent->expects($this->once())->method('getSubscriptionId')->with()->willReturn(5); + $this->subscriptionDeletedEvent->expects($this->once())->method('getSubscriptionData')->with()->willReturn(['principaluri' => 'principaluri', 'uri' => 'uri']); + $this->jobList->expects($this->once())->method('remove')->with(RefreshWebcalJob::class, ['principaluri' => 'principaluri', 'uri' => 'uri']); + $this->reminderBackend->expects($this->once())->method('cleanRemindersForCalendar')->with(5); + $this->logger->expects($this->exactly(2))->method('debug'); + $this->calendarPublicationListener->handle($this->subscriptionDeletedEvent); + } +} diff --git a/apps/dav/tests/unit/CalDAV/PublicCalendarRootTest.php b/apps/dav/tests/unit/CalDAV/PublicCalendarRootTest.php index 80e43d279dc..23c1c2ae896 100644 --- a/apps/dav/tests/unit/CalDAV/PublicCalendarRootTest.php +++ b/apps/dav/tests/unit/CalDAV/PublicCalendarRootTest.php @@ -42,7 +42,6 @@ use OCP\IL10N; use OCP\IUserManager; use OCP\Security\ISecureRandom; use Psr\Log\LoggerInterface; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Test\TestCase; /** @@ -84,7 +83,6 @@ class PublicCalendarRootTest extends TestCase { $this->random = \OC::$server->getSecureRandom(); $this->logger = $this->createMock(LoggerInterface::class); $dispatcher = $this->createMock(IEventDispatcher::class); - $legacyDispatcher = $this->createMock(EventDispatcherInterface::class); $config = $this->createMock(IConfig::class); $this->principal->expects($this->any())->method('getGroupMembership') @@ -103,7 +101,6 @@ class PublicCalendarRootTest extends TestCase { $this->random, $this->logger, $dispatcher, - $legacyDispatcher, $config ); $this->l10n = $this->getMockBuilder(IL10N::class) diff --git a/apps/dav/tests/unit/CalDAV/Schedule/PluginTest.php b/apps/dav/tests/unit/CalDAV/Schedule/PluginTest.php index 2518cc3d91a..b651379c2bd 100644 --- a/apps/dav/tests/unit/CalDAV/Schedule/PluginTest.php +++ b/apps/dav/tests/unit/CalDAV/Schedule/PluginTest.php @@ -27,11 +27,15 @@ namespace OCA\DAV\Tests\unit\CalDAV\Schedule; use OCA\DAV\CalDAV\CalDavBackend; +use OCA\DAV\CalDAV\Calendar; use OCA\DAV\CalDAV\CalendarHome; use OCA\DAV\CalDAV\Plugin as CalDAVPlugin; use OCA\DAV\CalDAV\Schedule\Plugin; +use OCA\DAV\CalDAV\Trashbin\Plugin as TrashbinPlugin; use OCP\IConfig; +use OCP\IL10N; use PHPUnit\Framework\MockObject\MockObject; +use Psr\Log\LoggerInterface; use Sabre\DAV\PropFind; use Sabre\DAV\Server; use Sabre\DAV\Tree; @@ -73,17 +77,22 @@ class PluginTest extends TestCase { public function testInitialize() { $plugin = new Plugin($this->config); - $this->server->expects($this->at(7)) + $this->server->expects($this->exactly(10)) ->method('on') - ->with('propFind', [$plugin, 'propFindDefaultCalendarUrl'], 90); - - $this->server->expects($this->at(8)) - ->method('on') - ->with('afterWriteContent', [$plugin, 'dispatchSchedulingResponses']); - - $this->server->expects($this->at(9)) - ->method('on') - ->with('afterCreateFile', [$plugin, 'dispatchSchedulingResponses']); + ->withConsecutive( + // Sabre\CalDAV\Schedule\Plugin events + ['method:POST', [$plugin, 'httpPost']], + ['propFind', [$plugin, 'propFind']], + ['propPatch', [$plugin, 'propPatch']], + ['calendarObjectChange', [$plugin, 'calendarObjectChange']], + ['beforeUnbind', [$plugin, 'beforeUnbind']], + ['schedule', [$plugin, 'scheduleLocalDelivery']], + ['getSupportedPrivilegeSet', [$plugin, 'getSupportedPrivilegeSet']], + // OCA\DAV\CalDAV\Schedule\Plugin events + ['propFind', [$plugin, 'propFindDefaultCalendarUrl'], 90], + ['afterWriteContent', [$plugin, 'dispatchSchedulingResponses']], + ['afterCreateFile', [$plugin, 'dispatchSchedulingResponses']] + ); $plugin->initialize($this->server); } @@ -183,6 +192,15 @@ class PluginTest extends TestCase { false, CalDavBackend::PERSONAL_CALENDAR_URI, CalDavBackend::PERSONAL_CALENDAR_NAME, + false, + true + ], + [ + 'principals/users/myuser', + 'calendars/myuser', + false, + CalDavBackend::PERSONAL_CALENDAR_URI, + CalDavBackend::PERSONAL_CALENDAR_NAME, false ], [ @@ -201,6 +219,7 @@ class PluginTest extends TestCase { CalDavBackend::PERSONAL_CALENDAR_NAME, true, false, + false, ], [ 'principals/users/myuser', @@ -240,14 +259,14 @@ class PluginTest extends TestCase { /** * @dataProvider propFindDefaultCalendarUrlProvider * @param string $principalUri - * @param string $calendarHome + * @param string|null $calendarHome * @param bool $isResource * @param string $calendarUri * @param string $displayName * @param bool $exists * @param bool $propertiesForPath */ - public function testPropFindDefaultCalendarUrl(string $principalUri, ?string $calendarHome, bool $isResource, string $calendarUri, string $displayName, bool $exists, bool $propertiesForPath = true) { + public function testPropFindDefaultCalendarUrl(string $principalUri, ?string $calendarHome, bool $isResource, string $calendarUri, string $displayName, bool $exists, bool $hasExistingCalendars = false, bool $propertiesForPath = true) { /** @var PropFind $propFind */ $propFind = new PropFind( $principalUri, @@ -290,6 +309,7 @@ class PluginTest extends TestCase { $this->assertNull($propFind->get(Plugin::SCHEDULE_DEFAULT_CALENDAR_URL)); return; } + if (!$isResource) { $this->config->expects($this->once()) ->method('getUserValue') @@ -303,18 +323,47 @@ class PluginTest extends TestCase { ->with($calendarUri) ->willReturn($exists); + $calendarBackend = $this->createMock(CalDavBackend::class); + $calendarUri = $hasExistingCalendars ? 'custom' : $calendarUri; + $displayName = $hasExistingCalendars ? 'Custom Calendar' : $displayName; + + $existingCalendars = $hasExistingCalendars ? [ + new Calendar( + $calendarBackend, + ['uri' => 'deleted', '{DAV:}displayname' => 'A deleted calendar', TrashbinPlugin::PROPERTY_DELETED_AT => 42], + $this->createMock(IL10N::class), + $this->config, + $this->createMock(LoggerInterface::class) + ), + new Calendar( + $calendarBackend, + ['uri' => $calendarUri, '{DAV:}displayname' => $displayName], + $this->createMock(IL10N::class), + $this->config, + $this->createMock(LoggerInterface::class) + ) + ] : []; + if (!$exists) { - $calendarBackend = $this->createMock(CalDavBackend::class); - $calendarBackend->expects($this->once()) + if (!$hasExistingCalendars) { + $calendarBackend->expects($this->once()) ->method('createCalendar') ->with($principalUri, $calendarUri, [ '{DAV:}displayname' => $displayName, ]); - $calendarHomeObject->expects($this->once()) - ->method('getCalDAVBackend') - ->with() - ->willReturn($calendarBackend); + $calendarHomeObject->expects($this->once()) + ->method('getCalDAVBackend') + ->with() + ->willReturn($calendarBackend); + } + + if (!$isResource) { + $calendarHomeObject->expects($this->once()) + ->method('getChildren') + ->with() + ->willReturn($existingCalendars); + } } /** @var Tree|MockObject $tree */ diff --git a/apps/dav/tests/unit/CalDAV/WebcalCaching/RefreshWebcalServiceTest.php b/apps/dav/tests/unit/CalDAV/WebcalCaching/RefreshWebcalServiceTest.php index 6bd1f6b3206..71d93bf851e 100644 --- a/apps/dav/tests/unit/CalDAV/WebcalCaching/RefreshWebcalServiceTest.php +++ b/apps/dav/tests/unit/CalDAV/WebcalCaching/RefreshWebcalServiceTest.php @@ -74,7 +74,7 @@ class RefreshWebcalServiceTest extends TestCase { */ public function testRun(string $body, string $contentType, string $result) { $refreshWebcalService = $this->getMockBuilder(RefreshWebcalService::class) - ->setMethods(['getRandomCalendarObjectUri']) + ->onlyMethods(['getRandomCalendarObjectUri']) ->setConstructorArgs([$this->caldavBackend, $this->clientService, $this->config, $this->logger]) ->getMock(); @@ -156,7 +156,7 @@ class RefreshWebcalServiceTest extends TestCase { $client = $this->createMock(IClient::class); $response = $this->createMock(IResponse::class); $refreshWebcalService = $this->getMockBuilder(RefreshWebcalService::class) - ->setMethods(['getRandomCalendarObjectUri', 'getSubscription', 'queryWebcalFeed']) + ->onlyMethods(['getRandomCalendarObjectUri', 'getSubscription', 'queryWebcalFeed']) ->setConstructorArgs([$this->caldavBackend, $this->clientService, $this->config, $this->logger]) ->getMock(); @@ -217,7 +217,7 @@ class RefreshWebcalServiceTest extends TestCase { $this->logger->expects($this->once()) ->method('error') - ->with($noInstanceException->getMessage(), ['exception' => $noInstanceException]); + ->with('Unable to create calendar object from subscription {subscriptionId}', ['exception' => $noInstanceException, 'subscriptionId' => '42', 'source' => 'webcal://foo.bar/bla2']); $refreshWebcalService->refreshSubscription('principals/users/testuser', 'sub123'); } @@ -233,7 +233,7 @@ class RefreshWebcalServiceTest extends TestCase { $client = $this->createMock(IClient::class); $response = $this->createMock(IResponse::class); $refreshWebcalService = $this->getMockBuilder(RefreshWebcalService::class) - ->setMethods(['getRandomCalendarObjectUri', 'getSubscription', 'queryWebcalFeed']) + ->onlyMethods(['getRandomCalendarObjectUri', 'getSubscription', 'queryWebcalFeed']) ->setConstructorArgs([$this->caldavBackend, $this->clientService, $this->config, $this->logger]) ->getMock(); @@ -294,7 +294,7 @@ class RefreshWebcalServiceTest extends TestCase { $this->logger->expects($this->once()) ->method('error') - ->with($badRequestException->getMessage(), ['exception' => $badRequestException]); + ->with('Unable to create calendar object from subscription {subscriptionId}', ['exception' => $badRequestException, 'subscriptionId' => '42', 'source' => 'webcal://foo.bar/bla2']); $refreshWebcalService->refreshSubscription('principals/users/testuser', 'sub123'); } @@ -324,10 +324,8 @@ class RefreshWebcalServiceTest extends TestCase { /** * @dataProvider runLocalURLDataProvider - * - * @param string $source */ - public function testRunLocalURL($source) { + public function testRunLocalURL(string $source) { $refreshWebcalService = new RefreshWebcalService( $this->caldavBackend, $this->clientService, @@ -361,14 +359,15 @@ class RefreshWebcalServiceTest extends TestCase { ->with('dav', 'webcalAllowLocalAccess', 'no') ->willReturn('no'); - $exception = new LocalServerException(); + $localServerException = new LocalServerException(); + $client->expects($this->once()) ->method('get') - ->willThrowException($exception); + ->willThrowException($localServerException); $this->logger->expects($this->once()) ->method('warning') - ->with($this->anything(), ['exception' => $exception]); + ->with("Subscription 42 was not refreshed because it violates local access rules", ['exception' => $localServerException]); $refreshWebcalService->refreshSubscription('principals/users/testuser', 'sub123'); } diff --git a/apps/dav/tests/unit/CardDAV/Activity/BackendTest.php b/apps/dav/tests/unit/CardDAV/Activity/BackendTest.php new file mode 100644 index 00000000000..dbc2c3550e7 --- /dev/null +++ b/apps/dav/tests/unit/CardDAV/Activity/BackendTest.php @@ -0,0 +1,529 @@ +<?php +/** + * @copyright Copyright (c) 2016 Joas Schilling <coding@schilljs.com> + * + * @author Christoph Wurst <christoph@winzerhof-wurst.at> + * @author Joas Schilling <coding@schilljs.com> + * @author Roeland Jago Douma <roeland@famdouma.nl> + * @author Thomas Citharel <nextcloud@tcit.fr> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +namespace OCA\DAV\Tests\unit\CardDAV\Activity; + +use OCA\DAV\CardDAV\Activity\Backend; +use OCA\DAV\CardDAV\Activity\Provider\Addressbook; +use OCA\DAV\CardDAV\Activity\Provider\Card; +use OCP\Activity\IEvent; +use OCP\Activity\IManager; +use OCP\App\IAppManager; +use OCP\IGroup; +use OCP\IGroupManager; +use OCP\IUser; +use OCP\IUserManager; +use OCP\IUserSession; +use PHPUnit\Framework\MockObject\MockObject; +use Test\TestCase; + +class BackendTest extends TestCase { + + /** @var IManager|MockObject */ + protected $activityManager; + + /** @var IGroupManager|MockObject */ + protected $groupManager; + + /** @var IUserSession|MockObject */ + protected $userSession; + + /** @var IAppManager|MockObject */ + protected $appManager; + + protected function setUp(): void { + parent::setUp(); + $this->activityManager = $this->createMock(IManager::class); + $this->groupManager = $this->createMock(IGroupManager::class); + $this->userSession = $this->createMock(IUserSession::class); + $this->appManager = $this->createMock(IAppManager::class); + $this->userManager = $this->createMock(IUserManager::class); + } + + /** + * @param array $methods + * @return Backend|MockObject + */ + protected function getBackend(array $methods = []) { + if (empty($methods)) { + return new Backend( + $this->activityManager, + $this->groupManager, + $this->userSession, + $this->appManager, + $this->userManager + ); + } else { + return $this->getMockBuilder(Backend::class) + ->setConstructorArgs([ + $this->activityManager, + $this->groupManager, + $this->userSession, + $this->appManager, + $this->userManager + ]) + ->onlyMethods($methods) + ->getMock(); + } + } + + public function dataCallTriggerAddressBookActivity(): array { + return [ + ['onAddressbookCreate', [['data']], Addressbook::SUBJECT_ADD, [['data'], [], []]], + ['onAddressbookUpdate', [['data'], ['shares'], ['changed-properties']], Addressbook::SUBJECT_UPDATE, [['data'], ['shares'], ['changed-properties']]], + ['onAddressbookDelete', [['data'], ['shares']], Addressbook::SUBJECT_DELETE, [['data'], ['shares'], []]], + ]; + } + + /** + * @dataProvider dataCallTriggerAddressBookActivity + */ + public function testCallTriggerAddressBookActivity(string $method, array $payload, string $expectedSubject, array $expectedPayload) { + $backend = $this->getBackend(['triggerAddressbookActivity']); + $backend->expects($this->once()) + ->method('triggerAddressbookActivity') + ->willReturnCallback(function () use ($expectedPayload, $expectedSubject) { + $arguments = func_get_args(); + $this->assertSame($expectedSubject, array_shift($arguments)); + $this->assertEquals($expectedPayload, $arguments); + }); + + call_user_func_array([$backend, $method], $payload); + } + + public function dataTriggerAddressBookActivity(): array { + return [ + // Add addressbook + [Addressbook::SUBJECT_ADD, [], [], [], '', '', null, []], + [Addressbook::SUBJECT_ADD, [ + 'principaluri' => 'principal/user/admin', + 'id' => 42, + 'uri' => 'this-uri', + '{DAV:}displayname' => 'Name of addressbook', + ], [], [], '', 'admin', null, ['admin']], + [Addressbook::SUBJECT_ADD, [ + 'principaluri' => 'principal/user/admin', + 'id' => 42, + 'uri' => 'this-uri', + '{DAV:}displayname' => 'Name of addressbook', + ], [], [], 'test2', 'test2', null, ['admin']], + + // Update addressbook + [Addressbook::SUBJECT_UPDATE, [], [], [], '', '', null, []], + // No visible change - owner only + [Addressbook::SUBJECT_UPDATE, [ + 'principaluri' => 'principal/user/admin', + 'id' => 42, + 'uri' => 'this-uri', + '{DAV:}displayname' => 'Name of addressbook', + ], ['shares'], [], '', 'admin', null, ['admin']], + // Visible change + [Addressbook::SUBJECT_UPDATE, [ + 'principaluri' => 'principal/user/admin', + 'id' => 42, + 'uri' => 'this-uri', + '{DAV:}displayname' => 'Name of addressbook', + ], ['shares'], ['{DAV:}displayname' => 'Name'], '', 'admin', ['user1'], ['user1', 'admin']], + [Addressbook::SUBJECT_UPDATE, [ + 'principaluri' => 'principal/user/admin', + 'id' => 42, + 'uri' => 'this-uri', + '{DAV:}displayname' => 'Name of addressbook', + ], ['shares'], ['{DAV:}displayname' => 'Name'], 'test2', 'test2', ['user1'], ['user1', 'admin']], + + // Delete addressbook + [Addressbook::SUBJECT_DELETE, [], [], [], '', '', null, []], + [Addressbook::SUBJECT_DELETE, [ + 'principaluri' => 'principal/user/admin', + 'id' => 42, + 'uri' => 'this-uri', + '{DAV:}displayname' => 'Name of addressbook', + ], ['shares'], [], '', 'admin', [], ['admin']], + [Addressbook::SUBJECT_DELETE, [ + 'principaluri' => 'principal/user/admin', + 'id' => 42, + 'uri' => 'this-uri', + '{DAV:}displayname' => 'Name of addressbook', + ], ['shares'], [], '', 'admin', ['user1'], ['user1', 'admin']], + [Addressbook::SUBJECT_DELETE, [ + 'principaluri' => 'principal/user/admin', + 'id' => 42, + 'uri' => 'this-uri', + '{DAV:}displayname' => 'Name of addressbook', + ], ['shares'], [], 'test2', 'test2', ['user1'], ['user1', 'admin']], + ]; + } + + /** + * @dataProvider dataTriggerAddressBookActivity + * @param string $action + * @param array $data + * @param array $shares + * @param array $changedProperties + * @param string $currentUser + * @param string $author + * @param string[]|null $shareUsers + * @param string[] $users + */ + public function testTriggerAddressBookActivity(string $action, array $data, array $shares, array $changedProperties, string $currentUser, string $author, ?array $shareUsers, array $users) { + $backend = $this->getBackend(['getUsersForShares']); + + if ($shareUsers === null) { + $backend->expects($this->never()) + ->method('getUsersForShares'); + } else { + $backend->expects($this->once()) + ->method('getUsersForShares') + ->with($shares) + ->willReturn($shareUsers); + } + + if ($author !== '') { + if ($currentUser !== '') { + $this->userSession->expects($this->once()) + ->method('getUser') + ->willReturn($this->getUserMock($currentUser)); + } else { + $this->userSession->expects($this->once()) + ->method('getUser') + ->willReturn(null); + } + + $event = $this->createMock(IEvent::class); + $this->activityManager->expects($this->once()) + ->method('generateEvent') + ->willReturn($event); + + $event->expects($this->once()) + ->method('setApp') + ->with('dav') + ->willReturnSelf(); + $event->expects($this->once()) + ->method('setObject') + ->with('addressbook', $data['id']) + ->willReturnSelf(); + $event->expects($this->once()) + ->method('setType') + ->with('addressbook') + ->willReturnSelf(); + $event->expects($this->once()) + ->method('setAuthor') + ->with($author) + ->willReturnSelf(); + + $this->userManager->expects($action === Addressbook::SUBJECT_DELETE ? $this->exactly(sizeof($users)) : $this->never()) + ->method('userExists') + ->willReturn(true); + + $event->expects($this->exactly(sizeof($users))) + ->method('setAffectedUser') + ->willReturnSelf(); + $event->expects($this->exactly(sizeof($users))) + ->method('setSubject') + ->willReturnSelf(); + $this->activityManager->expects($this->exactly(sizeof($users))) + ->method('publish') + ->with($event); + } else { + $this->activityManager->expects($this->never()) + ->method('generateEvent'); + } + + $this->invokePrivate($backend, 'triggerAddressbookActivity', [$action, $data, $shares, $changedProperties]); + } + + public function testNoAddressbookActivityCreatedForSystemAddressbook(): void { + $backend = $this->getBackend(); + $this->activityManager->expects($this->never()) + ->method('generateEvent'); + $this->assertEmpty($this->invokePrivate($backend, 'triggerAddressbookActivity', [Addressbook::SUBJECT_ADD, ['principaluri' => 'principals/system/system'], [], [], '', '', null, []])); + } + + public function testUserDeletionDoesNotCreateActivity() { + $backend = $this->getBackend(); + + $this->userManager->expects($this->once()) + ->method('userExists') + ->willReturn(false); + + $this->activityManager->expects($this->never()) + ->method('publish'); + + $this->invokePrivate($backend, 'triggerAddressbookActivity', [Addressbook::SUBJECT_DELETE, [ + 'principaluri' => 'principal/user/admin', + 'id' => 42, + 'uri' => 'this-uri', + '{DAV:}displayname' => 'Name of addressbook', + ], [], []]); + } + + public function dataTriggerCardActivity(): array { + $cardData = "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 3.4.8//EN\r\nUID:test-user\r\nFN:test-user\r\nN:test-user;;;;\r\nEND:VCARD\r\n\r\n"; + + return [ + // Add card + [Card::SUBJECT_ADD, [], [], [], '', '', null, []], + [Card::SUBJECT_ADD, [ + 'principaluri' => 'principal/user/admin', + 'id' => 42, + 'uri' => 'this-uri', + '{DAV:}displayname' => 'Name of addressbook', + ], [], [ + 'carddata' => $cardData + ], '', 'admin', [], ['admin']], + [Card::SUBJECT_ADD, [ + 'principaluri' => 'principal/user/admin', + 'id' => 42, + 'uri' => 'this-uri', + '{DAV:}displayname' => 'Name of addressbook', + ], [], ['carddata' => $cardData], 'test2', 'test2', [], ['admin']], + + // Update card + [Card::SUBJECT_UPDATE, [], [], [], '', '', null, []], + // No visible change - owner only + [Card::SUBJECT_UPDATE, [ + 'principaluri' => 'principal/user/admin', + 'id' => 42, + 'uri' => 'this-uri', + '{DAV:}displayname' => 'Name of addressbook', + ], ['shares'], ['carddata' => $cardData], '', 'admin', [], ['admin']], + // Visible change + [Card::SUBJECT_UPDATE, [ + 'principaluri' => 'principal/user/admin', + 'id' => 42, + 'uri' => 'this-uri', + '{DAV:}displayname' => 'Name of addressbook', + ], ['shares'], ['carddata' => $cardData], '', 'admin', ['user1'], ['user1', 'admin']], + [Card::SUBJECT_UPDATE, [ + 'principaluri' => 'principal/user/admin', + 'id' => 42, + 'uri' => 'this-uri', + '{DAV:}displayname' => 'Name of addressbook', + ], ['shares'], ['carddata' => $cardData], 'test2', 'test2', ['user1'], ['user1', 'admin']], + + // Delete card + [Card::SUBJECT_DELETE, [], [], ['carddata' => $cardData], '', '', null, []], + [Card::SUBJECT_DELETE, [ + 'principaluri' => 'principal/user/admin', + 'id' => 42, + 'uri' => 'this-uri', + '{DAV:}displayname' => 'Name of addressbook', + ], ['shares'], ['carddata' => $cardData], '', 'admin', [], ['admin']], + [Card::SUBJECT_DELETE, [ + 'principaluri' => 'principal/user/admin', + 'id' => 42, + 'uri' => 'this-uri', + '{DAV:}displayname' => 'Name of addressbook', + ], ['shares'], ['carddata' => $cardData], '', 'admin', ['user1'], ['user1', 'admin']], + [Card::SUBJECT_DELETE, [ + 'principaluri' => 'principal/user/admin', + 'id' => 42, + 'uri' => 'this-uri', + '{DAV:}displayname' => 'Name of addressbook', + ], ['shares'], ['carddata' => $cardData], 'test2', 'test2', ['user1'], ['user1', 'admin']], + ]; + } + + /** + * @dataProvider dataTriggerCardActivity + * @param string $action + * @param array $addressBookData + * @param array $shares + * @param array $cardData + * @param string $currentUser + * @param string $author + * @param string[]|null $shareUsers + * @param string[] $users + */ + public function testTriggerCardActivity(string $action, array $addressBookData, array $shares, array $cardData, string $currentUser, string $author, ?array $shareUsers, array $users) { + $backend = $this->getBackend(['getUsersForShares']); + + if ($shareUsers === null) { + $backend->expects($this->never()) + ->method('getUsersForShares'); + } else { + $backend->expects($this->once()) + ->method('getUsersForShares') + ->with($shares) + ->willReturn($shareUsers); + } + + if ($author !== '') { + if ($currentUser !== '') { + $this->userSession->expects($this->once()) + ->method('getUser') + ->willReturn($this->getUserMock($currentUser)); + } else { + $this->userSession->expects($this->once()) + ->method('getUser') + ->willReturn(null); + } + + $event = $this->createMock(IEvent::class); + $this->activityManager->expects($this->once()) + ->method('generateEvent') + ->willReturn($event); + + $event->expects($this->once()) + ->method('setApp') + ->with('dav') + ->willReturnSelf(); + $event->expects($this->once()) + ->method('setObject') + ->with('addressbook', $addressBookData['id']) + ->willReturnSelf(); + $event->expects($this->once()) + ->method('setType') + ->with('card') + ->willReturnSelf(); + $event->expects($this->once()) + ->method('setAuthor') + ->with($author) + ->willReturnSelf(); + + $event->expects($this->exactly(sizeof($users))) + ->method('setAffectedUser') + ->willReturnSelf(); + $event->expects($this->exactly(sizeof($users))) + ->method('setSubject') + ->willReturnSelf(); + $this->activityManager->expects($this->exactly(sizeof($users))) + ->method('publish') + ->with($event); + } else { + $this->activityManager->expects($this->never()) + ->method('generateEvent'); + } + + $this->invokePrivate($backend, 'triggerCardActivity', [$action, $addressBookData, $shares, $cardData]); + } + + public function testNoCardActivityCreatedForSystemAddressbook(): void { + $backend = $this->getBackend(); + $this->activityManager->expects($this->never()) + ->method('generateEvent'); + $this->assertEmpty($this->invokePrivate($backend, 'triggerCardActivity', [Card::SUBJECT_UPDATE, ['principaluri' => 'principals/system/system'], [], []])); + } + + public function dataGetUsersForShares(): array { + return [ + [ + [], + [], + [], + ], + [ + [ + ['{http://owncloud.org/ns}principal' => 'principal/users/user1'], + ['{http://owncloud.org/ns}principal' => 'principal/users/user2'], + ['{http://owncloud.org/ns}principal' => 'principal/users/user2'], + ['{http://owncloud.org/ns}principal' => 'principal/users/user2'], + ['{http://owncloud.org/ns}principal' => 'principal/users/user3'], + ], + [], + ['user1', 'user2', 'user3'], + ], + [ + [ + ['{http://owncloud.org/ns}principal' => 'principal/users/user1'], + ['{http://owncloud.org/ns}principal' => 'principal/users/user2'], + ['{http://owncloud.org/ns}principal' => 'principal/users/user2'], + ['{http://owncloud.org/ns}principal' => 'principal/groups/group2'], + ['{http://owncloud.org/ns}principal' => 'principal/groups/group3'], + ], + ['group2' => null, 'group3' => null], + ['user1', 'user2'], + ], + [ + [ + ['{http://owncloud.org/ns}principal' => 'principal/users/user1'], + ['{http://owncloud.org/ns}principal' => 'principal/users/user2'], + ['{http://owncloud.org/ns}principal' => 'principal/users/user2'], + ['{http://owncloud.org/ns}principal' => 'principal/groups/group2'], + ['{http://owncloud.org/ns}principal' => 'principal/groups/group3'], + ], + ['group2' => ['user1', 'user2', 'user3'], 'group3' => ['user2', 'user3', 'user4']], + ['user1', 'user2', 'user3', 'user4'], + ], + ]; + } + + /** + * @dataProvider dataGetUsersForShares + * @param array $shares + * @param array $groups + * @param array $expected + */ + public function testGetUsersForShares(array $shares, array $groups, array $expected) { + $backend = $this->getBackend(); + + $getGroups = []; + foreach ($groups as $gid => $members) { + if ($members === null) { + $getGroups[] = [$gid, null]; + continue; + } + + $group = $this->createMock(IGroup::class); + $group->expects($this->once()) + ->method('getUsers') + ->willReturn($this->getUsers($members)); + + $getGroups[] = [$gid, $group]; + } + + $this->groupManager->expects($this->exactly(sizeof($getGroups))) + ->method('get') + ->willReturnMap($getGroups); + + $users = $this->invokePrivate($backend, 'getUsersForShares', [$shares]); + sort($users); + $this->assertEquals($expected, $users); + } + + /** + * @param string[] $users + * @return IUser[]|MockObject[] + */ + protected function getUsers(array $users): array { + $list = []; + foreach ($users as $user) { + $list[] = $this->getUserMock($user); + } + return $list; + } + + /** + * @param string $uid + * @return IUser|MockObject + */ + protected function getUserMock(string $uid) { + $user = $this->createMock(IUser::class); + $user->expects($this->once()) + ->method('getUID') + ->willReturn($uid); + return $user; + } +} diff --git a/apps/dav/tests/unit/CardDAV/BirthdayServiceTest.php b/apps/dav/tests/unit/CardDAV/BirthdayServiceTest.php index bb45c88b10d..188b82843cd 100644 --- a/apps/dav/tests/unit/CardDAV/BirthdayServiceTest.php +++ b/apps/dav/tests/unit/CardDAV/BirthdayServiceTest.php @@ -34,6 +34,7 @@ use OCP\IConfig; use OCP\IDBConnection; use OCP\IL10N; use Sabre\VObject\Component\VCalendar; +use Sabre\VObject\Property\ICalendar\Duration; use Sabre\VObject\Reader; use Test\TestCase; @@ -82,11 +83,12 @@ class BirthdayServiceTest extends TestCase { * @param string $expectedFieldType * @param string $expectedUnknownYear * @param string $expectedOriginalYear + * @param string|null $expectedReminder * @param string | null $data */ - public function testBuildBirthdayFromContact($expectedSummary, $expectedDTStart, $expectedFieldType, $expectedUnknownYear, $expectedOriginalYear, $data, $fieldType, $prefix, $supports4Bytes) { + public function testBuildBirthdayFromContact($expectedSummary, $expectedDTStart, $expectedFieldType, $expectedUnknownYear, $expectedOriginalYear, $expectedReminder, $data, $fieldType, $prefix, $supports4Bytes, $configuredReminder) { $this->dbConnection->method('supports4ByteText')->willReturn($supports4Bytes); - $cal = $this->service->buildDateFromContact($data, $fieldType, $prefix); + $cal = $this->service->buildDateFromContact($data, $fieldType, $prefix, $configuredReminder); if ($expectedSummary === null) { $this->assertNull($cal); @@ -104,6 +106,11 @@ class BirthdayServiceTest extends TestCase { $this->assertEquals($expectedOriginalYear, $cal->VEVENT->{'X-NEXTCLOUD-BC-YEAR'}->getValue()); } + if ($expectedReminder) { + $this->assertEquals($expectedReminder, $cal->VEVENT->VALARM->TRIGGER->getValue()); + $this->assertEquals('DURATION', $cal->VEVENT->VALARM->TRIGGER->getValueType()); + } + $this->assertEquals('TRANSPARENT', $cal->VEVENT->TRANSP->getValue()); } } @@ -227,10 +234,13 @@ class BirthdayServiceTest extends TestCase { ->with('dav', 'generateBirthdayCalendar', 'yes') ->willReturn('yes'); - $this->config->expects($this->once()) + $this->config->expects($this->exactly(2)) ->method('getUserValue') - ->with('user01', 'dav', 'generateBirthdayCalendar', 'yes') - ->willReturn('yes'); + ->withConsecutive( + ['user01', 'dav', 'generateBirthdayCalendar', 'yes'], + ['user01', 'dav', 'birthdayCalendarReminderOffset', 'PT9H'], + ) + ->willReturnOnConsecutiveCalls('yes', 'PT9H'); $this->cardDav->expects($this->once())->method('getAddressBookById') ->with(666) @@ -402,29 +412,32 @@ class BirthdayServiceTest extends TestCase { public function providesVCards() { return [ - // $expectedSummary, $expectedDTStart, $expectedFieldType, $expectedUnknownYear, $expectedOriginalYear, $data, $fieldType, $prefix, $supports4Byte - [null, null, null, null, null, 'yasfewf', '', '', true], - [null, null, null, null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nEND:VCARD\r\n", 'BDAY', '', true], - [null, null, null, null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:\r\nEND:VCARD\r\n", 'BDAY', '', true], - [null, null, null, null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:someday\r\nEND:VCARD\r\n", 'BDAY', '', true], - ['🎂 12345 (1900)', '19700101', 'BDAY', '0', '1900', "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:19000101\r\nEND:VCARD\r\n", 'BDAY', '', true], - ['🎂 12345 (1900)', '19701231', 'BDAY', '0', '1900', "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:19001231\r\nEND:VCARD\r\n", 'BDAY', '', true], - ['Death of 12345 (1900)', '19701231', 'DEATHDATE', '0', '1900', "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nDEATHDATE:19001231\r\nEND:VCARD\r\n", 'DEATHDATE', '-death', true], - ['Death of 12345 (1900)', '19701231', 'DEATHDATE', '0', '1900', "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nDEATHDATE:19001231\r\nEND:VCARD\r\n", 'DEATHDATE', '-death', false], - ['💍 12345 (1900)', '19701231', 'ANNIVERSARY', '0', '1900', "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nANNIVERSARY:19001231\r\nEND:VCARD\r\n", 'ANNIVERSARY', '-anniversary', true], - ['12345 (⚭1900)', '19701231', 'ANNIVERSARY', '0', '1900', "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nANNIVERSARY:19001231\r\nEND:VCARD\r\n", 'ANNIVERSARY', '-anniversary', false], - ['🎂 12345', '19701231', 'BDAY', '1', null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:--1231\r\nEND:VCARD\r\n", 'BDAY', '', true], - ['🎂 12345', '19701231', 'BDAY', '1', null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY;X-APPLE-OMIT-YEAR=1604:16041231\r\nEND:VCARD\r\n", 'BDAY', '', true], - [null, null, null, null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:;VALUE=text:circa 1800\r\nEND:VCARD\r\n", 'BDAY', '', true], - [null, null, null, null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nN:12345;;;;\r\nBDAY:20031231\r\nEND:VCARD\r\n", 'BDAY', '', true], - ['🎂 12345 (900)', '19701231', 'BDAY', '0', '900', "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:09001231\r\nEND:VCARD\r\n", 'BDAY', '', true], - ['12345 (*1900)', '19700101', 'BDAY', '0', '1900', "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:19000101\r\nEND:VCARD\r\n", 'BDAY', '', false], - ['12345 (*1900)', '19701231', 'BDAY', '0', '1900', "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:19001231\r\nEND:VCARD\r\n", 'BDAY', '', false], - ['12345 *', '19701231', 'BDAY', '1', null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:--1231\r\nEND:VCARD\r\n", 'BDAY', '', false], - ['12345 *', '19701231', 'BDAY', '1', null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY;X-APPLE-OMIT-YEAR=1604:16041231\r\nEND:VCARD\r\n", 'BDAY', '', false], - [null, null, null, null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:;VALUE=text:circa 1800\r\nEND:VCARD\r\n", 'BDAY', '', false], - [null, null, null, null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nN:12345;;;;\r\nBDAY:20031231\r\nEND:VCARD\r\n", 'BDAY', '', false], - ['12345 (*900)', '19701231', 'BDAY', '0', '900', "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:09001231\r\nEND:VCARD\r\n", 'BDAY', '', false], + // $expectedSummary, $expectedDTStart, $expectedFieldType, $expectedUnknownYear, $expectedOriginalYear, $expectedReminder, $data, $fieldType, $prefix, $supports4Byte, $configuredReminder + [null, null, null, null, null, null, 'yasfewf', '', '', true, null], + [null, null, null, null, null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nEND:VCARD\r\n", 'BDAY', '', true, null], + [null, null, null, null, null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:\r\nEND:VCARD\r\n", 'BDAY', '', true, null], + [null, null, null, null, null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:someday\r\nEND:VCARD\r\n", 'BDAY', '', true, null], + ['🎂 12345 (1900)', '19700101', 'BDAY', '0', '1900', null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:19000101\r\nEND:VCARD\r\n", 'BDAY', '', true, null], + ['🎂 12345 (1900)', '19701231', 'BDAY', '0', '1900', null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:19001231\r\nEND:VCARD\r\n", 'BDAY', '', true, null], + ['Death of 12345 (1900)', '19701231', 'DEATHDATE', '0', '1900', null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nDEATHDATE:19001231\r\nEND:VCARD\r\n", 'DEATHDATE', '-death', true, null], + ['Death of 12345 (1900)', '19701231', 'DEATHDATE', '0', '1900', null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nDEATHDATE:19001231\r\nEND:VCARD\r\n", 'DEATHDATE', '-death', false, null], + ['💍 12345 (1900)', '19701231', 'ANNIVERSARY', '0', '1900', null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nANNIVERSARY:19001231\r\nEND:VCARD\r\n", 'ANNIVERSARY', '-anniversary', true, null], + ['12345 (⚭1900)', '19701231', 'ANNIVERSARY', '0', '1900', null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nANNIVERSARY:19001231\r\nEND:VCARD\r\n", 'ANNIVERSARY', '-anniversary', false, null], + ['🎂 12345', '19701231', 'BDAY', '1', null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:--1231\r\nEND:VCARD\r\n", 'BDAY', '', true, null], + ['🎂 12345', '19701231', 'BDAY', '1', null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY;X-APPLE-OMIT-YEAR=1604:16041231\r\nEND:VCARD\r\n", 'BDAY', '', true, null], + [null, null, null, null, null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:;VALUE=text:circa 1800\r\nEND:VCARD\r\n", 'BDAY', '', true, null], + [null, null, null, null, null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nN:12345;;;;\r\nBDAY:20031231\r\nEND:VCARD\r\n", 'BDAY', '', true, null], + ['🎂 12345 (900)', '19701231', 'BDAY', '0', '900', null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:09001231\r\nEND:VCARD\r\n", 'BDAY', '', true, null], + ['12345 (*1900)', '19700101', 'BDAY', '0', '1900', null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:19000101\r\nEND:VCARD\r\n", 'BDAY', '', false, null], + ['12345 (*1900)', '19701231', 'BDAY', '0', '1900', null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:19001231\r\nEND:VCARD\r\n", 'BDAY', '', false, null], + ['12345 *', '19701231', 'BDAY', '1', null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:--1231\r\nEND:VCARD\r\n", 'BDAY', '', false, null], + ['12345 *', '19701231', 'BDAY', '1', null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY;X-APPLE-OMIT-YEAR=1604:16041231\r\nEND:VCARD\r\n", 'BDAY', '', false, null], + [null, null, null, null, null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:;VALUE=text:circa 1800\r\nEND:VCARD\r\n", 'BDAY', '', false, null], + [null, null, null, null, null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nN:12345;;;;\r\nBDAY:20031231\r\nEND:VCARD\r\n", 'BDAY', '', false, null], + ['12345 (*900)', '19701231', 'BDAY', '0', '900', null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:09001231\r\nEND:VCARD\r\n", 'BDAY', '', false, null], + ['12345 (*1900)', '19701231', 'BDAY', '0', '1900', 'PT9H', "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:19001231\r\nEND:VCARD\r\n", 'BDAY', '', false, 'PT9H'], + ['12345 (*1900)', '19701231', 'BDAY', '0', '1900', '-PT15H', "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:19001231\r\nEND:VCARD\r\n", 'BDAY', '', false, '-PT15H'], + ['12345 (*1900)', '19701231', 'BDAY', '0', '1900', '-P6DT15H', "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:19001231\r\nEND:VCARD\r\n", 'BDAY', '', false, '-P6DT15H'], ]; } } diff --git a/apps/dav/tests/unit/CardDAV/CardDavBackendTest.php b/apps/dav/tests/unit/CardDAV/CardDavBackendTest.php index 7eda691d199..b468a2a65ae 100644 --- a/apps/dav/tests/unit/CardDAV/CardDavBackendTest.php +++ b/apps/dav/tests/unit/CardDAV/CardDavBackendTest.php @@ -13,6 +13,7 @@ * @author Morris Jobke <hey@morrisjobke.de> * @author Robin Appelman <robin@icewind.nl> * @author Roeland Jago Douma <roeland@famdouma.nl> + * @author Thomas Citharel <nextcloud@tcit.fr> * @author Thomas Müller <thomas.mueller@tmit.eu> * * @license AGPL-3.0 @@ -37,6 +38,7 @@ use OCA\DAV\CalDAV\Proxy\ProxyMapper; use OCA\DAV\CardDAV\AddressBook; use OCA\DAV\CardDAV\CardDavBackend; use OCA\DAV\Connector\Sabre\Principal; +use OCP\Accounts\IAccountManager; use OCP\App\IAppManager; use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\EventDispatcher\IEventDispatcher; @@ -52,8 +54,6 @@ use Sabre\DAV\Exception\BadRequest; use Sabre\DAV\PropPatch; use Sabre\VObject\Component\VCard; use Sabre\VObject\Property\Text; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; -use Symfony\Component\EventDispatcher\GenericEvent; use Test\TestCase; /** @@ -77,10 +77,7 @@ class CardDavBackendTest extends TestCase { /** @var IGroupManager|\PHPUnit\Framework\MockObject\MockObject */ private $groupManager; - /** @var EventDispatcherInterface|\PHPUnit\Framework\MockObject\MockObject */ - private $legacyDispatcher; - - /** @var IEventDispatcher|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IEventDispatcher|MockObject */ private $dispatcher; /** @var IDBConnection */ @@ -136,6 +133,7 @@ class CardDavBackendTest extends TestCase { ->setConstructorArgs([ $this->userManager, $this->groupManager, + $this->createMock(IAccountManager::class), $this->createMock(ShareManager::class), $this->createMock(IUserSession::class), $this->createMock(IAppManager::class), @@ -155,11 +153,10 @@ class CardDavBackendTest extends TestCase { ->withAnyParameters() ->willReturn([self::UNIT_TEST_GROUP]); $this->dispatcher = $this->createMock(IEventDispatcher::class); - $this->legacyDispatcher = $this->createMock(EventDispatcherInterface::class); $this->db = \OC::$server->getDatabaseConnection(); - $this->backend = new CardDavBackend($this->db, $this->principal, $this->userManager, $this->groupManager, $this->dispatcher, $this->legacyDispatcher); + $this->backend = new CardDavBackend($this->db, $this->principal, $this->userManager, $this->groupManager, $this->dispatcher); // start every test with a empty cards_properties and cards table $query = $this->db->getQueryBuilder(); $query->delete('cards_properties')->execute(); @@ -249,8 +246,8 @@ class CardDavBackendTest extends TestCase { /** @var CardDavBackend | \PHPUnit\Framework\MockObject\MockObject $backend */ $backend = $this->getMockBuilder(CardDavBackend::class) - ->setConstructorArgs([$this->db, $this->principal, $this->userManager, $this->groupManager, $this->dispatcher, $this->legacyDispatcher]) - ->setMethods(['updateProperties', 'purgeProperties'])->getMock(); + ->setConstructorArgs([$this->db, $this->principal, $this->userManager, $this->groupManager, $this->dispatcher]) + ->onlyMethods(['updateProperties', 'purgeProperties'])->getMock(); // create a new address book $backend->createAddressBook(self::UNIT_TEST_USER, 'Example', []); @@ -264,13 +261,9 @@ class CardDavBackendTest extends TestCase { $backend->expects($this->at(1))->method('updateProperties')->with($bookId, $uri, $this->vcardTest1); // Expect event - $this->legacyDispatcher->expects($this->at(0)) - ->method('dispatch') - ->with('\OCA\DAV\CardDAV\CardDavBackend::createCard', $this->callback(function (GenericEvent $e) use ($bookId, $uri) { - return $e->getArgument('addressBookId') === $bookId && - $e->getArgument('cardUri') === $uri && - $e->getArgument('cardData') === $this->vcardTest0; - })); + $this->dispatcher + ->expects($this->exactly(3)) + ->method('dispatchTyped'); // create a card $backend->createCard($bookId, $uri, $this->vcardTest0); @@ -290,28 +283,11 @@ class CardDavBackendTest extends TestCase { $this->assertArrayHasKey('size', $card); $this->assertEquals($this->vcardTest0, $card['carddata']); - // Expect event - $this->legacyDispatcher->expects($this->at(0)) - ->method('dispatch') - ->with('\OCA\DAV\CardDAV\CardDavBackend::updateCard', $this->callback(function (GenericEvent $e) use ($bookId, $uri) { - return $e->getArgument('addressBookId') === $bookId && - $e->getArgument('cardUri') === $uri && - $e->getArgument('cardData') === $this->vcardTest1; - })); - // update the card $backend->updateCard($bookId, $uri, $this->vcardTest1); $card = $backend->getCard($bookId, $uri); $this->assertEquals($this->vcardTest1, $card['carddata']); - // Expect event - $this->legacyDispatcher->expects($this->at(0)) - ->method('dispatch') - ->with('\OCA\DAV\CardDAV\CardDavBackend::deleteCard', $this->callback(function (GenericEvent $e) use ($bookId, $uri) { - return $e->getArgument('addressBookId') === $bookId && - $e->getArgument('cardUri') === $uri; - })); - // delete the card $backend->expects($this->once())->method('purgeProperties')->with($bookId, $card['id']); $backend->deleteCard($bookId, $uri); @@ -321,7 +297,7 @@ class CardDavBackendTest extends TestCase { public function testMultiCard() { $this->backend = $this->getMockBuilder(CardDavBackend::class) - ->setConstructorArgs([$this->db, $this->principal, $this->userManager, $this->groupManager, $this->dispatcher, $this->legacyDispatcher]) + ->setConstructorArgs([$this->db, $this->principal, $this->userManager, $this->groupManager, $this->dispatcher]) ->setMethods(['updateProperties'])->getMock(); // create a new address book @@ -374,8 +350,8 @@ class CardDavBackendTest extends TestCase { public function testMultipleUIDOnDifferentAddressbooks() { $this->backend = $this->getMockBuilder(CardDavBackend::class) - ->setConstructorArgs([$this->db, $this->principal, $this->userManager, $this->groupManager, $this->dispatcher, $this->legacyDispatcher]) - ->setMethods(['updateProperties'])->getMock(); + ->setConstructorArgs([$this->db, $this->principal, $this->userManager, $this->groupManager, $this->dispatcher]) + ->onlyMethods(['updateProperties'])->getMock(); // create 2 new address books $this->backend->createAddressBook(self::UNIT_TEST_USER, 'Example', []); @@ -396,7 +372,7 @@ class CardDavBackendTest extends TestCase { public function testMultipleUIDDenied() { $this->backend = $this->getMockBuilder(CardDavBackend::class) - ->setConstructorArgs([$this->db, $this->principal, $this->userManager, $this->groupManager, $this->dispatcher, $this->legacyDispatcher]) + ->setConstructorArgs([$this->db, $this->principal, $this->userManager, $this->groupManager, $this->dispatcher]) ->setMethods(['updateProperties'])->getMock(); // create a new address book @@ -417,7 +393,7 @@ class CardDavBackendTest extends TestCase { public function testNoValidUID() { $this->backend = $this->getMockBuilder(CardDavBackend::class) - ->setConstructorArgs([$this->db, $this->principal, $this->userManager, $this->groupManager, $this->dispatcher, $this->legacyDispatcher]) + ->setConstructorArgs([$this->db, $this->principal, $this->userManager, $this->groupManager, $this->dispatcher]) ->setMethods(['updateProperties'])->getMock(); // create a new address book @@ -434,8 +410,8 @@ class CardDavBackendTest extends TestCase { public function testDeleteWithoutCard() { $this->backend = $this->getMockBuilder(CardDavBackend::class) - ->setConstructorArgs([$this->db, $this->principal, $this->userManager, $this->groupManager, $this->dispatcher, $this->legacyDispatcher]) - ->setMethods([ + ->setConstructorArgs([$this->db, $this->principal, $this->userManager, $this->groupManager, $this->dispatcher]) + ->onlyMethods([ 'getCardId', 'addChange', 'purgeProperties', @@ -474,7 +450,7 @@ class CardDavBackendTest extends TestCase { public function testSyncSupport() { $this->backend = $this->getMockBuilder(CardDavBackend::class) - ->setConstructorArgs([$this->db, $this->principal, $this->userManager, $this->groupManager, $this->dispatcher, $this->legacyDispatcher]) + ->setConstructorArgs([$this->db, $this->principal, $this->userManager, $this->groupManager, $this->dispatcher]) ->setMethods(['updateProperties'])->getMock(); // create a new address book @@ -540,8 +516,8 @@ class CardDavBackendTest extends TestCase { $cardId = 2; $backend = $this->getMockBuilder(CardDavBackend::class) - ->setConstructorArgs([$this->db, $this->principal, $this->userManager, $this->groupManager, $this->dispatcher, $this->legacyDispatcher]) - ->setMethods(['getCardId'])->getMock(); + ->setConstructorArgs([$this->db, $this->principal, $this->userManager, $this->groupManager, $this->dispatcher]) + ->onlyMethods(['getCardId'])->getMock(); $backend->expects($this->any())->method('getCardId')->willReturn($cardId); @@ -630,8 +606,8 @@ class CardDavBackendTest extends TestCase { $qResult->closeCursor(); $this->assertSame(1, count($result)); - $this->assertSame(1 ,(int)$result[0]['addressbookid']); - $this->assertSame(2 ,(int)$result[0]['cardid']); + $this->assertSame(1, (int)$result[0]['addressbookid']); + $this->assertSame(2, (int)$result[0]['cardid']); } public function testGetCardId() { diff --git a/apps/dav/tests/unit/Comments/CommentsNodeTest.php b/apps/dav/tests/unit/Comments/CommentsNodeTest.php index ea3a1952e45..54d410b609a 100644 --- a/apps/dav/tests/unit/Comments/CommentsNodeTest.php +++ b/apps/dav/tests/unit/Comments/CommentsNodeTest.php @@ -405,6 +405,7 @@ class CommentsNodeTest extends \Test\TestCase { $ns . 'referenceId' => 'ref', $ns . 'isUnread' => null, $ns . 'reactions' => [], + $ns . 'expireDate' => new \DateTime('2016-01-12 19:00:00'), ]; $this->commentsManager->expects($this->exactly(2)) @@ -474,6 +475,10 @@ class CommentsNodeTest extends \Test\TestCase { ->method('getReferenceId') ->willReturn($expected[$ns . 'referenceId']); + $this->comment->expects($this->once()) + ->method('getExpireDate') + ->willReturn($expected[$ns . 'expireDate']); + $user = $this->getMockBuilder(IUser::class) ->disableOriginalConstructor() ->getMock(); diff --git a/apps/dav/tests/unit/Connector/Sabre/ExceptionLoggerPluginTest.php b/apps/dav/tests/unit/Connector/Sabre/ExceptionLoggerPluginTest.php index 3627a177969..a553c0687e0 100644 --- a/apps/dav/tests/unit/Connector/Sabre/ExceptionLoggerPluginTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/ExceptionLoggerPluginTest.php @@ -32,6 +32,7 @@ use OC\Log; use OC\SystemConfig; use OCA\DAV\Connector\Sabre\Exception\InvalidPath; use OCA\DAV\Connector\Sabre\ExceptionLoggerPlugin; +use OCA\DAV\Exception\ServerMaintenanceMode; use Psr\Log\LoggerInterface; use Sabre\DAV\Exception\NotFound; use Sabre\DAV\Exception\ServiceUnavailable; @@ -84,8 +85,10 @@ class ExceptionLoggerPluginTest extends TestCase { public function providesExceptions() { return [ ['debug', new NotFound()], - ['debug', new ServiceUnavailable('System in maintenance mode.')], - ['critical', new ServiceUnavailable('Upgrade needed')], + ['debug', new ServerMaintenanceMode('System is in maintenance mode.')], + // Faking a translation + ['debug', new ServerMaintenanceMode('Syst3m 1s 1n m41nt3n4nc3 m0d3.')], + ['debug', new ServerMaintenanceMode('Upgrade needed')], ['critical', new InvalidPath('This path leads to nowhere')] ]; } diff --git a/apps/dav/tests/unit/Connector/Sabre/FileTest.php b/apps/dav/tests/unit/Connector/Sabre/FileTest.php index 9870a62845c..6a954378d02 100644 --- a/apps/dav/tests/unit/Connector/Sabre/FileTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/FileTest.php @@ -316,7 +316,7 @@ class FileTest extends TestCase { * @param string $viewRoot root to use for the view * @param null|Request $request the HTTP request * - * @return null|string of the PUT operaiton which is usually the etag + * @return null|string of the PUT operation which is usually the etag */ private function doPut($path, $viewRoot = null, Request $request = null) { $view = \OC\Files\Filesystem::getView(); diff --git a/apps/dav/tests/unit/Connector/Sabre/NodeTest.php b/apps/dav/tests/unit/Connector/Sabre/NodeTest.php index 00fd0ebd8aa..3ac5b8f841a 100644 --- a/apps/dav/tests/unit/Connector/Sabre/NodeTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/NodeTest.php @@ -29,8 +29,11 @@ namespace OCA\DAV\Tests\unit\Connector\Sabre; use OC\Files\FileInfo; use OC\Files\View; +use OC\Share20\ShareAttributes; +use OCA\Files_Sharing\SharedStorage; use OCP\Files\Mount\IMountPoint; use OCP\Files\Storage; +use OCP\Share\IAttributes; use OCP\Share\IManager; use OCP\Share\IShare; @@ -169,6 +172,65 @@ class NodeTest extends \Test\TestCase { $this->assertEquals($expected, $node->getSharePermissions($user)); } + public function testShareAttributes() { + $storage = $this->getMockBuilder(SharedStorage::class) + ->disableOriginalConstructor() + ->setMethods(['getShare']) + ->getMock(); + + $shareManager = $this->getMockBuilder(IManager::class)->disableOriginalConstructor()->getMock(); + $share = $this->getMockBuilder(IShare::class)->disableOriginalConstructor()->getMock(); + + $storage->expects($this->once()) + ->method('getShare') + ->willReturn($share); + + $attributes = new ShareAttributes(); + $attributes->setAttribute('permissions', 'download', false); + + $share->expects($this->once())->method('getAttributes')->willReturn($attributes); + + $info = $this->getMockBuilder(FileInfo::class) + ->disableOriginalConstructor() + ->setMethods(['getStorage', 'getType']) + ->getMock(); + + $info->method('getStorage')->willReturn($storage); + $info->method('getType')->willReturn(FileInfo::TYPE_FOLDER); + + $view = $this->getMockBuilder(View::class) + ->disableOriginalConstructor() + ->getMock(); + + $node = new \OCA\DAV\Connector\Sabre\File($view, $info); + $this->invokePrivate($node, 'shareManager', [$shareManager]); + $this->assertEquals($attributes->toArray(), $node->getShareAttributes()); + } + + public function testShareAttributesNonShare() { + $storage = $this->getMockBuilder(Storage::class) + ->disableOriginalConstructor() + ->getMock(); + + $shareManager = $this->getMockBuilder(IManager::class)->disableOriginalConstructor()->getMock(); + + $info = $this->getMockBuilder(FileInfo::class) + ->disableOriginalConstructor() + ->setMethods(['getStorage', 'getType']) + ->getMock(); + + $info->method('getStorage')->willReturn($storage); + $info->method('getType')->willReturn(FileInfo::TYPE_FOLDER); + + $view = $this->getMockBuilder(View::class) + ->disableOriginalConstructor() + ->getMock(); + + $node = new \OCA\DAV\Connector\Sabre\File($view, $info); + $this->invokePrivate($node, 'shareManager', [$shareManager]); + $this->assertEquals([], $node->getShareAttributes()); + } + public function sanitizeMtimeProvider() { return [ [123456789, 123456789], diff --git a/apps/dav/tests/unit/Connector/Sabre/PrincipalTest.php b/apps/dav/tests/unit/Connector/Sabre/PrincipalTest.php index 86413e4a366..444c267b509 100644 --- a/apps/dav/tests/unit/Connector/Sabre/PrincipalTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/PrincipalTest.php @@ -34,6 +34,10 @@ use OC\User\User; use OCA\DAV\CalDAV\Proxy\Proxy; use OCA\DAV\CalDAV\Proxy\ProxyMapper; use OCA\DAV\Connector\Sabre\Principal; +use OCP\Accounts\IAccount; +use OCP\Accounts\IAccountManager; +use OCP\Accounts\IAccountProperty; +use OCP\Accounts\IAccountPropertyCollection; use OCP\App\IAppManager; use OCP\IConfig; use OCP\IGroup; @@ -59,6 +63,9 @@ class PrincipalTest extends TestCase { /** @var IGroupManager | MockObject */ private $groupManager; + /** @var IAccountManager|MockObject */ + private $accountManager; + /** @var IManager | MockObject */ private $shareManager; @@ -81,6 +88,7 @@ class PrincipalTest extends TestCase { protected function setUp(): void { $this->userManager = $this->createMock(IUserManager::class); $this->groupManager = $this->createMock(IGroupManager::class); + $this->accountManager = $this->createMock(IAccountManager::class); $this->shareManager = $this->createMock(IManager::class); $this->userSession = $this->createMock(IUserSession::class); $this->appManager = $this->createMock(IAppManager::class); @@ -92,6 +100,7 @@ class PrincipalTest extends TestCase { $this->connector = new Principal( $this->userManager, $this->groupManager, + $this->accountManager, $this->shareManager, $this->userSession, $this->appManager, @@ -143,6 +152,45 @@ class PrincipalTest extends TestCase { ->withConsecutive([$fooUser], [$barUser]) ->willReturnOnConsecutiveCalls('de', 'en'); + $fooAccountPropertyCollection = $this->createMock(IAccountPropertyCollection::class); + $fooAccountPropertyCollection->expects($this->once()) + ->method('getProperties') + ->with() + ->willReturn([]); + $fooAccount = $this->createMock(IAccount::class); + $fooAccount->expects($this->once()) + ->method('getPropertyCollection') + ->with(IAccountManager::COLLECTION_EMAIL) + ->willReturn($fooAccountPropertyCollection); + + $emailPropertyOne = $this->createMock(IAccountProperty::class); + $emailPropertyOne->expects($this->once()) + ->method('getValue') + ->with() + ->willReturn('alias@nextcloud.com'); + $emailPropertyTwo = $this->createMock(IAccountProperty::class); + $emailPropertyTwo->expects($this->once()) + ->method('getValue') + ->with() + ->willReturn('alias2@nextcloud.com'); + + $barAccountPropertyCollection = $this->createMock(IAccountPropertyCollection::class); + $barAccountPropertyCollection->expects($this->once()) + ->method('getProperties') + ->with() + ->willReturn([$emailPropertyOne, $emailPropertyTwo]); + $barAccount = $this->createMock(IAccount::class); + $barAccount->expects($this->once()) + ->method('getPropertyCollection') + ->with(IAccountManager::COLLECTION_EMAIL) + ->willReturn($barAccountPropertyCollection); + + $this->accountManager + ->expects($this->exactly(2)) + ->method('getAccount') + ->withConsecutive([$fooUser], [$barUser]) + ->willReturnOnConsecutiveCalls($fooAccount, $barAccount); + $expectedResponse = [ 0 => [ 'uri' => 'principals/users/foo', @@ -156,6 +204,7 @@ class PrincipalTest extends TestCase { '{urn:ietf:params:xml:ns:caldav}calendar-user-type' => 'INDIVIDUAL', '{http://nextcloud.com/ns}language' => 'en', '{http://sabredav.org/ns}email-address' => 'bar@nextcloud.com', + '{DAV:}alternate-URI-set' => ['mailto:alias@nextcloud.com', 'mailto:alias2@nextcloud.com'] ] ]; $response = $this->connector->getPrincipalsByPrefix('principals/users'); diff --git a/apps/dav/tests/unit/Controller/DirectControllerTest.php b/apps/dav/tests/unit/Controller/DirectControllerTest.php index 00771e7f7a6..fe6d4ea8f24 100644 --- a/apps/dav/tests/unit/Controller/DirectControllerTest.php +++ b/apps/dav/tests/unit/Controller/DirectControllerTest.php @@ -34,11 +34,12 @@ use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\OCS\OCSBadRequestException; use OCP\AppFramework\OCS\OCSNotFoundException; use OCP\AppFramework\Utility\ITimeFactory; +use OCP\EventDispatcher\IEventDispatcher; use OCP\Files\File; use OCP\Files\Folder; use OCP\Files\IRootFolder; use OCP\IRequest; -use OCP\IURLGenerator; +use OCP\IUrlGenerator; use OCP\Security\ISecureRandom; use Test\TestCase; @@ -56,11 +57,13 @@ class DirectControllerTest extends TestCase { /** @var ITimeFactory|\PHPUnit\Framework\MockObject\MockObject */ private $timeFactory; - /** @var IURLGenerator|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IUrlGenerator|\PHPUnit\Framework\MockObject\MockObject */ private $urlGenerator; - /** @var DirectController */ - private $controller; + /** @var IEventDispatcher|\PHPUnit\Framework\MockObject\MockObject */ + private $eventDispatcher; + + private DirectController $controller; protected function setUp(): void { parent::setUp(); @@ -69,7 +72,8 @@ class DirectControllerTest extends TestCase { $this->directMapper = $this->createMock(DirectMapper::class); $this->random = $this->createMock(ISecureRandom::class); $this->timeFactory = $this->createMock(ITimeFactory::class); - $this->urlGenerator = $this->createMock(IURLGenerator::class); + $this->urlGenerator = $this->createMock(IUrlGenerator::class); + $this->eventDispatcher = $this->createMock(IEventDispatcher::class); $this->controller = new DirectController( 'dav', @@ -79,11 +83,12 @@ class DirectControllerTest extends TestCase { $this->directMapper, $this->random, $this->timeFactory, - $this->urlGenerator + $this->urlGenerator, + $this->eventDispatcher ); } - public function testGetUrlNonExistingFileId() { + public function testGetUrlNonExistingFileId(): void { $userFolder = $this->createMock(Folder::class); $this->rootFolder->method('getUserFolder') ->with('awesomeUser') @@ -97,7 +102,7 @@ class DirectControllerTest extends TestCase { $this->controller->getUrl(101); } - public function testGetUrlForFolder() { + public function testGetUrlForFolder(): void { $userFolder = $this->createMock(Folder::class); $this->rootFolder->method('getUserFolder') ->with('awesomeUser') @@ -113,7 +118,7 @@ class DirectControllerTest extends TestCase { $this->controller->getUrl(101); } - public function testGetUrlValid() { + public function testGetUrlValid(): void { $userFolder = $this->createMock(Folder::class); $this->rootFolder->method('getUserFolder') ->with('awesomeUser') @@ -128,6 +133,9 @@ class DirectControllerTest extends TestCase { ->with(101) ->willReturn([$file]); + $userFolder->method('getRelativePath') + ->willReturn('/path'); + $this->random->method('generate') ->with( 60, diff --git a/apps/dav/tests/unit/Controller/InvitationResponseControllerTest.php b/apps/dav/tests/unit/Controller/InvitationResponseControllerTest.php index cd3269d657c..576fde2d4af 100644 --- a/apps/dav/tests/unit/Controller/InvitationResponseControllerTest.php +++ b/apps/dav/tests/unit/Controller/InvitationResponseControllerTest.php @@ -37,6 +37,7 @@ use OCP\AppFramework\Utility\ITimeFactory; use OCP\DB\IResult; use OCP\DB\QueryBuilder\IExpressionBuilder; use OCP\DB\QueryBuilder\IQueryBuilder; +use OCP\DB\QueryBuilder\IQueryFunction; use OCP\IDBConnection; use OCP\IRequest; use Sabre\VObject\ITip\Message; @@ -477,10 +478,11 @@ EOF; ->with(\PDO::FETCH_ASSOC) ->willReturn($return); + $function = $this->createMock(IQueryFunction::class); $expr->expects($this->once()) ->method('eq') ->with('token', 'namedParameterToken') - ->willReturn('EQ STATEMENT'); + ->willReturn($function); $this->dbConnection->expects($this->once()) ->method('getQueryBuilder') @@ -497,7 +499,7 @@ EOF; ->willReturn($queryBuilder); $queryBuilder->expects($this->at(4)) ->method('where') - ->with('EQ STATEMENT') + ->with($function) ->willReturn($queryBuilder); $queryBuilder->expects($this->at(5)) ->method('execute') diff --git a/apps/dav/tests/unit/DAV/ViewOnlyPluginTest.php b/apps/dav/tests/unit/DAV/ViewOnlyPluginTest.php new file mode 100644 index 00000000000..f86a60fb4bf --- /dev/null +++ b/apps/dav/tests/unit/DAV/ViewOnlyPluginTest.php @@ -0,0 +1,117 @@ +<?php +/** + * @author Piotr Mrowczynski piotr@owncloud.com + * + * @copyright Copyright (c) 2019, ownCloud GmbH + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ +namespace OCA\DAV\Tests\unit\DAV; + +use OCA\DAV\DAV\ViewOnlyPlugin; +use OCA\Files_Sharing\SharedStorage; +use OCA\DAV\Connector\Sabre\File as DavFile; +use OCP\Files\File; +use OCP\Files\Storage\IStorage; +use OCP\Share\IAttributes; +use OCP\Share\IShare; +use Psr\Log\LoggerInterface; +use Sabre\DAV\Server; +use Sabre\DAV\Tree; +use Test\TestCase; +use Sabre\HTTP\RequestInterface; +use OCA\DAV\Connector\Sabre\Exception\Forbidden; + +class ViewOnlyPluginTest extends TestCase { + + private ViewOnlyPlugin $plugin; + /** @var Tree | \PHPUnit\Framework\MockObject\MockObject */ + private $tree; + /** @var RequestInterface | \PHPUnit\Framework\MockObject\MockObject */ + private $request; + + public function setUp(): void { + $this->plugin = new ViewOnlyPlugin( + $this->createMock(LoggerInterface::class) + ); + $this->request = $this->createMock(RequestInterface::class); + $this->tree = $this->createMock(Tree::class); + + $server = $this->createMock(Server::class); + $server->tree = $this->tree; + + $this->plugin->initialize($server); + } + + public function testCanGetNonDav(): void { + $this->request->expects($this->once())->method('getPath')->willReturn('files/test/target'); + $this->tree->method('getNodeForPath')->willReturn(null); + + $this->assertTrue($this->plugin->checkViewOnly($this->request)); + } + + public function testCanGetNonShared(): void { + $this->request->expects($this->once())->method('getPath')->willReturn('files/test/target'); + $davNode = $this->createMock(DavFile::class); + $this->tree->method('getNodeForPath')->willReturn($davNode); + + $file = $this->createMock(File::class); + $davNode->method('getNode')->willReturn($file); + + $storage = $this->createMock(IStorage::class); + $file->method('getStorage')->willReturn($storage); + $storage->method('instanceOfStorage')->with(SharedStorage::class)->willReturn(false); + + $this->assertTrue($this->plugin->checkViewOnly($this->request)); + } + + public function providesDataForCanGet(): array { + return [ + // has attribute permissions-download enabled - can get file + [ $this->createMock(File::class), true, true], + // has no attribute permissions-download - can get file + [ $this->createMock(File::class), null, true], + // has attribute permissions-download disabled- cannot get the file + [ $this->createMock(File::class), false, false], + ]; + } + + /** + * @dataProvider providesDataForCanGet + */ + public function testCanGet(File $nodeInfo, ?bool $attrEnabled, bool $expectCanDownloadFile): void { + $this->request->expects($this->once())->method('getPath')->willReturn('files/test/target'); + + $davNode = $this->createMock(DavFile::class); + $this->tree->method('getNodeForPath')->willReturn($davNode); + + $davNode->method('getNode')->willReturn($nodeInfo); + + $storage = $this->createMock(SharedStorage::class); + $share = $this->createMock(IShare::class); + $nodeInfo->method('getStorage')->willReturn($storage); + $storage->method('instanceOfStorage')->with(SharedStorage::class)->willReturn(true); + $storage->method('getShare')->willReturn($share); + + $extAttr = $this->createMock(IAttributes::class); + $share->method('getAttributes')->willReturn($extAttr); + $extAttr->method('getAttribute')->with('permissions', 'download')->willReturn($attrEnabled); + + if (!$expectCanDownloadFile) { + $this->expectException(Forbidden::class); + } + $this->plugin->checkViewOnly($this->request); + } +} |