Compare commits

...

208 Commits

Author SHA1 Message Date
Marcel Klehr 934ad51959 fix(FileSequence): Check whether temp dir still exists before using it
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
2025-12-15 15:21:50 +01:00
Marcel Klehr b15e294a6e Merge pull request #57004 from nextcloud/fix/taskprocessing-increase-text-limit
fix(TaskProcessing): Increase EShapeType::Text limit to 256_000 KB
2025-12-15 12:48:53 +01:00
Kate db530d1eae Merge pull request #56921 from nextcloud/fix-caching-routes-by-users-with-an-active-session 2025-12-15 10:53:04 +01:00
Kate 9350a6798c Merge pull request #57084 from nextcloud/carl/fix-32-bits-job 2025-12-15 09:23:06 +01:00
Carl Schwan 8034de84aa fix(jobs): Fix 32 bits jobs
Specifying the type to int force a convertion from string to int which
fails on 32 bits for snowflake ids.

Signed-off-by: Carl Schwan <carl.schwan@nextcloud.com>
2025-12-15 08:41:26 +01:00
Marcel Klehr 0745731806 fix(TaskProcessing): Increase EShapeType::Text limit to 256_000 KB
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
2025-12-15 07:53:26 +01:00
Nextcloud bot b7ef5d5855 fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-12-15 00:13:26 +00:00
Nextcloud bot 0580014b73 fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-12-14 00:13:27 +00:00
Nextcloud bot 48f7dac9b9 fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-12-13 00:13:29 +00:00
Ferdinand Thiessen 0fe787558e Merge pull request #57010 from nextcloud/fix/breaking-points
fix(css): correct boundaries of breaking points
2025-12-12 21:38:21 +01:00
Daniel d957f6190c Merge pull request #57017 from nextcloud/fix/do-not-truncate-birthday-year-to-1970
fix: do not truncate birth year to 1970
2025-12-12 16:41:03 +01:00
Daniel Calviño Sánchez 51ed61bb4a fix: Fix caching routes by users with an active session
When a user has an active session only the apps that are enabled for the
user are initially loaded. In order to cache the routes the routes for
all apps are loaded, but routes defined in routes.php are taken into
account only if the app was already loaded. Therefore, when the routes
were cached in a request by a user with an active session only the
routes for apps enabled for that user were cached, and those routes were
used by any other user, independently of which apps they had access to.
To solve that now all the enabled apps are explicitly loaded before
caching the routes.

Note that this did not affect routes defined using annotations on the
controller files; in that case the loaded routes do not depend on the
previously loaded apps, as it explicitly checks all the enabled apps.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2025-12-12 16:10:20 +01:00
Daniel Calviño Sánchez de7ddb6e1c test: Fix recording app state when admin is not the current user
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2025-12-12 16:10:20 +01:00
Daniel Calviño Sánchez 0ba2f5e537 Revert "fix(CachingRouter): Disable cache for findMatchingRoute"
This reverts commit 90948f5096.

It temporary disabled cache for routes until an actual fix was added,
which is done in the following commits.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2025-12-12 16:06:47 +01:00
Kate 400ade585d Merge pull request #57042 from nextcloud/fix/restrict-enumeration-userid 2025-12-12 15:52:07 +01:00
Julius Knorr a45f4b0cdc fix: Fix setting name inconsistency between backend and frontend
Signed-off-by: Julius Knorr <jus@bitgrid.net>
2025-12-12 13:08:34 +01:00
Joas Schilling 0edaff9426 Merge pull request #57031 from nextcloud/automated/noid/master-update-code-signing-crl
[master] fix(security): Update code signing revocation list
2025-12-12 07:46:15 +01:00
Ferdinand Thiessen d9d8449340 Merge pull request #57012 from nextcloud/refactor/oauth2-to-vue3
refactor(oauth2): migrate to Typescript and Vue 3
2025-12-12 04:44:56 +01:00
nextcloud-command 2c62e695ba fix(security): Update code signing revocation list
Signed-off-by: GitHub <noreply@github.com>
2025-12-12 02:43:46 +00:00
Nextcloud bot 09dfa965b4 fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-12-12 00:13:50 +00:00
Ferdinand Thiessen ad23c85d0c chore: compile assets
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-12-12 00:44:42 +01:00
Ferdinand Thiessen 6a570c0133 refactor(oauth2): migrate to Typescript and Vue 3
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-12-12 00:42:15 +01:00
Ferdinand Thiessen 6d7a7f3146 Merge pull request #56942 from nextcloud/refactor/federatedfilessharing-vue3
refactor(federatedfilesharing): migrate to Typescript and Vue 3
2025-12-12 00:25:42 +01:00
SebastianKrupinski 7c266d9f23 fix: do not truncate birth year to 1970
Signed-off-by: SebastianKrupinski <krupinskis05@gmail.com>
2025-12-11 13:59:28 -05:00
Ferdinand Thiessen e1b9723428 chore: compile assets
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-12-11 19:46:47 +01:00
Ferdinand Thiessen 9edcc864fe test: use istanbul coverage provider
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-12-11 19:46:47 +01:00
Ferdinand Thiessen 14f52a2303 refactor(federatedfilesharing): migrate to Typescript and Vue 3
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-12-11 19:08:44 +01:00
Louis 3efb1d80e9 Merge pull request #56646 from nextcloud/fix/no_double_admin_delegations
fix(admin-delegation): Prevent delegation to group if delegation already
2025-12-11 17:45:12 +01:00
John Molakvoæ 52e3762045 Merge pull request #56743 from nextcloud/chore/files-4-0-0 2025-12-11 17:36:51 +01:00
Ferdinand Thiessen 2eaf18dd49 chore: compile assets
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-12-11 14:31:10 +01:00
Ferdinand Thiessen a95d781989 fix(css): correct boundaries of breaking points
We mixed the logic of breaking points (when to break),
this makes it consistent:
Mobile breaking point is 1024px, so it is applied to width < 1024 and starting with 1024 its "normal".

So we consistently have:
width < 512px: small mobile
512 <= width < 1024px: mobile
width >= 1024px: normal

Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-12-11 14:28:15 +01:00
Stephan Orbaugh 282341a8d6 Merge pull request #55738 from nextcloud/carl/cleanup-preview-command
fix(preview-cleanup): Also delete previews stored in the oc_previews table
2025-12-11 14:07:50 +01:00
Stephan Orbaugh a7a64de6e6 Merge pull request #54441 from nextcloud/fix/directoryAsINodeByPath
Add INodeByPath to Directory
2025-12-11 14:07:23 +01:00
skjnldsv 2c4b5c6b68 chore: compile assets
Signed-off-by: skjnldsv <skjnldsv@protonmail.com>
2025-12-11 12:56:02 +01:00
skjnldsv 7aa6a74b31 chore: update @nextcloud/vue
Signed-off-by: skjnldsv <skjnldsv@protonmail.com>
2025-12-11 12:44:17 +01:00
skjnldsv 0eadf1753d fix(settings): adjust systemtags handling and tests
Signed-off-by: skjnldsv <skjnldsv@protonmail.com>
2025-12-11 12:44:17 +01:00
skjnldsv 492bdb7010 chore: update @nextcloud/files to 4.0.0
Signed-off-by: skjnldsv <skjnldsv@protonmail.com>
2025-12-11 12:44:16 +01:00
F. E Noel Nfebe d15feb4ba6 Merge pull request #56977 from nextcloud/fix/federated-share-display-in-shared-with-you
fix(files_sharing): Normalize dir type to folder for federated shares
2025-12-11 11:31:34 +01:00
nextcloud-command b92b3e7940 chore(assets): Recompile assets
Signed-off-by: nextcloud-command <nextcloud-command@users.noreply.github.com>
2025-12-11 09:57:48 +00:00
nfebe 13df65850e fix(files_sharing): Normalize dir type to folder for federated shares
The backend returns type 'dir' for folders (from FileInfo::TYPE_FOLDER),
but the frontend expects 'folder'. This mismatch caused federated shared
folders to display incorrectly as files in the "Shared with you" view.

Signed-off-by: nfebe <fenn25.fn@gmail.com>
2025-12-11 10:49:41 +01:00
Arthur Schiwon f892437210 Merge pull request #56982 from nextcloud/bugfix/noid/check-comment-object
fix(comments): Check comment object
2025-12-11 09:37:43 +01:00
Joas Schilling 69e6b6a483 fix(comments): Check comment object
Signed-off-by: Joas Schilling <coding@schilljs.com>
2025-12-11 07:55:55 +01:00
github-actions[bot] 0fd888da09 Merge pull request #56980 from nextcloud/dependabot/npm_and_yarn/build/frontend-legacy/nextcloud/logger-3.0.3
build(deps): bump @nextcloud/logger from 3.0.2 to 3.0.3 in /build/frontend-legacy
2025-12-11 01:21:22 +00:00
github-actions[bot] 986af30032 Merge pull request #56981 from nextcloud/dependabot/npm_and_yarn/build/frontend-legacy/sass-1.95.1
build(deps-dev): bump sass from 1.94.2 to 1.95.1 in /build/frontend-legacy
2025-12-11 00:17:54 +00:00
Nextcloud bot c4c247d535 fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-12-11 00:13:43 +00:00
nextcloud-command aeca72538a chore(assets): Recompile assets
Signed-off-by: nextcloud-command <nextcloud-command@users.noreply.github.com>
2025-12-10 23:50:34 +00:00
dependabot[bot] f839d7825a build(deps-dev): bump sass in /build/frontend-legacy
Bumps [sass](https://github.com/sass/dart-sass) from 1.94.2 to 1.95.1.
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.94.2...1.95.1)

---
updated-dependencies:
- dependency-name: sass
  dependency-version: 1.95.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-10 23:27:49 +00:00
dependabot[bot] 5682ff4479 build(deps): bump @nextcloud/logger in /build/frontend-legacy
Bumps [@nextcloud/logger](https://github.com/nextcloud-libraries/nextcloud-logger) from 3.0.2 to 3.0.3.
- [Release notes](https://github.com/nextcloud-libraries/nextcloud-logger/releases)
- [Changelog](https://github.com/nextcloud-libraries/nextcloud-logger/blob/main/CHANGELOG.md)
- [Commits](https://github.com/nextcloud-libraries/nextcloud-logger/compare/v3.0.2...v3.0.3)

---
updated-dependencies:
- dependency-name: "@nextcloud/logger"
  dependency-version: 3.0.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-10 23:27:38 +00:00
Elizabeth Danzberger 070ec61759 Merge pull request #56722 from nextcloud/fix/deduplicate-templates
fix(templates): deduplicate provider templates
2025-12-10 18:21:40 -05:00
Elizabeth Danzberger 3a89c18888 fix(templates): deduplicate provider templates
Signed-off-by: Elizabeth Danzberger <elizabeth@elzody.dev>
2025-12-10 16:06:21 -05:00
F. E Noel Nfebe 186b12b718 Merge pull request #56620 from nextcloud/fix/filter-interaction-issues
fix(unified-search): prevent provider disabling on content filter apply
2025-12-10 20:07:46 +01:00
github-actions[bot] a86a2a070e Merge pull request #56890 from nextcloud/dependabot/npm_and_yarn/build/frontend-legacy/libphonenumber-js-1.12.31
build(deps): bump libphonenumber-js from 1.12.29 to 1.12.31 in /build/frontend-legacy
2025-12-10 18:52:47 +00:00
github-actions[bot] 8f82ad358a Merge pull request #56946 from nextcloud/dependabot/composer/vendor-bin/rector/rector/rector-2.2.14
build(deps-dev): bump rector/rector from 2.2.9 to 2.2.14 in /vendor-bin/rector
2025-12-10 19:42:19 +01:00
github-actions[bot] 9af153f5b7 Merge pull request #56950 from nextcloud/dependabot/npm_and_yarn/sass-1.95.1
build(deps-dev): bump sass from 1.94.2 to 1.95.1
2025-12-10 19:41:51 +01:00
nextcloud-command 4a5bacc8c7 chore(assets): Recompile assets
Signed-off-by: nextcloud-command <nextcloud-command@users.noreply.github.com>
2025-12-10 18:00:26 +00:00
Andy Scherzinger d50828aa92 Merge pull request #56887 from nextcloud/dependabot/npm_and_yarn/vitest-afa725de22
build(deps-dev): bump the vitest group across 2 directories with 2 updates
2025-12-10 18:57:16 +01:00
github-actions[bot] 258670de61 Merge pull request #56748 from nextcloud/dependabot/composer/bamarni/composer-bin-plugin-1.8.3
build(deps-dev): bump bamarni/composer-bin-plugin from 1.8.2 to 1.8.3
2025-12-10 17:56:30 +00:00
dependabot[bot] 7f76a6d4aa build(deps): bump libphonenumber-js in /build/frontend-legacy
Bumps [libphonenumber-js](https://gitlab.com/catamphetamine/libphonenumber-js) from 1.12.29 to 1.12.31.
- [Changelog](https://gitlab.com/catamphetamine/libphonenumber-js/blob/master/CHANGELOG.md)
- [Commits](https://gitlab.com/catamphetamine/libphonenumber-js/compare/v1.12.29...v1.12.31)

---
updated-dependencies:
- dependency-name: libphonenumber-js
  dependency-version: 1.12.31
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-10 18:51:25 +01:00
github-actions[bot] edbcb6af6f Merge pull request #56956 from nextcloud/dependabot/npm_and_yarn/vite-1f75bea169
build(deps-dev): bump the vite group across 2 directories with 1 update
2025-12-10 18:50:20 +01:00
F. E Noel Nfebe b07801a2b5 Merge pull request #56652 from nextcloud/fix/federated-share-external-filter
fix(sharing): allow federated shares to non-trusted servers
2025-12-10 18:41:05 +01:00
Salvatore Martire 871262d6f6 chore: update 3rdparty
Signed-off-by: Salvatore Martire <4652631+salmart-dev@users.noreply.github.com>
2025-12-10 18:30:44 +01:00
Salvatore Martire 2a4ee2df9f fix: add INodeByPath to Directory
Signed-off-by: Salvatore Martire <4652631+salmart-dev@users.noreply.github.com>
2025-12-10 18:30:44 +01:00
Salvatore Martire aaf07ab73e Merge pull request #55072 from nextcloud/feature/54562/pathSpecificFSSetup
Introduces support for mount providers that can provide a partial list of mount points based on a path and the information related to mounts present in that path.
2025-12-10 18:28:15 +01:00
nextcloud-command 5de1d46be4 chore(assets): Recompile assets
Signed-off-by: nextcloud-command <nextcloud-command@users.noreply.github.com>
2025-12-10 17:20:09 +00:00
nextcloud-command cf56d6325a chore(assets): Recompile assets
Signed-off-by: nextcloud-command <nextcloud-command@users.noreply.github.com>
2025-12-10 17:13:01 +00:00
nfebe 08382282ea fix(sharing): allow federated shares to non-trusted servers
When `showFederatedSharesToTrustedServersAsInternal` is enabled, the
trusted server filter was incorrectly applied to both internal and
external sharing sections. This prevented users from sharing with
federated users on non-trusted servers via the external share UI.

The filter now only applies to the internal section, allowing
non-trusted federated shares to appear in the external section.

Fixes: https://github.com/nextcloud/server/issues/56622

Signed-off-by: nfebe <fenn25.fn@gmail.com>
2025-12-10 17:41:11 +01:00
nfebe f035ff3d3a fix(unified-search): Separate filtered and unfiltered results
Show results from providers that don't support active content filters
(date/person) in a separate "Additional results" section with a note
explaining that some filters may have been ignored.

Changes:
- Add computed properties to separate filtered/unfiltered results
- Track filter compatibility using baseProvider for searchFrom providers
- Deduplicate results by resourceUrl across sections
- Skip in-folder results when at root to avoid duplicating Files results
- Fix providerIsCompatibleWithFilters to check correct filter properties
- Add styling for the unfiltered results section

Signed-off-by: nfebe <fenn25.fn@gmail.com>
2025-12-10 17:30:32 +01:00
nfebe 61ebc6e251 fix(unified-search): prevent provider disabling on content filter apply
When date range or person filters were applied, providers that didn't
support these filters were automatically disabled in the UI. This made
the in-folder filter appear auto-applied and prevented users from
searching non-compatible providers.

Remove automatic provider disabling logic from updateDateFilter(),
applyPersonFilter(), and removeFilter(). Content filters now apply only
to compatible providers via existing compatibility checks while keeping
all providers available for selection.

Signed-off-by: nfebe <fenn25.fn@gmail.com>
2025-12-10 17:30:32 +01:00
dependabot[bot] 6bde5db7da build(deps-dev): bump bamarni/composer-bin-plugin from 1.8.2 to 1.8.3
Bumps [bamarni/composer-bin-plugin](https://github.com/bamarni/composer-bin-plugin) from 1.8.2 to 1.8.3.
- [Release notes](https://github.com/bamarni/composer-bin-plugin/releases)
- [Commits](https://github.com/bamarni/composer-bin-plugin/compare/1.8.2...1.8.3)

---
updated-dependencies:
- dependency-name: bamarni/composer-bin-plugin
  dependency-version: 1.8.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-10 17:13:00 +01:00
Salvatore Martire d14a032220 feat: implement support for authoritative mount providers
Signed-off-by: Salvatore Martire <4652631+salmart-dev@users.noreply.github.com>
2025-12-10 16:05:27 +01:00
Salvatore Martire fcdb28e4a3 feat: add IPartialMountProvider to support authoritative mounts
IMountProviders implementing this interface will be able to take
advantage of authoritative mounts.

The function `getMountsFromMountPoints` will receive the path that
the provider is asked to set-up and an array of IMountProviderArgs
providing information regarding the stored mount points and the
file cache data for the related root. The mount provider should verify
the validity of the mounts and return IMountPoints related to them.

Signed-off-by: Salvatore Martire <4652631+salmart-dev@users.noreply.github.com>
2025-12-10 16:05:27 +01:00
Salvatore Martire 9b519b4679 refactor: simplify code
replace array_reduce + array_merge with array_merge(...)
replace conditional assignment with ??=

Signed-off-by: Salvatore Martire <4652631+salmart-dev@users.noreply.github.com>
2025-12-10 16:05:27 +01:00
Salvatore Martire f47a586cdd docs: update comments
Signed-off-by: Salvatore Martire <4652631+salmart-dev@users.noreply.github.com>
2025-12-10 16:05:27 +01:00
Daniel ac4e82d2a5 Merge pull request #56925 from nextcloud/fix/dav/escape-summary-description-location
fix(dav): handle HTML in CalDAV invitations
2025-12-10 15:09:16 +01:00
Misha M.-Kupriyanov 770ad6249e fix(admin-delegation): Prevent delegation to group if delegation already exist
Signed-off-by: Misha M.-Kupriyanov <kupriyanov@strato.de>
2025-12-10 15:08:53 +01:00
nextcloud-command 161e59929a chore(assets): Recompile assets
Signed-off-by: nextcloud-command <nextcloud-command@users.noreply.github.com>
2025-12-10 13:29:31 +00:00
Carl Schwan 247b66c5ee fix(preview-cleanup): Also delete previews stored in the oc_previews table
Signed-off-by: Carl Schwan <carl.schwan@nextcloud.com>
2025-12-10 13:49:24 +01:00
Christoph Wurst dac8818102 fix(dav): handle HTML in CalDAV invitations
Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
2025-12-10 12:51:18 +01:00
dependabot[bot] 08b39e2585 build(deps-dev): bump the vite group across 2 directories with 1 update
Bumps the vite group with 1 update in the / directory: [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite).
Bumps the vite group with 1 update in the /build/frontend-legacy directory: [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite).


Updates `vite` from 7.2.4 to 7.2.7
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v7.2.7/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v7.2.7/packages/vite)

Updates `vite` from 7.2.4 to 7.2.7
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v7.2.7/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v7.2.7/packages/vite)

Updates `vite` from 7.2.4 to 7.2.7
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v7.2.7/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v7.2.7/packages/vite)

Updates `vite` from 7.2.4 to 7.2.7
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v7.2.7/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v7.2.7/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 7.2.7
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: vite
- dependency-name: vite
  dependency-version: 7.2.7
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: vite
- dependency-name: vite
  dependency-version: 7.2.7
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: vite
- dependency-name: vite
  dependency-version: 7.2.7
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: vite
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-10 10:53:40 +00:00
dependabot[bot] 24c0f4b06d build(deps-dev): bump the vitest group across 2 directories with 2 updates
Bumps the vitest group with 1 update in the / directory: [@vitest/coverage-v8](https://github.com/vitest-dev/vitest/tree/HEAD/packages/coverage-v8).
Bumps the vitest group with 1 update in the /build/frontend-legacy directory: [@vitest/coverage-v8](https://github.com/vitest-dev/vitest/tree/HEAD/packages/coverage-v8).


Updates `@vitest/coverage-v8` from 4.0.14 to 4.0.15
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.15/packages/coverage-v8)

Updates `vitest` from 4.0.14 to 4.0.15
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.15/packages/vitest)

Updates `@vitest/coverage-v8` from 4.0.14 to 4.0.15
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.15/packages/coverage-v8)

Updates `vitest` from 4.0.14 to 4.0.15
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.15/packages/vitest)

---
updated-dependencies:
- dependency-name: "@vitest/coverage-v8"
  dependency-version: 4.0.15
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: vitest
- dependency-name: vitest
  dependency-version: 4.0.15
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: vitest
- dependency-name: "@vitest/coverage-v8"
  dependency-version: 4.0.15
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: vitest
- dependency-name: vitest
  dependency-version: 4.0.15
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: vitest
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-10 10:52:33 +00:00
dependabot[bot] 077cb3ebba build(deps-dev): bump sass from 1.94.2 to 1.95.1
Bumps [sass](https://github.com/sass/dart-sass) from 1.94.2 to 1.95.1.
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.94.2...1.95.1)

---
updated-dependencies:
- dependency-name: sass
  dependency-version: 1.95.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-10 10:51:34 +00:00
dependabot[bot] 3c809eaceb build(deps-dev): bump rector/rector in /vendor-bin/rector
Bumps [rector/rector](https://github.com/rectorphp/rector) from 2.2.9 to 2.2.14.
- [Release notes](https://github.com/rectorphp/rector/releases)
- [Commits](https://github.com/rectorphp/rector/compare/2.2.9...2.2.14)

---
updated-dependencies:
- dependency-name: rector/rector
  dependency-version: 2.2.14
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-10 10:50:45 +00:00
Ferdinand Thiessen 496404de56 Merge pull request #56718 from nextcloud/chore/move-behat-to-vendor-bin
chore: move behat dependencies to vendor-bin
2025-12-10 11:49:42 +01:00
Joas Schilling da1dd481e9 Merge pull request #56900 from nextcloud/fix/noid/allow-macos-on-ci
fix: Allow installation on macOS CI
2025-12-10 11:39:21 +01:00
Nextcloud bot f3c56f051a fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-12-10 00:13:59 +00:00
Ferdinand Thiessen e0e2d0fd2e chore: drop usage of -integration docker image
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-12-10 01:13:50 +01:00
Ferdinand Thiessen 65135bba31 chore: move behat dependencies to vendor-bin
So we do not have 3 locatations to look for PHP dependencies.

Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-12-10 01:13:50 +01:00
Sebastian Krupinski 75edec9d6c Merge pull request #56784 from nextcloud/fix/calendar-subscription-memory-exhaustion
fix: calendar subscription memory exhaustion
2025-12-09 13:08:24 -05:00
SebastianKrupinski 1a0535aa75 fix: calendar subscription memory exhaustion
Signed-off-by: SebastianKrupinski <krupinskis05@gmail.com>
2025-12-09 12:36:16 -05:00
Sebastian Krupinski 4185dfb599 Merge pull request #55415 from nextcloud/fix/issue-legal-footer
fix: legal footer on public page
2025-12-09 12:05:35 -05:00
SebastianKrupinski 162ebfaf3c fix: legal footer on public page
Signed-off-by: SebastianKrupinski <krupinskis05@gmail.com>
2025-12-09 11:21:03 -05:00
Kate 6277ecf480 Merge pull request #56862 from abhinavohri/56609 2025-12-09 16:02:18 +01:00
Abhinav Ohri f78e2a33ea test(settings): add missing logger parameter to MailSettingsController test
Signed-off-by: Abhinav Ohri <abhinavohri13@gmail.com>
2025-12-09 18:34:29 +05:30
Marcel Klehr f967134f58 Merge pull request #56928 from nextcloud/fix/taskprocessing-ocr
fix(TaskProcessing): Adjust OCR task type to allow for multiple files and pdfs
2025-12-09 13:52:57 +01:00
Andy Scherzinger 71c2e94123 Merge pull request #54436 from nextcloud/s3-signed-url
perf(s3): Provide direct pre-signed download link
2025-12-09 12:38:20 +01:00
Carl Schwan b6313f68d3 perf(s3): Expose pre-signed urls for S3
This is faster than going back to nextcloud to download the files.

This is an opt-in setting that can be enabled by setting
use_presigned_url in the object store config.

Additionally add support for the proxy config which is needed in a
docker setup. See https://github.com/juliusknorr/nextcloud-docker-dev/pull/431

Signed-off-by: Carl Schwan <carl.schwan@nextcloud.com>
2025-12-09 11:21:35 +01:00
Benjamin Gaussorgues d343207b25 Merge pull request #56926 from nextcloud/fix/CachingRouter/disable-cache-find-matching 2025-12-09 10:18:58 +01:00
Marcel Klehr 25044f82ae fix(TaskProcessing): Adjust OCR task type to allow for multiple files and pdfs
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
2025-12-09 09:21:33 +01:00
provokateurin 90948f5096 fix(CachingRouter): Disable cache for findMatchingRoute
Signed-off-by: provokateurin <kate@provokateurin.de>
2025-12-09 09:16:01 +01:00
Nextcloud bot 65d008b40c fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-12-09 00:13:32 +00:00
Daniel b7b4a3a6d7 Merge pull request #56908 from nextcloud/feat/tasktype-ocr
feat(TaskProcessing): Add OCR TaskType
2025-12-08 17:53:00 +01:00
Marcel Klehr 3355e6a2f7 feat(TaskProcessing): Add OCR TaskType
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
2025-12-08 17:44:37 +01:00
F. E Noel Nfebe 1158319acb Merge pull request #56740 from nextcloud/fix/sharing-password-removal
fix(files_sharing): Allow removing password from link shares
2025-12-08 14:31:11 +01:00
Kate 66d07f4ddd Merge pull request #56896 from nextcloud/fix/flake/eol-php-versions 2025-12-08 14:17:48 +01:00
nextcloud-command f46f41eabc chore(assets): Recompile assets
Signed-off-by: nextcloud-command <nextcloud-command@users.noreply.github.com>
2025-12-08 12:42:57 +01:00
nfebe 8e7cbcea40 fix(files_sharing): Allow removing password from link shares
Fixes regression from a28834b163

Signed-off-by: nfebe <fenn25.fn@gmail.com>
2025-12-08 12:42:57 +01:00
Andy Scherzinger 2c6d3d6f76 Merge pull request #56628 from nextcloud/carl/snowflake/jobs
feat: Port jobs table to snowflakes ids
2025-12-08 12:23:44 +01:00
Kate c0a4098f14 Merge pull request #56490 from nextcloud/automated/noid/-update-min-supported-desktop-version 2025-12-08 07:07:53 +01:00
nextcloud-command 40c504ec2d chore: Update minimum supported desktop version
Signed-off-by: GitHub <noreply@github.com>
2025-12-08 00:32:02 +00:00
Nextcloud bot ca52687b73 fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-12-08 00:13:27 +00:00
Marcel Müller ae85eab73c fix: Allow installation on macOS CI
Signed-off-by: Marcel Müller <marcel-mueller@gmx.de>
2025-12-07 13:32:43 +01:00
Abhinav Ohri 980c243132 fix(settings): log exception when test email fails
Signed-off-by: Abhinav Ohri <abhinavohri13@gmail.com>
2025-12-07 17:36:22 +05:30
Abhinav Ohri babab821a7 fix(settings): improve mail test error handling and logging
Signed-off-by: Abhinav Ohri <abhinavohri13@gmail.com>
2025-12-07 15:06:14 +05:30
Nextcloud bot bbca4fe56e fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-12-07 00:13:27 +00:00
provokateurin 8136b14d81 fix(flake): Allow using EOL PHP versions
Signed-off-by: provokateurin <kate@provokateurin.de>
2025-12-06 14:49:05 +01:00
Nextcloud bot de381f3b5a fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-12-06 00:13:28 +00:00
Louis 8ec73e1976 Merge pull request #56726 from nextcloud/artonge/fix/user_ldap/deleting_and_initial_config
fix(user_ldap): Improve case where selected config is undefined
2025-12-05 20:26:25 +01:00
Kate 842df498e0 Merge pull request #56816 from nextcloud/jtr/chore-legacy-drop-mac-checker 2025-12-05 17:42:38 +01:00
Joas Schilling 594d22021a Merge pull request #56076 from nextcloud/carl/cleanup-comment
refactor(comment): Port away from deprecated event comment constant
2025-12-05 11:38:08 +01:00
github-actions[bot] 9d04624fe2 Merge pull request #56785 from nextcloud/dependabot/npm_and_yarn/mdast-util-to-hast-13.2.1
build(deps): bump mdast-util-to-hast from 13.2.0 to 13.2.1
2025-12-05 10:15:01 +01:00
github-actions[bot] 309e714f14 Merge pull request #56751 from nextcloud/dependabot/npm_and_yarn/stylelint-16.26.1
build(deps-dev): bump stylelint from 16.26.0 to 16.26.1
2025-12-05 08:02:37 +00:00
dependabot[bot] 61b74102a5 build(deps): bump mdast-util-to-hast from 13.2.0 to 13.2.1
Bumps [mdast-util-to-hast](https://github.com/syntax-tree/mdast-util-to-hast) from 13.2.0 to 13.2.1.
- [Release notes](https://github.com/syntax-tree/mdast-util-to-hast/releases)
- [Commits](https://github.com/syntax-tree/mdast-util-to-hast/compare/13.2.0...13.2.1)

---
updated-dependencies:
- dependency-name: mdast-util-to-hast
  dependency-version: 13.2.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-05 08:07:17 +01:00
github-actions[bot] 818ce6ded2 Merge pull request #56860 from nextcloud/dependabot/npm_and_yarn/build/frontend-legacy/mdast-util-to-hast-13.2.1
build(deps): bump mdast-util-to-hast from 13.2.0 to 13.2.1 in /build/frontend-legacy
2025-12-05 08:06:25 +01:00
nextcloud-command 93d1684617 chore(assets): Recompile assets
Signed-off-by: nextcloud-command <nextcloud-command@users.noreply.github.com>
2025-12-05 06:37:53 +00:00
dependabot[bot] 040bdbaf28 build(deps): bump mdast-util-to-hast in /build/frontend-legacy
Bumps [mdast-util-to-hast](https://github.com/syntax-tree/mdast-util-to-hast) from 13.2.0 to 13.2.1.
- [Release notes](https://github.com/syntax-tree/mdast-util-to-hast/releases)
- [Commits](https://github.com/syntax-tree/mdast-util-to-hast/compare/13.2.0...13.2.1)

---
updated-dependencies:
- dependency-name: mdast-util-to-hast
  dependency-version: 13.2.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-05 06:02:48 +00:00
Nextcloud bot 5fcf28942f fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-12-05 00:13:36 +00:00
Daniel 9e455f0650 Merge pull request #56032 from nextcloud/carl/share-manager-correct-return-type
refactor(share-manager): Make return type more precise
2025-12-04 23:24:49 +01:00
Josh 511f54324a chore: drop unused Darwin range test variation
Signed-off-by: Josh <josh.t.richards@gmail.com>
2025-12-04 16:48:42 -05:00
Josh d95ce6ac92 chore: drop no longer needed runningOnMac method
Removed deprecated method 'runningOnMac' that checks if PHP is running on macOS.

Signed-off-by: Josh <josh.t.richards@gmail.com>
2025-12-04 16:46:55 -05:00
Carl Schwan 8bbd30693c refactor(share-manager): Make return type more precise
Signed-off-by: Carl Schwan <carl.schwan@nextcloud.com>
2025-12-04 21:39:25 +01:00
dependabot[bot] 4fce62376e build(deps-dev): bump stylelint from 16.26.0 to 16.26.1
Bumps [stylelint](https://github.com/stylelint/stylelint) from 16.26.0 to 16.26.1.
- [Release notes](https://github.com/stylelint/stylelint/releases)
- [Changelog](https://github.com/stylelint/stylelint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/stylelint/stylelint/compare/16.26.0...16.26.1)

---
updated-dependencies:
- dependency-name: stylelint
  dependency-version: 16.26.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-04 19:05:45 +01:00
Andy Scherzinger 3cdfe6dbfa Merge pull request #56790 from nextcloud/refactor/password-confirm-attribute-getstrict
refactor: improve reflection attribute typing
2025-12-04 19:04:27 +01:00
nextcloud-command 5e5ed7d912 chore(assets): Recompile assets
Signed-off-by: nextcloud-command <nextcloud-command@users.noreply.github.com>
2025-12-04 17:19:05 +00:00
Louis Chmn 291ec1e474 fix(user_ldap): Fix activation enforcement when testing the config
Signed-off-by: Louis Chmn <louis@chmn.me>
2025-12-04 17:16:21 +00:00
Louis Chmn ae8b6290e1 fix(user_ldap): Improve case where selected config is undefined
Signed-off-by: Louis Chmn <louis@chmn.me>
2025-12-04 17:16:21 +00:00
Louis Chmn 75312017d4 fix(user_ldap): Disable some buttons when clicking them would lead to an issue
Signed-off-by: Louis Chmn <louis@chmn.me>
2025-12-04 17:16:21 +00:00
Louis Chmn 2174e0b4fe fix(user_ldap): Properly update local variable for username and password in server settings
Signed-off-by: Louis Chmn <louis@chmn.me>
2025-12-04 17:16:21 +00:00
Louis Chmn b801f583d8 fix(user_ldap): Properly use fall back message in case of empty response
Signed-off-by: Louis Chmn <louis@chmn.me>
2025-12-04 17:16:21 +00:00
Louis Chmn 06c10586b7 fix(user_ldap): Properly handle new config creation in settings
Signed-off-by: Louis Chmn <louis@chmn.me>
2025-12-04 17:16:21 +00:00
Louis 189e1fcf22 Merge pull request #56834 from nextcloud/artonge/feat/repair_tree_path_and_storage
feat(files): Add support for `storage-id` and `path` in RepairTree command
2025-12-04 18:06:07 +01:00
Carl Schwan 3c9b937e28 refactor(comment): Port away from deprecated event comment constant
Create new events to replace deprecated CommentsEvent constant and use
them when creating CommentsEvents.

On the listener side, we can't yet use these events as deck still send
the old events.

Also fixes some issues reported by psalm level 3 on the comment app.

Signed-off-by: Carl Schwan <carl.schwan@nextcloud.com>
2025-12-04 17:38:53 +01:00
Christoph Wurst 8a581c230b refactor: improve reflection attribute typing
This allows tools to see the correct usage of
PasswordConfirmationRequired::getStrict

Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
2025-12-04 17:37:47 +01:00
Andy Scherzinger 1ef465f804 Merge pull request #56251 from nextcloud/carl/template-manager-cleanup
refactor(template-manager): Modernize template manager API
2025-12-04 17:26:53 +01:00
Carl Schwan 0e686fc6a9 feat: Port jobs table to snowflakes ids
Signed-off-by: Carl Schwan <carl.schwan@nextcloud.com>
2025-12-04 17:16:12 +01:00
Côme Chilliet aeed32cfba Merge pull request #56843 from nextcloud/feat/add-cli-details-to-log
feat(log): Add script name and occ command to log details
2025-12-04 17:06:00 +01:00
Daniel 73017f564a Merge pull request #56768 from nextcloud/feat/log-cache-events-to-audit
feat(admin_audit): Log cache insert/delete to audit log
2025-12-04 16:53:29 +01:00
Maxence Lange b18372e637 Merge pull request #56668 from nextcloud/fix/noid/real-account-on-deleted-federation
fix(trashbin): deletedBy of a file from a federated folder
2025-12-04 13:46:43 -01:00
Côme Chilliet cb80ec7ebb feat(log): Add script name and occ command to log details
This will help when troubleshooting issues. For web request we have
 method and url, but for cron and occ currently we have no way to know if
 it’s one or the other and which command.

Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
2025-12-04 15:04:59 +01:00
Stephan Orbaugh 86f0cbf1e8 Merge pull request #56664 from cristianscheid/feat/54790/transfer-ownership-use-user-id
feat(files): add --use-user-id option to transfer-ownership command
2025-12-04 13:43:07 +01:00
Louis 5bf67fd206 Merge pull request #56745 from nextcloud/artonge/feat/files_sharing/support_priority_in_template_providers
feat(files_sharing): Support priority in public template providers
2025-12-04 12:58:44 +01:00
Louis Chmn 55756e626f feat(files): Add support for storage-id and path in RepairTree command
This allows to run the command on specific part of the filecache. When the filecache is big, it prevents overloading the DB.

Signed-off-by: Louis Chmn <louis@chmn.me>
2025-12-04 11:43:12 +01:00
Louis Chmn 10b82c8bf8 feat(files_sharing): Support priority in public template providers
Signed-off-by: Louis Chmn <louis@chmn.me>
2025-12-04 10:59:58 +01:00
Nextcloud bot e5367e11ba fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-12-04 00:14:05 +00:00
Salvatore Martire 31af870ef0 Merge pull request #55147 from nextcloud/fixPublicShares
Reflect public shares in `isPublic` flag and fix permission check
2025-12-03 16:37:33 +01:00
Andy Scherzinger 5b1d928dcd Merge pull request #56630 from nextcloud/carl/workflowengine-hardening
refactor(workflowengine): Check if class is correct
2025-12-03 16:21:24 +01:00
Sebastian Krupinski 8e7bdabe15 Merge pull request #56801 from nextcloud/fix/caldav-increase-uid-size
fix(CalDAV): Increase Calendar Object UID field size
2025-12-03 07:52:17 -05:00
Kate c23dbcce45 Merge pull request #56783 from nextcloud/chore/deps/flake 2025-12-03 13:49:40 +01:00
Carl Schwan f38c8c3d7c fix(formatting): Fix formatting issue
Signed-off-by: Carl Schwan <carl.schwan@nextcloud.com>
2025-12-03 11:10:18 +01:00
Sebastian Möbus bae24eb2e3 Merge pull request #56791 from nextcloud/binford6000-patch-upgrading-from-owncloud->-v10.13
patch the version file to allow upgrading from owncloud  > v10.13
2025-12-03 06:42:30 +01:00
Joas Schilling 48f39f54c5 Merge pull request #56811 from nextcloud/automated/noid/master-update-ca-cert-bundle
[master] fix(security): Update CA certificate bundle
2025-12-03 05:54:38 +01:00
Josh aa498654c5 refactor(setup): use OS constant rather than function (macOS)
PHP_OS_FAMILY

- Facilitates elimination of a legacy OC_Util method
  - `runningOnMac()` -- yes, really! ;-)
- Supported since PHP late 7.x-era

Signed-off-by: Josh <josh.t.richards@gmail.com>
2025-12-02 21:54:44 -05:00
Josh d9a7e0855c refactor(tests): use OS constant over function
Use PHP's newer PHP_OS_FAMILY constant.

- Allows us to drop a legacy OC_Util method.
- This test isn't even enabled at the moment.

Signed-off-by: Josh <josh.t.richards@gmail.com>
2025-12-02 21:53:03 -05:00
Josh cc873ccaec chore(legacy): deprecate OC_Util::runningOnMac()
- Easy enough query directly these days; Only used in one spot anyhow
- Updated the runningOnMac method to use PHP_OS_FAMILY just for clarity until we can remove the function entirely (same result; supported since PHP ~7.4).

Signed-off-by: Josh <josh.t.richards@gmail.com>
2025-12-02 21:52:58 -05:00
nextcloud-command c6a68d5f17 fix(security): Update CA certificate bundle
Signed-off-by: GitHub <noreply@github.com>
2025-12-03 02:40:57 +00:00
Nextcloud bot b520db7eb5 fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-12-03 00:13:30 +00:00
Kate 756efb76aa Merge pull request #56672 from nextcloud/chore-disable-s3-data-protection 2025-12-02 22:14:10 +01:00
Louis cbe18a8677 Merge pull request #56792 from nextcloud/artonge/debt/files/remove_regular_stats_request
debt(files): Remove regular stats request
2025-12-02 21:13:50 +01:00
Daniel Kesselberg f977a7fec6 fix(s3): make data integrity protections opt-in
Signed-off-by: Daniel Kesselberg <mail@danielkesselberg.de>
2025-12-02 21:03:26 +01:00
Andy Scherzinger 34c6cb7b2e Merge pull request #56655 from nextcloud/fix/fix-updater-secret-log-spam
fix(updatenotification): Fix log spam from ResetToken job
2025-12-02 19:24:40 +01:00
Andy Scherzinger 0e9aa3dd78 Merge pull request #56728 from nextcloud/fix/fix-wizard-controller-translation-string
fix(user_ldap): Do not use variables directly in translation strings
2025-12-02 19:23:10 +01:00
SebastianKrupinski 54e23aeac9 feat(CalDAV): Increase Calendar Object UID field size
Signed-off-by: SebastianKrupinski <krupinskis05@gmail.com>
2025-12-02 12:54:00 -05:00
Edward Ly 1490ea95cb Merge pull request #56781 from nextcloud/fix/s3-name
fix(s3): rename 'Amazon S3' to 'S3 Storage'
2025-12-02 09:20:34 -08:00
Benjamin Gaussorgues 5a0651e7c7 Merge pull request #56561 from nextcloud/fix/fix-files-external-with-php-84 2025-12-02 17:58:26 +01:00
Edward Ly 09f774a61f fix(s3): rename 'Amazon S3' to 'S3 Storage'
The current name may be confusing to users who take advantage of other S3-compatible storage solutions not offered by Amazon, so a more generic name is preferred here.

Signed-off-by: Edward Ly <contact@edward.ly>
2025-12-02 08:33:06 -08:00
Joas Schilling 7a5c79b0f2 Merge pull request #56629 from nextcloud/carl/autoloader-bump
chore: Bump autoloader files for new composer version
2025-12-02 16:58:01 +01:00
F. E Noel Nfebe 68b9108ca6 Merge pull request #55811 from nextcloud/fix/public-share-group-exclusion-access
fix(sharing): Allow public share access for everyone
2025-12-02 15:41:59 +01:00
nextcloud-command 3b41ab108f chore(assets): Recompile assets
Signed-off-by: nextcloud-command <nextcloud-command@users.noreply.github.com>
2025-12-02 15:37:02 +01:00
Louis Chmn 9aac7ecc60 chore(files): Remove regular stats request
All views are now migrated.

Signed-off-by: Louis Chmn <louis@chmn.me>
2025-12-02 15:37:02 +01:00
Andy Scherzinger f5620538b9 Fix indentation in version.php for Nextcloud version
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
2025-12-02 14:40:27 +01:00
Sebastian Möbus 4f933d3505 patch the version file to allow upgrading from owncloud > v10.13
Some customers already migrated from 10.15.3 and needed to edit the version.php file before the migration. 10.16 was recently published and it seems migration from there also works fine.

Signed-off-by: Sebastian Möbus <sebastian@nextcloud.com>
2025-12-02 14:40:27 +01:00
Benjamin Gaussorgues 86c2dd467d Merge pull request #56758 from nextcloud/fix/fix-orphan-share-blocking-moves 2025-12-02 10:45:40 +01:00
Carl Schwan d877262e07 chore: Bump autoloader files for new composer version
Signed-off-by: Carl Schwan <carl.schwan@nextcloud.com>
2025-12-02 10:32:44 +01:00
nfebe 6bccaf778a fix(sharing): Allow public share access for everyone
When a logged-in user accesses a public share link in the same browser,
the system was incorrectly checking if that user's groups were excluded
from creating link shares. This caused share not found errors for users
in excluded groups, even though public shares should be accessible to anyone
with the link.

The group exclusion setting (`shareapi_allow_links_exclude_groups`) is
intended to restrict share creation, not share access. Public shares
are meant to be anonymous and accessible regardless of the viewer identity
or group membership.

We now check the exclusion for the share creator and not the viewer.

Signed-off-by: nfebe <fenn25.fn@gmail.com>
2025-12-02 09:45:18 +01:00
John Molakvoæ 3b2a306a67 Merge pull request #56694 from nextcloud/refactor/files_reminders-vue3 2025-12-02 09:42:49 +01:00
Côme Chilliet f453411d59 fix: Log missing nodes of shares at debug level
Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
2025-12-02 09:33:07 +01:00
Kate 8eff6537a2 Merge pull request #56527 from nextcloud/fix/quotaplugin/always-check-before-move 2025-12-02 08:31:53 +01:00
Nextcloud bot a9b811906d fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-12-02 00:14:04 +00:00
provokateurin dabde76f9e chore(deps): Update flake to 25.11 and haze to 2.1.3
Signed-off-by: provokateurin <kate@provokateurin.de>
2025-12-01 23:15:57 +01:00
Maxence Lange ea8b133910 fix(trashbin): deletedBy of a file from a federated folder
Signed-off-by: Maxence Lange <maxence@artificial-owl.com>

d
2025-12-01 16:25:05 -01:00
Salvatore Martire 631318f86f style: apply cs-fixer to publicwebdav.php
Signed-off-by: Salvatore Martire <4652631+salmart-dev@users.noreply.github.com>
2025-12-01 18:09:25 +01:00
Salvatore Martire 4ac0fcf02e fix: check instance of storage using helper function
instanceof cannot be used to check the instance of a storage, doing so
breaks the check in certain cases. In this case, enabling the
`files_accesscontrol` app breaks the check.

Signed-off-by: Salvatore Martire <4652631+salmart-dev@users.noreply.github.com>
2025-12-01 18:09:25 +01:00
Salvatore Martire 38f8423cd6 fix: isPublicShare =true when share is public
The isPublicShare was set to false in one instance where it should have
been true. Flipping the value to true, would break the functionality for
PROPFIND /public.php/webdav/ which returns properties of files in a
share identified by the username being the share token.

Signed-off-by: Salvatore Martire <4652631+salmart-dev@users.noreply.github.com>
2025-12-01 18:09:25 +01:00
Salvatore Martire c5ad20d925 refactor: extract tree initialization logic
Signed-off-by: Salvatore Martire <4652631+salmart-dev@users.noreply.github.com>
2025-12-01 18:09:25 +01:00
provokateurin b1deae7232 fix(QuotaPlugin): Always check the quota before moving
Signed-off-by: provokateurin <kate@provokateurin.de>
2025-12-01 16:07:02 +01:00
nextcloud-command 7cafbb009f chore(assets): Recompile assets
Signed-off-by: nextcloud-command <nextcloud-command@users.noreply.github.com>
2025-12-01 14:34:34 +01:00
Ferdinand Thiessen d2ff4214f8 refactor(files_reminders): migrate app to Vue 3
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-12-01 14:34:34 +01:00
Cristian Scheid 9272a13e9d refactor(files): use strict string comparison instead of empty()
Co-authored-by: Kate <26026535+provokateurin@users.noreply.github.com>
Signed-off-by: Cristian Scheid <74515775+cristianscheid@users.noreply.github.com>
2025-12-01 09:52:59 -03:00
Côme Chilliet 938e8d3a46 feat(admin_audit): Log cache insert/delete to audit log
That allows to see files added/removed by a filesystem scan for
instance.

Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
2025-12-01 13:52:09 +01:00
Cristian Scheid fa2a7b9b2d refactor(files): use explicit empty check instead of elvis operator
Signed-off-by: Cristian Scheid <cristianscheid@gmail.com>
2025-12-01 07:36:18 -03:00
Côme Chilliet 7eefd725db fix(user_ldap): Do not use variables directly in translation strings
I simply removed translations for exceptions which are never supposed to
 happen apart from API misuse or code bug.

Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
2025-12-01 10:40:50 +01:00
Côme Chilliet 8d64e076ee fix: Fix orphan shares blocking moving other shares
Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
2025-12-01 09:43:39 +01:00
Carl Schwan 7541afae07 refactor(workflowengine): Check if class is correct
Signed-off-by: Carl Schwan <carl.schwan@nextcloud.com>
2025-11-26 10:16:35 +01:00
Cristian Scheid 40d3118751 feat(files): add --use-user-id option to transfer-ownership command
Signed-off-by: Cristian Scheid <cristianscheid@gmail.com>
2025-11-25 11:45:40 -03:00
Côme Chilliet 69b85fab32 fix(files_external): Properly register event listeners in register method
This is the clean solution, LoginCredentials was the only auth class
 actually registering stuff in constructor.

Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
2025-11-25 15:08:35 +01:00
Côme Chilliet 3279afc529 fix(files_external): Fix registration of listeners with PHP >= 8.4
With the lazy ghosts the constructor is not always called in
 files_external boot. This is a quick and dirty fix but we should
 instead move the code out of the constructors and to the boot method.

Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
2025-11-25 15:08:35 +01:00
Côme Chilliet 98ee89286d fix(updatenotification): Fix log spam from ResetToken job
Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
2025-11-25 10:43:22 +01:00
Carl Schwan 9522dde7a2 feat: Add Folder::getOrCreateFolder api
Allow to remove some boilerplate and also this new function is type
safe.

Signed-off-by: Carl Schwan <carl.schwan@nextcloud.com>
2025-11-24 11:10:52 +01:00
Carl Schwan 38fd84aa6a refactor(template-manager): Modernize template manager API
And correct openapi types for the size.

Signed-off-by: Carl Schwan <carl.schwan@nextcloud.com>
2025-11-24 10:00:47 +01:00
1782 changed files with 12695 additions and 10459 deletions
+1 -1
View File
@@ -69,7 +69,7 @@ updates:
target-branch: stable32
directories:
- "/"
- "/build/integration"
- "/vendor-bin/behat"
- "/vendor-bin/cs-fixer"
- "/vendor-bin/openapi-extractor"
- "/vendor-bin/phpunit"
@@ -90,6 +90,7 @@ jobs:
- name: Set up Nextcloud
run: |
composer install
mkdir data
echo '<?php $CONFIG=["${{ matrix.key }}" => ["class" => "OC\Files\ObjectStore\S3", "arguments" => ["bucket" => "nextcloud", "autocreate" => true, "key" => "nextcloud", "secret" => "bWluaW8tc2VjcmV0LWtleS1uZXh0Y2xvdWQ=", "hostname" => "localhost", "port" => 9000, "use_ssl" => false, "use_path_style" => true, "uploadPartSize" => 52428800]]];' > config/config.php
echo '<?php $CONFIG=["redis" => ["host" => "localhost", "port" => 6379], "memcache.local" => "\OC\Memcache\Redis", "memcache.distributed" => "\OC\Memcache\Redis"];' > config/redis.config.php
+3 -6
View File
@@ -131,12 +131,9 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Set up production dependencies
run: composer i --no-dev
- name: Set up behat dependencies
working-directory: build/integration
run: composer i
- name: Set up dependencies
run: |
composer install
- name: Set up Talk dependencies
if: ${{ matrix.test-suite == 'videoverification_features' }}
+1 -1
View File
@@ -256,7 +256,7 @@ SPDX-FileCopyrightText = "2025 Nextcloud GmbH and Nextcloud contributors"
SPDX-License-Identifier = "AGPL-3.0-or-later"
[[annotations]]
path = ["composer.json", "composer.lock", ".github/CODEOWNERS", "__tests__/tsconfig.json", "tsconfig.json", "build/integration/composer.**", "vendor-bin/**/composer.json", "vendor-bin/**/composer.lock", "apps/**/composer/composer.json", "apps/**/composer/composer.lock", "apps/**/composer/composer/installed.json"]
path = ["composer.json", "composer.lock", ".github/CODEOWNERS", "__tests__/tsconfig.json", "tsconfig.json", "apps/**/composer/composer.json", "apps/**/composer/composer.lock", "apps/**/composer/composer/installed.json"]
precedence = "aggregate"
SPDX-FileCopyrightText = "2011-2016 ownCloud, Inc., 2016-2024 Nextcloud GmbH and Nextcloud contributors"
SPDX-License-Identifier = "AGPL-3.0-only OR AGPL-3.0-or-later"
@@ -19,6 +19,7 @@ return array(
'OCA\\AdminAudit\\IAuditLogger' => $baseDir . '/../lib/IAuditLogger.php',
'OCA\\AdminAudit\\Listener\\AppManagementEventListener' => $baseDir . '/../lib/Listener/AppManagementEventListener.php',
'OCA\\AdminAudit\\Listener\\AuthEventListener' => $baseDir . '/../lib/Listener/AuthEventListener.php',
'OCA\\AdminAudit\\Listener\\CacheEventListener' => $baseDir . '/../lib/Listener/CacheEventListener.php',
'OCA\\AdminAudit\\Listener\\ConsoleEventListener' => $baseDir . '/../lib/Listener/ConsoleEventListener.php',
'OCA\\AdminAudit\\Listener\\CriticalActionPerformedEventListener' => $baseDir . '/../lib/Listener/CriticalActionPerformedEventListener.php',
'OCA\\AdminAudit\\Listener\\FileEventListener' => $baseDir . '/../lib/Listener/FileEventListener.php',
@@ -7,14 +7,14 @@ namespace Composer\Autoload;
class ComposerStaticInitAdminAudit
{
public static $prefixLengthsPsr4 = array (
'O' =>
'O' =>
array (
'OCA\\AdminAudit\\' => 15,
),
);
public static $prefixDirsPsr4 = array (
'OCA\\AdminAudit\\' =>
'OCA\\AdminAudit\\' =>
array (
0 => __DIR__ . '/..' . '/../lib',
),
@@ -34,6 +34,7 @@ class ComposerStaticInitAdminAudit
'OCA\\AdminAudit\\IAuditLogger' => __DIR__ . '/..' . '/../lib/IAuditLogger.php',
'OCA\\AdminAudit\\Listener\\AppManagementEventListener' => __DIR__ . '/..' . '/../lib/Listener/AppManagementEventListener.php',
'OCA\\AdminAudit\\Listener\\AuthEventListener' => __DIR__ . '/..' . '/../lib/Listener/AuthEventListener.php',
'OCA\\AdminAudit\\Listener\\CacheEventListener' => __DIR__ . '/..' . '/../lib/Listener/CacheEventListener.php',
'OCA\\AdminAudit\\Listener\\ConsoleEventListener' => __DIR__ . '/..' . '/../lib/Listener/ConsoleEventListener.php',
'OCA\\AdminAudit\\Listener\\CriticalActionPerformedEventListener' => __DIR__ . '/..' . '/../lib/Listener/CriticalActionPerformedEventListener.php',
'OCA\\AdminAudit\\Listener\\FileEventListener' => __DIR__ . '/..' . '/../lib/Listener/FileEventListener.php',
@@ -20,6 +20,7 @@ use OCA\AdminAudit\AuditLogger;
use OCA\AdminAudit\IAuditLogger;
use OCA\AdminAudit\Listener\AppManagementEventListener;
use OCA\AdminAudit\Listener\AuthEventListener;
use OCA\AdminAudit\Listener\CacheEventListener;
use OCA\AdminAudit\Listener\ConsoleEventListener;
use OCA\AdminAudit\Listener\CriticalActionPerformedEventListener;
use OCA\AdminAudit\Listener\FileEventListener;
@@ -40,6 +41,8 @@ use OCP\Authentication\TwoFactorAuth\TwoFactorProviderChallengeFailed;
use OCP\Authentication\TwoFactorAuth\TwoFactorProviderChallengePassed;
use OCP\Console\ConsoleEvent;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\Cache\CacheEntryInsertedEvent;
use OCP\Files\Cache\CacheEntryRemovedEvent;
use OCP\Files\Events\Node\BeforeNodeDeletedEvent;
use OCP\Files\Events\Node\BeforeNodeReadEvent;
use OCP\Files\Events\Node\NodeCopiedEvent;
@@ -123,6 +126,10 @@ class Application extends App implements IBootstrap {
// Console events
$context->registerEventListener(ConsoleEvent::class, ConsoleEventListener::class);
// Cache events
$context->registerEventListener(CacheEntryInsertedEvent::class, CacheEventListener::class);
$context->registerEventListener(CacheEntryRemovedEvent::class, CacheEventListener::class);
}
public function boot(IBootContext $context): void {
@@ -0,0 +1,51 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\AdminAudit\Listener;
use OCA\AdminAudit\Actions\Action;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
use OCP\Files\Cache\CacheEntryInsertedEvent;
use OCP\Files\Cache\CacheEntryRemovedEvent;
/**
* @template-implements IEventListener<CacheEntryInsertedEvent|CacheEntryRemovedEvent>
*/
class CacheEventListener extends Action implements IEventListener {
public function handle(Event $event): void {
if ($event instanceof CacheEntryInsertedEvent) {
$this->entryInserted($event);
} elseif ($event instanceof CacheEntryRemovedEvent) {
$this->entryRemoved($event);
}
}
private function entryInserted(CacheEntryInsertedEvent $event): void {
$this->log('Cache entry inserted for fileid "%1$d", path "%2$s" on storageid "%3$d"',
[
'fileid' => $event->getFileId(),
'path' => $event->getPath(),
'storageid' => $event->getStorageId(),
],
['fileid', 'path', 'storageid']
);
}
private function entryRemoved(CacheEntryRemovedEvent $event): void {
$this->log('Cache entry removed for fileid "%1$d", path "%2$s" on storageid "%3$d"',
[
'fileid' => $event->getFileId(),
'path' => $event->getPath(),
'storageid' => $event->getStorageId(),
],
['fileid', 'path', 'storageid']
);
}
}
@@ -7,14 +7,14 @@ namespace Composer\Autoload;
class ComposerStaticInitCloudFederationAPI
{
public static $prefixLengthsPsr4 = array (
'O' =>
'O' =>
array (
'OCA\\CloudFederationAPI\\' => 23,
),
);
public static $prefixDirsPsr4 = array (
'OCA\\CloudFederationAPI\\' =>
'OCA\\CloudFederationAPI\\' =>
array (
0 => __DIR__ . '/..' . '/../lib',
),
@@ -7,14 +7,14 @@ namespace Composer\Autoload;
class ComposerStaticInitComments
{
public static $prefixLengthsPsr4 = array (
'O' =>
'O' =>
array (
'OCA\\Comments\\' => 13,
),
);
public static $prefixDirsPsr4 = array (
'OCA\\Comments\\' =>
'OCA\\Comments\\' =>
array (
0 => __DIR__ . '/..' . '/../lib',
),
+1
View File
@@ -17,6 +17,7 @@ OC.L10N.register(
"Delete comment" : "Borrar comentario",
"Cancel edit" : "Cacelar edición",
"New comment" : "Comentario nuevo",
"Write a comment …" : "Escribe un comentario ….",
"Post comment" : "Publicar comentario",
"@ for mentions, : for emoji, / for smart picker" : "@ para menciones, : para emoji, / para selector inteligente",
"Could not reload comments" : "No se pudieron recargar los comentarios",
+1
View File
@@ -15,6 +15,7 @@
"Delete comment" : "Borrar comentario",
"Cancel edit" : "Cacelar edición",
"New comment" : "Comentario nuevo",
"Write a comment …" : "Escribe un comentario ….",
"Post comment" : "Publicar comentario",
"@ for mentions, : for emoji, / for smart picker" : "@ para menciones, : para emoji, / para selector inteligente",
"Could not reload comments" : "No se pudieron recargar los comentarios",
+1
View File
@@ -15,6 +15,7 @@ OC.L10N.register(
"Delete comment" : "Poista kommentti",
"Cancel edit" : "Peruuta muokkaus",
"New comment" : "Uusi kommentti",
"Write a comment …" : "Kirjoita kommentti …",
"Post comment" : "Lähetä viesti",
"@ for mentions, : for emoji, / for smart picker" : "@ maininnoille, : emojille, / älykkäälle valitsimelle",
"Could not reload comments" : "Kommenttien lataus epäonnistui",
+1
View File
@@ -13,6 +13,7 @@
"Delete comment" : "Poista kommentti",
"Cancel edit" : "Peruuta muokkaus",
"New comment" : "Uusi kommentti",
"Write a comment …" : "Kirjoita kommentti …",
"Post comment" : "Lähetä viesti",
"@ for mentions, : for emoji, / for smart picker" : "@ maininnoille, : emojille, / älykkäälle valitsimelle",
"Could not reload comments" : "Kommenttien lataus epäonnistui",
+1 -1
View File
@@ -17,7 +17,7 @@ OC.L10N.register(
"Delete comment" : "Supprimer le commentaire",
"Cancel edit" : "Annuler les modifications",
"New comment" : "Nouveau commentaire",
"Write a comment …" : "Écrire un commentaire …",
"Write a comment …" : "Écrire un commentaire…",
"Post comment" : "Publier le commentaire",
"@ for mentions, : for emoji, / for smart picker" : "@ pour les mentions, : pour les émojis, / pour le sélecteur intelligent",
"Could not reload comments" : "Impossible de recharger les commentaires",
+1 -1
View File
@@ -15,7 +15,7 @@
"Delete comment" : "Supprimer le commentaire",
"Cancel edit" : "Annuler les modifications",
"New comment" : "Nouveau commentaire",
"Write a comment …" : "Écrire un commentaire …",
"Write a comment …" : "Écrire un commentaire…",
"Post comment" : "Publier le commentaire",
"@ for mentions, : for emoji, / for smart picker" : "@ pour les mentions, : pour les émojis, / pour le sélecteur intelligent",
"Could not reload comments" : "Impossible de recharger les commentaires",
+12 -14
View File
@@ -18,8 +18,6 @@ use OCP\IUserManager;
use OCP\L10N\IFactory;
class Provider implements IProvider {
protected ?IL10N $l = null;
public function __construct(
protected IFactory $languageFactory,
protected IURLGenerator $url,
@@ -42,9 +40,9 @@ class Provider implements IProvider {
throw new UnknownActivityException();
}
$this->l = $this->languageFactory->get('comments', $language);
if ($event->getSubject() === 'add_comment_subject') {
$l = $this->languageFactory->get('comments', $language);
$this->parseMessage($event);
if ($this->activityManager->getRequirePNG()) {
$event->setIcon($this->url->getAbsoluteURL($this->url->imagePath('core', 'actions/comment.png')));
@@ -54,13 +52,13 @@ class Provider implements IProvider {
if ($this->activityManager->isFormattingFilteredObject()) {
try {
return $this->parseShortVersion($event);
return $this->parseShortVersion($event, $l);
} catch (UnknownActivityException) {
// Ignore and simply use the long version...
}
}
return $this->parseLongVersion($event);
return $this->parseLongVersion($event, $l);
}
throw new UnknownActivityException();
@@ -69,15 +67,15 @@ class Provider implements IProvider {
/**
* @throws UnknownActivityException
*/
protected function parseShortVersion(IEvent $event): IEvent {
protected function parseShortVersion(IEvent $event, IL10N $l): IEvent {
$subjectParameters = $this->getSubjectParameters($event);
if ($event->getSubject() === 'add_comment_subject') {
if ($subjectParameters['actor'] === $this->activityManager->getCurrentUserId()) {
$event->setRichSubject($this->l->t('You commented'), []);
$event->setRichSubject($l->t('You commented'), []);
} else {
$author = $this->generateUserParameter($subjectParameters['actor']);
$event->setRichSubject($this->l->t('{author} commented'), [
$event->setRichSubject($l->t('{author} commented'), [
'author' => $author,
]);
}
@@ -91,24 +89,24 @@ class Provider implements IProvider {
/**
* @throws UnknownActivityException
*/
protected function parseLongVersion(IEvent $event): IEvent {
protected function parseLongVersion(IEvent $event, IL10N $l): IEvent {
$subjectParameters = $this->getSubjectParameters($event);
if ($event->getSubject() === 'add_comment_subject') {
if ($subjectParameters['actor'] === $this->activityManager->getCurrentUserId()) {
$event->setParsedSubject($this->l->t('You commented on %1$s', [
$event->setParsedSubject($l->t('You commented on %1$s', [
$subjectParameters['filePath'],
]))
->setRichSubject($this->l->t('You commented on {file}'), [
->setRichSubject($l->t('You commented on {file}'), [
'file' => $this->generateFileParameter($subjectParameters['fileId'], $subjectParameters['filePath']),
]);
} else {
$author = $this->generateUserParameter($subjectParameters['actor']);
$event->setParsedSubject($this->l->t('%1$s commented on %2$s', [
$event->setParsedSubject($l->t('%1$s commented on %2$s', [
$author['name'],
$subjectParameters['filePath'],
]))
->setRichSubject($this->l->t('{author} commented on {file}'), [
->setRichSubject($l->t('{author} commented on {file}'), [
'author' => $author,
'file' => $this->generateFileParameter($subjectParameters['fileId'], $subjectParameters['filePath']),
]);
+3 -3
View File
@@ -11,7 +11,7 @@ use OCP\IL10N;
class Setting extends ActivitySettings {
public function __construct(
protected IL10N $l,
protected readonly IL10N $l,
) {
}
@@ -23,11 +23,11 @@ class Setting extends ActivitySettings {
return $this->l->t('<strong>Comments</strong> for files');
}
public function getGroupIdentifier() {
public function getGroupIdentifier(): string {
return 'files';
}
public function getGroupName() {
public function getGroupName(): string {
return $this->l->t('Files');
}
@@ -27,6 +27,10 @@ class CommentsEntityEventListener implements IEventListener {
return;
}
if ($this->userId === null) {
return;
}
$event->addEntityCollection('files', function ($name): bool {
$nodes = $this->rootFolder->getUserFolder($this->userId)->getById((int)$name);
return !empty($nodes);
@@ -35,8 +35,7 @@ class CommentsEventListener implements IEventListener {
}
$eventType = $event->getEvent();
if ($eventType === CommentsEvent::EVENT_ADD
) {
if ($eventType === CommentsEvent::EVENT_ADD) {
$this->notificationHandler($event);
$this->activityHandler($event);
return;
@@ -3,7 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import type { View } from '@nextcloud/files'
import type { Folder, View } from '@nextcloud/files'
import { File, FileAction, Permission } from '@nextcloud/files'
import { describe, expect, test, vi } from 'vitest'
@@ -26,15 +26,41 @@ describe('Inline unread comments action display name tests', () => {
attributes: {
'comments-unread': 1,
},
root: '/files/admin',
})
expect(action).toBeInstanceOf(FileAction)
expect(action.id).toBe('comments-unread')
expect(action.displayName([file], view)).toBe('')
expect(action.title!([file], view)).toBe('1 new comment')
expect(action.iconSvgInline([], view)).toMatch(/<svg.+<\/svg>/)
expect(action.enabled!([file], view)).toBe(true)
expect(action.inline!(file, view)).toBe(true)
expect(action.displayName({
nodes: [file],
view,
folder: {} as Folder,
contents: [],
})).toBe('')
expect(action.title!({
nodes: [file],
view,
folder: {} as Folder,
contents: [],
})).toBe('1 new comment')
expect(action.iconSvgInline({
nodes: [file],
view,
folder: {} as Folder,
contents: [],
})).toMatch(/<svg.+<\/svg>/)
expect(action.enabled!({
nodes: [file],
view,
folder: {} as Folder,
contents: [],
})).toBe(true)
expect(action.inline!({
nodes: [file],
view,
folder: {} as Folder,
contents: [],
})).toBe(true)
expect(action.default).toBeUndefined()
expect(action.order).toBe(-140)
})
@@ -49,10 +75,21 @@ describe('Inline unread comments action display name tests', () => {
attributes: {
'comments-unread': 2,
},
root: '/files/admin',
})
expect(action.displayName([file], view)).toBe('')
expect(action.title!([file], view)).toBe('2 new comments')
expect(action.displayName({
nodes: [file],
view,
folder: {} as Folder,
contents: [],
})).toBe('')
expect(action.title!({
nodes: [file],
view,
folder: {} as Folder,
contents: [],
})).toBe('2 new comments')
})
})
@@ -64,10 +101,16 @@ describe('Inline unread comments action enabled tests', () => {
owner: 'admin',
mime: 'text/plain',
permissions: Permission.ALL,
attributes: { },
attributes: {},
root: '/files/admin',
})
expect(action.enabled!([file], view)).toBe(false)
expect(action.enabled!({
nodes: [file],
view,
folder: {} as Folder,
contents: [],
})).toBe(false)
})
test('Action is disabled when file does not have unread comments', () => {
@@ -80,9 +123,15 @@ describe('Inline unread comments action enabled tests', () => {
attributes: {
'comments-unread': 0,
},
root: '/files/admin',
})
expect(action.enabled!([file], view)).toBe(false)
expect(action.enabled!({
nodes: [file],
view,
folder: {} as Folder,
contents: [],
})).toBe(false)
})
test('Action is enabled when file has a single unread comment', () => {
@@ -95,9 +144,15 @@ describe('Inline unread comments action enabled tests', () => {
attributes: {
'comments-unread': 1,
},
root: '/files/admin',
})
expect(action.enabled!([file], view)).toBe(true)
expect(action.enabled!({
nodes: [file],
view,
folder: {} as Folder,
contents: [],
})).toBe(true)
})
test('Action is enabled when file has a two unread comments', () => {
@@ -110,9 +165,15 @@ describe('Inline unread comments action enabled tests', () => {
attributes: {
'comments-unread': 2,
},
root: '/files/admin',
})
expect(action.enabled!([file], view)).toBe(true)
expect(action.enabled!({
nodes: [file],
view,
folder: {} as Folder,
contents: [],
})).toBe(true)
})
})
@@ -139,9 +200,15 @@ describe('Inline unread comments action execute tests', () => {
attributes: {
'comments-unread': 1,
},
root: '/files/admin',
})
const result = await action.exec!(file, view, '/')
const result = await action.exec!({
nodes: [file],
view,
folder: {} as Folder,
contents: [],
})
expect(result).toBe(null)
expect(setActiveTabMock).toBeCalledWith('comments')
@@ -173,9 +240,15 @@ describe('Inline unread comments action execute tests', () => {
attributes: {
'comments-unread': 1,
},
root: '/files/admin',
})
const result = await action.exec!(file, view, '/')
const result = await action.exec!({
nodes: [file],
view,
folder: {} as Folder,
contents: [],
})
expect(result).toBe(false)
expect(setActiveTabMock).toBeCalledWith('comments')
@@ -2,9 +2,6 @@
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import type { Node } from '@nextcloud/files'
import CommentProcessingSvg from '@mdi/svg/svg/comment-processing.svg?raw'
import { FileAction } from '@nextcloud/files'
import { n, t } from '@nextcloud/l10n'
@@ -13,9 +10,9 @@ import logger from '../logger.js'
export const action = new FileAction({
id: 'comments-unread',
title(nodes: Node[]) {
const unread = nodes[0].attributes['comments-unread'] as number
if (unread >= 0) {
title({ nodes }) {
const unread = nodes[0]?.attributes['comments-unread'] as number | undefined
if (typeof unread === 'number' && unread >= 0) {
return n('comments', '1 new comment', '{unread} new comments', unread, { unread })
}
return t('comments', 'Comment')
@@ -26,15 +23,19 @@ export const action = new FileAction({
iconSvgInline: () => CommentProcessingSvg,
enabled(nodes: Node[]) {
const unread = nodes[0].attributes['comments-unread'] as number | undefined
enabled({ nodes }) {
const unread = nodes[0]?.attributes?.['comments-unread'] as number | undefined
return typeof unread === 'number' && unread > 0
},
async exec(node: Node) {
async exec({ nodes }) {
if (nodes.length !== 1 || !nodes[0]) {
return false
}
try {
window.OCA.Files.Sidebar.setActiveTab('comments')
await window.OCA.Files.Sidebar.open(node.path)
await window.OCA.Files.Sidebar.open(nodes[0].path)
return null
} catch (error) {
logger.error('Error while opening sidebar', { error })
@@ -12,7 +12,7 @@ use OCA\Comments\Activity\Listener;
use OCP\Activity\IEvent;
use OCP\Activity\IManager;
use OCP\App\IAppManager;
use OCP\Comments\CommentsEvent;
use OCP\Comments\Events\CommentAddedEvent;
use OCP\Comments\IComment;
use OCP\Files\Config\ICachedMountFileInfo;
use OCP\Files\Config\IMountProviderCollection;
@@ -66,14 +66,7 @@ class ListenerTest extends TestCase {
->method('getObjectType')
->willReturn('files');
/** @var CommentsEvent|MockObject $event */
$event = $this->createMock(CommentsEvent::class);
$event->expects($this->any())
->method('getComment')
->willReturn($comment);
$event->expects($this->any())
->method('getEvent')
->willReturn(CommentsEvent::EVENT_ADD);
$event = new CommentAddedEvent($comment);
/** @var IUser|MockObject $ownerUser */
$ownerUser = $this->createMock(IUser::class);
+14 -12
View File
@@ -12,6 +12,10 @@ use OCA\Comments\Activity\Listener as ActivityListener;
use OCA\Comments\Listener\CommentsEventListener;
use OCA\Comments\Notification\Listener as NotificationListener;
use OCP\Comments\CommentsEvent;
use OCP\Comments\Events\BeforeCommentUpdatedEvent;
use OCP\Comments\Events\CommentAddedEvent;
use OCP\Comments\Events\CommentDeletedEvent;
use OCP\Comments\Events\CommentUpdatedEvent;
use OCP\Comments\IComment;
use PHPUnit\Framework\MockObject\MockObject;
use Test\TestCase;
@@ -50,10 +54,10 @@ class EventHandlerTest extends TestCase {
public static function handledProvider(): array {
return [
[CommentsEvent::EVENT_DELETE],
[CommentsEvent::EVENT_UPDATE],
[CommentsEvent::EVENT_PRE_UPDATE],
[CommentsEvent::EVENT_ADD]
['delete'],
['update'],
['pre_update'],
['add']
];
}
@@ -65,14 +69,12 @@ class EventHandlerTest extends TestCase {
->method('getObjectType')
->willReturn('files');
/** @var CommentsEvent|MockObject $event */
$event = $this->createMock(CommentsEvent::class);
$event->expects($this->atLeastOnce())
->method('getComment')
->willReturn($comment);
$event->expects($this->atLeastOnce())
->method('getEvent')
->willReturn($eventType);
$event = match ($eventType) {
'add' => new CommentAddedEvent($comment),
'pre_update' => new BeforeCommentUpdatedEvent($comment),
'update' => new CommentUpdatedEvent($comment),
'delete' => new CommentDeletedEvent($comment),
};
$this->notificationListener->expects($this->once())
->method('evaluate')
@@ -8,7 +8,10 @@
namespace OCA\Comments\Tests\Unit\Notification;
use OCA\Comments\Notification\Listener;
use OCP\Comments\CommentsEvent;
use OCP\Comments\Events\BeforeCommentUpdatedEvent;
use OCP\Comments\Events\CommentAddedEvent;
use OCP\Comments\Events\CommentDeletedEvent;
use OCP\Comments\Events\CommentUpdatedEvent;
use OCP\Comments\IComment;
use OCP\IURLGenerator;
use OCP\IUserManager;
@@ -37,10 +40,10 @@ class ListenerTest extends TestCase {
public static function eventProvider(): array {
return [
[CommentsEvent::EVENT_ADD, 'notify'],
[CommentsEvent::EVENT_UPDATE, 'notify'],
[CommentsEvent::EVENT_PRE_UPDATE, 'markProcessed'],
[CommentsEvent::EVENT_DELETE, 'markProcessed']
['add', 'notify'],
['update', 'notify'],
['pre_update', 'markProcessed'],
['delete', 'markProcessed']
];
}
@@ -49,7 +52,7 @@ class ListenerTest extends TestCase {
* @param string $notificationMethod
*/
#[\PHPUnit\Framework\Attributes\DataProvider('eventProvider')]
public function testEvaluate($eventType, $notificationMethod): void {
public function testEvaluate(string $eventType, $notificationMethod): void {
/** @var IComment|MockObject $comment */
$comment = $this->createMock(IComment::class);
$comment->expects($this->any())
@@ -72,14 +75,12 @@ class ListenerTest extends TestCase {
->method('getId')
->willReturn('1234');
/** @var CommentsEvent|MockObject $event */
$event = $this->createMock(CommentsEvent::class);
$event->expects($this->once())
->method('getComment')
->willReturn($comment);
$event->expects(($this->any()))
->method(('getEvent'))
->willReturn($eventType);
$event = match ($eventType) {
'add' => new CommentAddedEvent($comment),
'pre_update' => new BeforeCommentUpdatedEvent($comment),
'update' => new CommentUpdatedEvent($comment),
'delete' => new CommentDeletedEvent($comment),
};
/** @var INotification|MockObject $notification */
$notification = $this->createMock(INotification::class);
@@ -124,14 +125,12 @@ class ListenerTest extends TestCase {
->method('getMentions')
->willReturn([]);
/** @var CommentsEvent|MockObject $event */
$event = $this->createMock(CommentsEvent::class);
$event->expects($this->once())
->method('getComment')
->willReturn($comment);
$event->expects(($this->any()))
->method(('getEvent'))
->willReturn($eventType);
$event = match ($eventType) {
'add' => new CommentAddedEvent($comment),
'pre_update' => new BeforeCommentUpdatedEvent($comment),
'update' => new CommentUpdatedEvent($comment),
'delete' => new CommentDeletedEvent($comment),
};
$this->notificationManager->expects($this->never())
->method('createNotification');
@@ -162,14 +161,7 @@ class ListenerTest extends TestCase {
->method('getId')
->willReturn('1234');
/** @var CommentsEvent|MockObject $event */
$event = $this->createMock(CommentsEvent::class);
$event->expects($this->once())
->method('getComment')
->willReturn($comment);
$event->expects(($this->any()))
->method(('getEvent'))
->willReturn(CommentsEvent::EVENT_ADD);
$event = new CommentAddedEvent($comment);
/** @var INotification|MockObject $notification */
$notification = $this->createMock(INotification::class);
@@ -7,14 +7,14 @@ namespace Composer\Autoload;
class ComposerStaticInitContactsInteraction
{
public static $prefixLengthsPsr4 = array (
'O' =>
'O' =>
array (
'OCA\\ContactsInteraction\\' => 24,
),
);
public static $prefixDirsPsr4 = array (
'OCA\\ContactsInteraction\\' =>
'OCA\\ContactsInteraction\\' =>
array (
0 => __DIR__ . '/..' . '/../lib',
),
@@ -7,14 +7,14 @@ namespace Composer\Autoload;
class ComposerStaticInitDashboard
{
public static $prefixLengthsPsr4 = array (
'O' =>
'O' =>
array (
'OCA\\Dashboard\\' => 14,
),
);
public static $prefixDirsPsr4 = array (
'OCA\\Dashboard\\' =>
'OCA\\Dashboard\\' =>
array (
0 => __DIR__ . '/..' . '/../lib',
),
+1 -1
View File
@@ -10,7 +10,7 @@
<name>WebDAV</name>
<summary>WebDAV endpoint</summary>
<description>WebDAV endpoint</description>
<version>1.35.0</version>
<version>1.36.0</version>
<licence>agpl</licence>
<author>owncloud.org</author>
<namespace>DAV</namespace>
+46 -38
View File
@@ -68,47 +68,55 @@ $requestUri = Server::get(IRequest::class)->getRequestUri();
$linkCheckPlugin = new PublicLinkCheckPlugin();
$filesDropPlugin = new FilesDropPlugin();
$server = $serverFactory->createServer(false, $baseuri, $requestUri, $authPlugin, function (\Sabre\DAV\Server $server) use ($authBackend, $linkCheckPlugin, $filesDropPlugin) {
$isAjax = in_array('XMLHttpRequest', explode(',', $_SERVER['HTTP_X_REQUESTED_WITH'] ?? ''));
/** @var FederatedShareProvider $shareProvider */
$federatedShareProvider = Server::get(FederatedShareProvider::class);
if ($federatedShareProvider->isOutgoingServer2serverShareEnabled() === false && !$isAjax) {
// this is what is thrown when trying to access a non-existing share
throw new \Sabre\DAV\Exception\NotAuthenticated();
}
$server = $serverFactory->createServer(
true,
$baseuri,
$requestUri,
$authPlugin,
function (\Sabre\DAV\Server $server) use (
$authBackend,
$linkCheckPlugin,
$filesDropPlugin
) {
$isAjax = in_array('XMLHttpRequest', explode(',', $_SERVER['HTTP_X_REQUESTED_WITH'] ?? ''));
/** @var FederatedShareProvider $shareProvider */
$federatedShareProvider = Server::get(FederatedShareProvider::class);
if ($federatedShareProvider->isOutgoingServer2serverShareEnabled() === false && !$isAjax) {
// this is what is thrown when trying to access a non-existing share
throw new \Sabre\DAV\Exception\NotAuthenticated();
}
$share = $authBackend->getShare();
$owner = $share->getShareOwner();
$isReadable = $share->getPermissions() & Constants::PERMISSION_READ;
$fileId = $share->getNodeId();
$share = $authBackend->getShare();
$owner = $share->getShareOwner();
$isReadable = $share->getPermissions() & Constants::PERMISSION_READ;
$fileId = $share->getNodeId();
// FIXME: should not add storage wrappers outside of preSetup, need to find a better way
$previousLog = Filesystem::logWarningWhenAddingStorageWrapper(false);
Filesystem::addStorageWrapper('sharePermissions', function ($mountPoint, $storage) use ($share) {
return new PermissionsMask(['storage' => $storage, 'mask' => $share->getPermissions() | Constants::PERMISSION_SHARE]);
// FIXME: should not add storage wrappers outside of preSetup, need to find a better way
$previousLog = Filesystem::logWarningWhenAddingStorageWrapper(false);
Filesystem::addStorageWrapper('sharePermissions', function ($mountPoint, $storage) use ($share) {
return new PermissionsMask(['storage' => $storage, 'mask' => $share->getPermissions() | Constants::PERMISSION_SHARE]);
});
Filesystem::addStorageWrapper('shareOwner', function ($mountPoint, $storage) use ($share) {
return new PublicOwnerWrapper(['storage' => $storage, 'owner' => $share->getShareOwner()]);
});
Filesystem::logWarningWhenAddingStorageWrapper($previousLog);
$rootFolder = Server::get(IRootFolder::class);
$userFolder = $rootFolder->getUserFolder($owner);
$node = $userFolder->getFirstNodeById($fileId);
if (!$node) {
throw new \Sabre\DAV\Exception\NotFound();
}
$linkCheckPlugin->setFileInfo($node);
// If not readable (files_drop) enable the filesdrop plugin
if (!$isReadable) {
$filesDropPlugin->enable();
}
$filesDropPlugin->setShare($share);
return new View($node->getPath());
});
Filesystem::addStorageWrapper('shareOwner', function ($mountPoint, $storage) use ($share) {
return new PublicOwnerWrapper(['storage' => $storage, 'owner' => $share->getShareOwner()]);
});
Filesystem::logWarningWhenAddingStorageWrapper($previousLog);
$rootFolder = Server::get(IRootFolder::class);
$userFolder = $rootFolder->getUserFolder($owner);
$node = $userFolder->getFirstNodeById($fileId);
if (!$node) {
throw new \Sabre\DAV\Exception\NotFound();
}
$linkCheckPlugin->setFileInfo($node);
// If not readable (files_drop) enable the filesdrop plugin
if (!$isReadable) {
$filesDropPlugin->enable();
}
$filesDropPlugin->setShare($share);
$view = new View($node->getPath());
return $view;
});
$server->addPlugin($linkCheckPlugin);
$server->addPlugin($filesDropPlugin);
@@ -386,6 +386,7 @@ return array(
'OCA\\DAV\\Migration\\Version1031Date20240610134258' => $baseDir . '/../lib/Migration/Version1031Date20240610134258.php',
'OCA\\DAV\\Migration\\Version1034Date20250605132605' => $baseDir . '/../lib/Migration/Version1034Date20250605132605.php',
'OCA\\DAV\\Migration\\Version1034Date20250813093701' => $baseDir . '/../lib/Migration/Version1034Date20250813093701.php',
'OCA\\DAV\\Migration\\Version1036Date20251202000000' => $baseDir . '/../lib/Migration/Version1036Date20251202000000.php',
'OCA\\DAV\\Model\\ExampleEvent' => $baseDir . '/../lib/Model/ExampleEvent.php',
'OCA\\DAV\\Paginate\\LimitedCopyIterator' => $baseDir . '/../lib/Paginate/LimitedCopyIterator.php',
'OCA\\DAV\\Paginate\\PaginateCache' => $baseDir . '/../lib/Paginate/PaginateCache.php',
@@ -7,14 +7,14 @@ namespace Composer\Autoload;
class ComposerStaticInitDAV
{
public static $prefixLengthsPsr4 = array (
'O' =>
'O' =>
array (
'OCA\\DAV\\' => 8,
),
);
public static $prefixDirsPsr4 = array (
'OCA\\DAV\\' =>
'OCA\\DAV\\' =>
array (
0 => __DIR__ . '/..' . '/../lib',
),
@@ -401,6 +401,7 @@ class ComposerStaticInitDAV
'OCA\\DAV\\Migration\\Version1031Date20240610134258' => __DIR__ . '/..' . '/../lib/Migration/Version1031Date20240610134258.php',
'OCA\\DAV\\Migration\\Version1034Date20250605132605' => __DIR__ . '/..' . '/../lib/Migration/Version1034Date20250605132605.php',
'OCA\\DAV\\Migration\\Version1034Date20250813093701' => __DIR__ . '/..' . '/../lib/Migration/Version1034Date20250813093701.php',
'OCA\\DAV\\Migration\\Version1036Date20251202000000' => __DIR__ . '/..' . '/../lib/Migration/Version1036Date20251202000000.php',
'OCA\\DAV\\Model\\ExampleEvent' => __DIR__ . '/..' . '/../lib/Model/ExampleEvent.php',
'OCA\\DAV\\Paginate\\LimitedCopyIterator' => __DIR__ . '/..' . '/../lib/Paginate/LimitedCopyIterator.php',
'OCA\\DAV\\Paginate\\PaginateCache' => __DIR__ . '/..' . '/../lib/Paginate/PaginateCache.php',
+30
View File
@@ -73,7 +73,19 @@ OC.L10N.register(
"Where: %s" : "Dove: %s",
"%1$s via %2$s" : "%1$s tramite %2$s",
"In the past on %1$s for the entire day" : "In passato ogni %1$s per l'intero giorno",
"_In %n minute on %1$s for the entire day_::_In %n minutes on %1$s for the entire day_" : ["Fra %n minuto il %1$s per l'intero giorno","Fra %n minuti il %1$s per l'intero giorno","Fra %n minuti il %1$s per l'intero giorno"],
"_In %n hour on %1$s for the entire day_::_In %n hours on %1$s for the entire day_" : ["Fra %n ora il %1$s per l'intero giorno","Fra %n ore il %1$s per l'intero giorno","Fra %n ore il %1$s per l'intero giorno"],
"_In %n day on %1$s for the entire day_::_In %n days on %1$s for the entire day_" : ["Fra %n giorno il %1$s per l'intero giorno","Fra %n giorni il %1$s per l'intero giorno","Fra %n giorni il %1$s per l'intero giorno"],
"_In %n week on %1$s for the entire day_::_In %n weeks on %1$s for the entire day_" : ["Fra %n settimana il %1$s per l'intero giorno","Fra %n settimane il %1$s per l'intero giorno","Fra %n settimane il %1$s per l'intero giorno"],
"_In %n month on %1$s for the entire day_::_In %n months on %1$s for the entire day_" : ["Fra %n mese il %1$s per l'intero giorno","Fra %n mesi il %1$s per l'intero giorno","Fra %n mesi il %1$s per l'intero giorno"],
"_In %n year on %1$s for the entire day_::_In %n years on %1$s for the entire day_" : ["Fra %n anno di %1$s per l'intero giorno","Fra %n anni di %1$s per l'intero giorno","Fra %n anni di %1$s per l'intero giorno"],
"In the past on %1$s between %2$s - %3$s" : "In passato il %1$s nelle ore %2$s - %3$s",
"_In %n minute on %1$s between %2$s - %3$s_::_In %n minutes on %1$s between %2$s - %3$s_" : ["Fra %n minuto il %1$s nelle ore %2$s - %3$s","Fra %n minuti il %1$s nelle ore %2$s - %3$s","Fra %n minuti il %1$s nelle ore %2$s - %3$s"],
"_In %n hour on %1$s between %2$s - %3$s_::_In %n hours on %1$s between %2$s - %3$s_" : ["Fra %n ora il %1$s nelle ore %2$s - %3$s","Fra %n ore il %1$s nelle ore %2$s - %3$s","Fra %n ore il %1$s nelle ore %2$s - %3$s"],
"_In %n day on %1$s between %2$s - %3$s_::_In %n days on %1$s between %2$s - %3$s_" : ["Fra %n giorno il %1$s nelle ore %2$s - %3$s","Fra %n giorni il %1$s nelle ore %2$s - %3$s","Fra %n giorni il %1$s nelle ore %2$s - %3$s"],
"_In %n week on %1$s between %2$s - %3$s_::_In %n weeks on %1$s between %2$s - %3$s_" : ["Fra %n settimana il %1$s nelle ore %2$s - %3$s","Fra %n settimane il %1$s nelle ore %2$s - %3$s","Fra %n settimane il %1$s nelle ore %2$s - %3$s"],
"_In %n month on %1$s between %2$s - %3$s_::_In %n months on %1$s between %2$s - %3$s_" : ["Fra %n mese il %1$s nelle ore %2$s - %3$s","Fra %n mesi il %1$s nelle ore %2$s - %3$s","Fra %n mesi il %1$s nelle ore %2$s - %3$s"],
"_In %n year on %1$s between %2$s - %3$s_::_In %n years on %1$s between %2$s - %3$s_" : ["Fra %n anno il %1$s nelle ore %2$s - %3$s","Fra %n anni il %1$s nelle ore %2$s - %3$s","Fra %n anni il %1$s nelle ore %2$s - %3$s"],
"Could not generate when statement" : "Impossibile generare l'istruzione \"quando\"",
"Every Day for the entire day" : "Ogni giorno per l'intero giorno",
"Every Day for the entire day until %1$s" : "Ogni Giorno per l'intero giorno fino a %1$s",
@@ -111,8 +123,26 @@ OC.L10N.register(
"On specific dates for the entire day until %1$s" : "In una specifica data per l'intero giorno fino al %1$s",
"On specific dates between %1$s - %2$s until %3$s" : "In una specifica data nelle ore %1$s - %2$s fino al %3$s",
"In the past on %1$s" : "In passato il %1$s",
"_In %n minute on %1$s_::_In %n minutes on %1$s_" : ["Fra %n minuto il %1$s","Fra %n minuti il %1$s","Fra %n minuti il %1$s"],
"_In %n hour on %1$s_::_In %n hours on %1$s_" : ["Fra %n ora il %1$s","Fra %n ore il %1$s","Fra %n ore il %1$s"],
"_In %n day on %1$s_::_In %n days on %1$s_" : ["Fra %n giorno il %1$s","Fra %n giorni il %1$s","Fra %n giorni il %1$s"],
"_In %n week on %1$s_::_In %n weeks on %1$s_" : ["Fra %n settimana il %1$s","Fra %n settimane il %1$s","Fra %n settimane il %1$s"],
"_In %n month on %1$s_::_In %n months on %1$s_" : ["Fra %n mese il %1$s","Fra %n mesi il %1$s","Fra %n mesi il %1$s"],
"_In %n year on %1$s_::_In %n years on %1$s_" : ["Fra %n anno il %1$s","Fra %n anni il %1$s","Fra %n anni il %1$s"],
"In the past on %1$s then on %2$s" : "In passato il %1$s successivamente il %2$s",
"_In %n minute on %1$s then on %2$s_::_In %n minutes on %1$s then on %2$s_" : ["Fra %n minuto %1$s successivamente il %2$s","Fra %n minuti %1$s successivamente il %2$s","Fra %n minuti %1$s successivamente il %2$s"],
"_In %n hour on %1$s then on %2$s_::_In %n hours on %1$s then on %2$s_" : ["Fra %n ora %1$s successivamente il %2$s","Fra %n ore %1$s successivamente il %2$s","Fra %n ore %1$s successivamente il %2$s"],
"_In %n day on %1$s then on %2$s_::_In %n days on %1$s then on %2$s_" : ["Fra %n giorno %1$s successivamente il %2$s","Fra %n giorni %1$s successivamente il %2$s","Fra %n giorni %1$s successivamente il %2$s"],
"_In %n week on %1$s then on %2$s_::_In %n weeks on %1$s then on %2$s_" : ["Fra %n settimana %1$s successivamente il %2$s","Fra %n settimane %1$s successivamente il %2$s","Fra %n settimane %1$s successivamente il %2$s"],
"_In %n month on %1$s then on %2$s_::_In %n months on %1$s then on %2$s_" : ["Fra %n mese %1$s successivamente il %2$s","Fra %n mesi %1$s successivamente il %2$s","Fra %n mesi %1$s successivamente il %2$s"],
"_In %n year on %1$s then on %2$s_::_In %n years on %1$s then on %2$s_" : ["Fra %n anno %1$s successivamente il %2$s","Fra %n anni %1$s successivamente il %2$s","Fra %n anni %1$s successivamente il %2$s"],
"In the past on %1$s then on %2$s and %3$s" : "In passato il %1$s successivamente il %2$s e %3$s",
"_In %n minute on %1$s then on %2$s and %3$s_::_In %n minutes on %1$s then on %2$s and %3$s_" : ["Fra %n minuto il %1$s successivamente il %2$s e %3$s","Fra %n minuti il %1$s successivamente il %2$s e %3$s","Fra %n minuti il %1$s successivamente il %2$s e %3$s"],
"_In %n hour on %1$s then on %2$s and %3$s_::_In %n hours on %1$s then on %2$s and %3$s_" : ["Fra %n ora il %1$s successivamente il %2$s e %3$s","Fra %n ore il %1$s successivamente il %2$s e %3$s","Fra %n ore il %1$s successivamente il %2$s e %3$s"],
"_In %n day on %1$s then on %2$s and %3$s_::_In %n days on %1$s then on %2$s and %3$s_" : ["Fra %n giorno il %1$s successivamente il %2$s e %3$s","Fra %n giorni il %1$s successivamente il %2$s e %3$s","Fra %n giorni il %1$s successivamente il %2$s e %3$s"],
"_In %n week on %1$s then on %2$s and %3$s_::_In %n weeks on %1$s then on %2$s and %3$s_" : ["Fra %n settimana il %1$s successivamente il %2$s e %3$s","Fra %n settimane il %1$s successivamente il %2$s e %3$s","Fra %n settimane il %1$s successivamente il %2$s e %3$s"],
"_In %n month on %1$s then on %2$s and %3$s_::_In %n months on %1$s then on %2$s and %3$s_" : ["Fra %n mese il %1$s successivamente il %2$s e %3$s","Fra %n mesi il %1$s successivamente il %2$s e %3$s","Fra %n mesi il %1$s successivamente il %2$s e %3$s"],
"_In %n year on %1$s then on %2$s and %3$s_::_In %n years on %1$s then on %2$s and %3$s_" : ["Fra %n anno il %1$s successivamente il %2$s e %3$s","Fra %n anni il %1$s successivamente il %2$s e %3$s","Fra %n anni il %1$s successivamente il %2$s e %3$s"],
"Could not generate next recurrence statement" : "Impossibile generare l'istruzione della prossima ricorrenza ",
"Cancelled: %1$s" : "Annullato: %1$s",
"\"%1$s\" has been canceled" : "\"%1$s\" è stato annullato",
+30
View File
@@ -71,7 +71,19 @@
"Where: %s" : "Dove: %s",
"%1$s via %2$s" : "%1$s tramite %2$s",
"In the past on %1$s for the entire day" : "In passato ogni %1$s per l'intero giorno",
"_In %n minute on %1$s for the entire day_::_In %n minutes on %1$s for the entire day_" : ["Fra %n minuto il %1$s per l'intero giorno","Fra %n minuti il %1$s per l'intero giorno","Fra %n minuti il %1$s per l'intero giorno"],
"_In %n hour on %1$s for the entire day_::_In %n hours on %1$s for the entire day_" : ["Fra %n ora il %1$s per l'intero giorno","Fra %n ore il %1$s per l'intero giorno","Fra %n ore il %1$s per l'intero giorno"],
"_In %n day on %1$s for the entire day_::_In %n days on %1$s for the entire day_" : ["Fra %n giorno il %1$s per l'intero giorno","Fra %n giorni il %1$s per l'intero giorno","Fra %n giorni il %1$s per l'intero giorno"],
"_In %n week on %1$s for the entire day_::_In %n weeks on %1$s for the entire day_" : ["Fra %n settimana il %1$s per l'intero giorno","Fra %n settimane il %1$s per l'intero giorno","Fra %n settimane il %1$s per l'intero giorno"],
"_In %n month on %1$s for the entire day_::_In %n months on %1$s for the entire day_" : ["Fra %n mese il %1$s per l'intero giorno","Fra %n mesi il %1$s per l'intero giorno","Fra %n mesi il %1$s per l'intero giorno"],
"_In %n year on %1$s for the entire day_::_In %n years on %1$s for the entire day_" : ["Fra %n anno di %1$s per l'intero giorno","Fra %n anni di %1$s per l'intero giorno","Fra %n anni di %1$s per l'intero giorno"],
"In the past on %1$s between %2$s - %3$s" : "In passato il %1$s nelle ore %2$s - %3$s",
"_In %n minute on %1$s between %2$s - %3$s_::_In %n minutes on %1$s between %2$s - %3$s_" : ["Fra %n minuto il %1$s nelle ore %2$s - %3$s","Fra %n minuti il %1$s nelle ore %2$s - %3$s","Fra %n minuti il %1$s nelle ore %2$s - %3$s"],
"_In %n hour on %1$s between %2$s - %3$s_::_In %n hours on %1$s between %2$s - %3$s_" : ["Fra %n ora il %1$s nelle ore %2$s - %3$s","Fra %n ore il %1$s nelle ore %2$s - %3$s","Fra %n ore il %1$s nelle ore %2$s - %3$s"],
"_In %n day on %1$s between %2$s - %3$s_::_In %n days on %1$s between %2$s - %3$s_" : ["Fra %n giorno il %1$s nelle ore %2$s - %3$s","Fra %n giorni il %1$s nelle ore %2$s - %3$s","Fra %n giorni il %1$s nelle ore %2$s - %3$s"],
"_In %n week on %1$s between %2$s - %3$s_::_In %n weeks on %1$s between %2$s - %3$s_" : ["Fra %n settimana il %1$s nelle ore %2$s - %3$s","Fra %n settimane il %1$s nelle ore %2$s - %3$s","Fra %n settimane il %1$s nelle ore %2$s - %3$s"],
"_In %n month on %1$s between %2$s - %3$s_::_In %n months on %1$s between %2$s - %3$s_" : ["Fra %n mese il %1$s nelle ore %2$s - %3$s","Fra %n mesi il %1$s nelle ore %2$s - %3$s","Fra %n mesi il %1$s nelle ore %2$s - %3$s"],
"_In %n year on %1$s between %2$s - %3$s_::_In %n years on %1$s between %2$s - %3$s_" : ["Fra %n anno il %1$s nelle ore %2$s - %3$s","Fra %n anni il %1$s nelle ore %2$s - %3$s","Fra %n anni il %1$s nelle ore %2$s - %3$s"],
"Could not generate when statement" : "Impossibile generare l'istruzione \"quando\"",
"Every Day for the entire day" : "Ogni giorno per l'intero giorno",
"Every Day for the entire day until %1$s" : "Ogni Giorno per l'intero giorno fino a %1$s",
@@ -109,8 +121,26 @@
"On specific dates for the entire day until %1$s" : "In una specifica data per l'intero giorno fino al %1$s",
"On specific dates between %1$s - %2$s until %3$s" : "In una specifica data nelle ore %1$s - %2$s fino al %3$s",
"In the past on %1$s" : "In passato il %1$s",
"_In %n minute on %1$s_::_In %n minutes on %1$s_" : ["Fra %n minuto il %1$s","Fra %n minuti il %1$s","Fra %n minuti il %1$s"],
"_In %n hour on %1$s_::_In %n hours on %1$s_" : ["Fra %n ora il %1$s","Fra %n ore il %1$s","Fra %n ore il %1$s"],
"_In %n day on %1$s_::_In %n days on %1$s_" : ["Fra %n giorno il %1$s","Fra %n giorni il %1$s","Fra %n giorni il %1$s"],
"_In %n week on %1$s_::_In %n weeks on %1$s_" : ["Fra %n settimana il %1$s","Fra %n settimane il %1$s","Fra %n settimane il %1$s"],
"_In %n month on %1$s_::_In %n months on %1$s_" : ["Fra %n mese il %1$s","Fra %n mesi il %1$s","Fra %n mesi il %1$s"],
"_In %n year on %1$s_::_In %n years on %1$s_" : ["Fra %n anno il %1$s","Fra %n anni il %1$s","Fra %n anni il %1$s"],
"In the past on %1$s then on %2$s" : "In passato il %1$s successivamente il %2$s",
"_In %n minute on %1$s then on %2$s_::_In %n minutes on %1$s then on %2$s_" : ["Fra %n minuto %1$s successivamente il %2$s","Fra %n minuti %1$s successivamente il %2$s","Fra %n minuti %1$s successivamente il %2$s"],
"_In %n hour on %1$s then on %2$s_::_In %n hours on %1$s then on %2$s_" : ["Fra %n ora %1$s successivamente il %2$s","Fra %n ore %1$s successivamente il %2$s","Fra %n ore %1$s successivamente il %2$s"],
"_In %n day on %1$s then on %2$s_::_In %n days on %1$s then on %2$s_" : ["Fra %n giorno %1$s successivamente il %2$s","Fra %n giorni %1$s successivamente il %2$s","Fra %n giorni %1$s successivamente il %2$s"],
"_In %n week on %1$s then on %2$s_::_In %n weeks on %1$s then on %2$s_" : ["Fra %n settimana %1$s successivamente il %2$s","Fra %n settimane %1$s successivamente il %2$s","Fra %n settimane %1$s successivamente il %2$s"],
"_In %n month on %1$s then on %2$s_::_In %n months on %1$s then on %2$s_" : ["Fra %n mese %1$s successivamente il %2$s","Fra %n mesi %1$s successivamente il %2$s","Fra %n mesi %1$s successivamente il %2$s"],
"_In %n year on %1$s then on %2$s_::_In %n years on %1$s then on %2$s_" : ["Fra %n anno %1$s successivamente il %2$s","Fra %n anni %1$s successivamente il %2$s","Fra %n anni %1$s successivamente il %2$s"],
"In the past on %1$s then on %2$s and %3$s" : "In passato il %1$s successivamente il %2$s e %3$s",
"_In %n minute on %1$s then on %2$s and %3$s_::_In %n minutes on %1$s then on %2$s and %3$s_" : ["Fra %n minuto il %1$s successivamente il %2$s e %3$s","Fra %n minuti il %1$s successivamente il %2$s e %3$s","Fra %n minuti il %1$s successivamente il %2$s e %3$s"],
"_In %n hour on %1$s then on %2$s and %3$s_::_In %n hours on %1$s then on %2$s and %3$s_" : ["Fra %n ora il %1$s successivamente il %2$s e %3$s","Fra %n ore il %1$s successivamente il %2$s e %3$s","Fra %n ore il %1$s successivamente il %2$s e %3$s"],
"_In %n day on %1$s then on %2$s and %3$s_::_In %n days on %1$s then on %2$s and %3$s_" : ["Fra %n giorno il %1$s successivamente il %2$s e %3$s","Fra %n giorni il %1$s successivamente il %2$s e %3$s","Fra %n giorni il %1$s successivamente il %2$s e %3$s"],
"_In %n week on %1$s then on %2$s and %3$s_::_In %n weeks on %1$s then on %2$s and %3$s_" : ["Fra %n settimana il %1$s successivamente il %2$s e %3$s","Fra %n settimane il %1$s successivamente il %2$s e %3$s","Fra %n settimane il %1$s successivamente il %2$s e %3$s"],
"_In %n month on %1$s then on %2$s and %3$s_::_In %n months on %1$s then on %2$s and %3$s_" : ["Fra %n mese il %1$s successivamente il %2$s e %3$s","Fra %n mesi il %1$s successivamente il %2$s e %3$s","Fra %n mesi il %1$s successivamente il %2$s e %3$s"],
"_In %n year on %1$s then on %2$s and %3$s_::_In %n years on %1$s then on %2$s and %3$s_" : ["Fra %n anno il %1$s successivamente il %2$s e %3$s","Fra %n anni il %1$s successivamente il %2$s e %3$s","Fra %n anni il %1$s successivamente il %2$s e %3$s"],
"Could not generate next recurrence statement" : "Impossibile generare l'istruzione della prossima ricorrenza ",
"Cancelled: %1$s" : "Annullato: %1$s",
"\"%1$s\" has been canceled" : "\"%1$s\" è stato annullato",
+30
View File
@@ -73,7 +73,19 @@ OC.L10N.register(
"Where: %s" : "Wapi: %s",
"%1$s via %2$s" : "%1$skupitia %2$s",
"In the past on %1$s for the entire day" : "Hapo awali kwenye %1$s kwa siku nzima",
"_In %n minute on %1$s for the entire day_::_In %n minutes on %1$s for the entire day_" : ["In %n minute on %1$s for the entire day","Baada ya dakika %n kwenye %1$s kwa siku nzima"],
"_In %n hour on %1$s for the entire day_::_In %n hours on %1$s for the entire day_" : ["In %n hour on %1$s for the entire day","Baada ya saa %n kwenye %1$s kwa siku nzima"],
"_In %n day on %1$s for the entire day_::_In %n days on %1$s for the entire day_" : ["In %n day on %1$s for the entire day","Baada ya siku %n tarehe %1$s kwa siku nzima"],
"_In %n week on %1$s for the entire day_::_In %n weeks on %1$s for the entire day_" : ["In %n week on %1$s for the entire day","Baada ya wiki %n mnamo %1$s kwa siku nzima"],
"_In %n month on %1$s for the entire day_::_In %n months on %1$s for the entire day_" : ["In %n month on %1$s for the entire day","Baada ya miezi %n mnamo %1$s kwa siku nzima"],
"_In %n year on %1$s for the entire day_::_In %n years on %1$s for the entire day_" : ["In %n year on %1$s for the entire day","Katika miaka %n kwenye %1$s kwa siku nzima"],
"In the past on %1$s between %2$s - %3$s" : "Hapo awali kwenye %1$s kati ya %2$s - %3$s",
"_In %n minute on %1$s between %2$s - %3$s_::_In %n minutes on %1$s between %2$s - %3$s_" : ["In %n minute on %1$s between %2$s - %3$s","Baada ya dakika %n kwenye %1$s kati ya %2$s - %3$s"],
"_In %n hour on %1$s between %2$s - %3$s_::_In %n hours on %1$s between %2$s - %3$s_" : ["In %n hour on %1$s between %2$s - %3$s","Baada ya saa %n kwenye %1$s kati ya %2$s - %3$s"],
"_In %n day on %1$s between %2$s - %3$s_::_In %n days on %1$s between %2$s - %3$s_" : ["In %n day on %1$s between %2$s - %3$s","Katika siku %n mnamo %1$s kati ya %2$s - %3$s"],
"_In %n week on %1$s between %2$s - %3$s_::_In %n weeks on %1$s between %2$s - %3$s_" : ["In %n week on %1$s between %2$s - %3$s","Katika wiki %n mnamo %1$s kati ya %2$s - %3$s"],
"_In %n month on %1$s between %2$s - %3$s_::_In %n months on %1$s between %2$s - %3$s_" : ["In %n month on %1$s between %2$s - %3$s","Katika miezi %n tarehe %1$s kati ya %2$s - %3$s"],
"_In %n year on %1$s between %2$s - %3$s_::_In %n years on %1$s between %2$s - %3$s_" : ["In %n year on %1$s between %2$s - %3$s","Katika miaka %n kwenye %1$s kati ya %2$s - %3$s"],
"Could not generate when statement" : "Haikuweza kuzalisha taarifa ya lini",
"Every Day for the entire day" : "Kila Siku kwa siku nzima",
"Every Day for the entire day until %1$s" : "Kila Siku kwa siku nzima hadi %1$s",
@@ -111,8 +123,26 @@ OC.L10N.register(
"On specific dates for the entire day until %1$s" : "Kwa tarehe mahususi kwa siku nzima hadi %1$s ",
"On specific dates between %1$s - %2$s until %3$s" : "Katika tarehe mahususi kati ya %1$s - %2$s hadi %3$s",
"In the past on %1$s" : "Hapo awali kwenye %1$s",
"_In %n minute on %1$s_::_In %n minutes on %1$s_" : ["In %n minute on %1$s","Baada ya dakika %n kwenye %1$s"],
"_In %n hour on %1$s_::_In %n hours on %1$s_" : ["In %n hour on %1$s","Baada ya saa %n kwenye %1$s"],
"_In %n day on %1$s_::_In %n days on %1$s_" : ["In %n day on %1$s","Baada ya siku %n tarehe %1$s"],
"_In %n week on %1$s_::_In %n weeks on %1$s_" : ["In %n week on %1$s","Baada ya wiki %n tarehe %1$s"],
"_In %n month on %1$s_::_In %n months on %1$s_" : ["In %n month on %1$s","Baada ya miezi %n tarehe %1$s"],
"_In %n year on %1$s_::_In %n years on %1$s_" : ["In %n year on %1$s","Katika miaka %n tarehe %1$s"],
"In the past on %1$s then on %2$s" : "Hapo awali kwenye %1$s kisha kwenye %2$s",
"_In %n minute on %1$s then on %2$s_::_In %n minutes on %1$s then on %2$s_" : ["In %n minute on %1$s then on %2$s","Baada ya dakika %n kwenye %1$s kisha %2$s"],
"_In %n hour on %1$s then on %2$s_::_In %n hours on %1$s then on %2$s_" : ["In %n hour on %1$s then on %2$s","Baada ya saa %n kwenye %1$s kisha %2$s"],
"_In %n day on %1$s then on %2$s_::_In %n days on %1$s then on %2$s_" : ["In %n day on %1$s then on %2$s","Baada ya siku %n mnamo %1$s kisha %2$s"],
"_In %n week on %1$s then on %2$s_::_In %n weeks on %1$s then on %2$s_" : ["In %n week on %1$s then on %2$s","Baada ya wiki %n mnamo %1$s kisha %2$s"],
"_In %n month on %1$s then on %2$s_::_In %n months on %1$s then on %2$s_" : ["In %n month on %1$s then on %2$s","Baada ya miezi %n mnamo %1$s kisha %2$s"],
"_In %n year on %1$s then on %2$s_::_In %n years on %1$s then on %2$s_" : ["In %n year on %1$s then on %2$s","Katika miaka %n kwenye %1$s kisha %2$s"],
"In the past on %1$s then on %2$s and %3$s" : "Hapo awali kwenye %1$s kisha kwenye %2$s na %3$s",
"_In %n minute on %1$s then on %2$s and %3$s_::_In %n minutes on %1$s then on %2$s and %3$s_" : ["In %n minute on %1$s then on %2$s and %3$s","Baada ya dakika %n kwenye %1$s kisha %2$s na %3$s"],
"_In %n hour on %1$s then on %2$s and %3$s_::_In %n hours on %1$s then on %2$s and %3$s_" : ["In %n hour on %1$s then on %2$s and %3$s","Baada ya saa %n kwenye %1$s kisha %2$s na %3$s"],
"_In %n day on %1$s then on %2$s and %3$s_::_In %n days on %1$s then on %2$s and %3$s_" : ["In %n day on %1$s then on %2$s and %3$s","Baada ya siku %n mnamo %1$s kisha %2$s na %3$s"],
"_In %n week on %1$s then on %2$s and %3$s_::_In %n weeks on %1$s then on %2$s and %3$s_" : ["In %n week on %1$s then on %2$s and %3$s","Baada ya wiki %n %1$s kisha %2$s na %3$s"],
"_In %n month on %1$s then on %2$s and %3$s_::_In %n months on %1$s then on %2$s and %3$s_" : ["In %n month on %1$s then on %2$s and %3$s","Baada ya miezi %n kwenye %1$s kisha %2$s na %3$s"],
"_In %n year on %1$s then on %2$s and %3$s_::_In %n years on %1$s then on %2$s and %3$s_" : ["In %n year on %1$s then on %2$s and %3$s","Katika miaka %n kwenye %1$s kisha %2$s na %3$s"],
"Could not generate next recurrence statement" : "Haikuweza kutoa taarifa inayofuata ya kujirudia",
"Cancelled: %1$s" : "Imeghairiwa: %1$s ",
"\"%1$s\" has been canceled" : "\"%1$s\" imeghairiwa",
+30
View File
@@ -71,7 +71,19 @@
"Where: %s" : "Wapi: %s",
"%1$s via %2$s" : "%1$skupitia %2$s",
"In the past on %1$s for the entire day" : "Hapo awali kwenye %1$s kwa siku nzima",
"_In %n minute on %1$s for the entire day_::_In %n minutes on %1$s for the entire day_" : ["In %n minute on %1$s for the entire day","Baada ya dakika %n kwenye %1$s kwa siku nzima"],
"_In %n hour on %1$s for the entire day_::_In %n hours on %1$s for the entire day_" : ["In %n hour on %1$s for the entire day","Baada ya saa %n kwenye %1$s kwa siku nzima"],
"_In %n day on %1$s for the entire day_::_In %n days on %1$s for the entire day_" : ["In %n day on %1$s for the entire day","Baada ya siku %n tarehe %1$s kwa siku nzima"],
"_In %n week on %1$s for the entire day_::_In %n weeks on %1$s for the entire day_" : ["In %n week on %1$s for the entire day","Baada ya wiki %n mnamo %1$s kwa siku nzima"],
"_In %n month on %1$s for the entire day_::_In %n months on %1$s for the entire day_" : ["In %n month on %1$s for the entire day","Baada ya miezi %n mnamo %1$s kwa siku nzima"],
"_In %n year on %1$s for the entire day_::_In %n years on %1$s for the entire day_" : ["In %n year on %1$s for the entire day","Katika miaka %n kwenye %1$s kwa siku nzima"],
"In the past on %1$s between %2$s - %3$s" : "Hapo awali kwenye %1$s kati ya %2$s - %3$s",
"_In %n minute on %1$s between %2$s - %3$s_::_In %n minutes on %1$s between %2$s - %3$s_" : ["In %n minute on %1$s between %2$s - %3$s","Baada ya dakika %n kwenye %1$s kati ya %2$s - %3$s"],
"_In %n hour on %1$s between %2$s - %3$s_::_In %n hours on %1$s between %2$s - %3$s_" : ["In %n hour on %1$s between %2$s - %3$s","Baada ya saa %n kwenye %1$s kati ya %2$s - %3$s"],
"_In %n day on %1$s between %2$s - %3$s_::_In %n days on %1$s between %2$s - %3$s_" : ["In %n day on %1$s between %2$s - %3$s","Katika siku %n mnamo %1$s kati ya %2$s - %3$s"],
"_In %n week on %1$s between %2$s - %3$s_::_In %n weeks on %1$s between %2$s - %3$s_" : ["In %n week on %1$s between %2$s - %3$s","Katika wiki %n mnamo %1$s kati ya %2$s - %3$s"],
"_In %n month on %1$s between %2$s - %3$s_::_In %n months on %1$s between %2$s - %3$s_" : ["In %n month on %1$s between %2$s - %3$s","Katika miezi %n tarehe %1$s kati ya %2$s - %3$s"],
"_In %n year on %1$s between %2$s - %3$s_::_In %n years on %1$s between %2$s - %3$s_" : ["In %n year on %1$s between %2$s - %3$s","Katika miaka %n kwenye %1$s kati ya %2$s - %3$s"],
"Could not generate when statement" : "Haikuweza kuzalisha taarifa ya lini",
"Every Day for the entire day" : "Kila Siku kwa siku nzima",
"Every Day for the entire day until %1$s" : "Kila Siku kwa siku nzima hadi %1$s",
@@ -109,8 +121,26 @@
"On specific dates for the entire day until %1$s" : "Kwa tarehe mahususi kwa siku nzima hadi %1$s ",
"On specific dates between %1$s - %2$s until %3$s" : "Katika tarehe mahususi kati ya %1$s - %2$s hadi %3$s",
"In the past on %1$s" : "Hapo awali kwenye %1$s",
"_In %n minute on %1$s_::_In %n minutes on %1$s_" : ["In %n minute on %1$s","Baada ya dakika %n kwenye %1$s"],
"_In %n hour on %1$s_::_In %n hours on %1$s_" : ["In %n hour on %1$s","Baada ya saa %n kwenye %1$s"],
"_In %n day on %1$s_::_In %n days on %1$s_" : ["In %n day on %1$s","Baada ya siku %n tarehe %1$s"],
"_In %n week on %1$s_::_In %n weeks on %1$s_" : ["In %n week on %1$s","Baada ya wiki %n tarehe %1$s"],
"_In %n month on %1$s_::_In %n months on %1$s_" : ["In %n month on %1$s","Baada ya miezi %n tarehe %1$s"],
"_In %n year on %1$s_::_In %n years on %1$s_" : ["In %n year on %1$s","Katika miaka %n tarehe %1$s"],
"In the past on %1$s then on %2$s" : "Hapo awali kwenye %1$s kisha kwenye %2$s",
"_In %n minute on %1$s then on %2$s_::_In %n minutes on %1$s then on %2$s_" : ["In %n minute on %1$s then on %2$s","Baada ya dakika %n kwenye %1$s kisha %2$s"],
"_In %n hour on %1$s then on %2$s_::_In %n hours on %1$s then on %2$s_" : ["In %n hour on %1$s then on %2$s","Baada ya saa %n kwenye %1$s kisha %2$s"],
"_In %n day on %1$s then on %2$s_::_In %n days on %1$s then on %2$s_" : ["In %n day on %1$s then on %2$s","Baada ya siku %n mnamo %1$s kisha %2$s"],
"_In %n week on %1$s then on %2$s_::_In %n weeks on %1$s then on %2$s_" : ["In %n week on %1$s then on %2$s","Baada ya wiki %n mnamo %1$s kisha %2$s"],
"_In %n month on %1$s then on %2$s_::_In %n months on %1$s then on %2$s_" : ["In %n month on %1$s then on %2$s","Baada ya miezi %n mnamo %1$s kisha %2$s"],
"_In %n year on %1$s then on %2$s_::_In %n years on %1$s then on %2$s_" : ["In %n year on %1$s then on %2$s","Katika miaka %n kwenye %1$s kisha %2$s"],
"In the past on %1$s then on %2$s and %3$s" : "Hapo awali kwenye %1$s kisha kwenye %2$s na %3$s",
"_In %n minute on %1$s then on %2$s and %3$s_::_In %n minutes on %1$s then on %2$s and %3$s_" : ["In %n minute on %1$s then on %2$s and %3$s","Baada ya dakika %n kwenye %1$s kisha %2$s na %3$s"],
"_In %n hour on %1$s then on %2$s and %3$s_::_In %n hours on %1$s then on %2$s and %3$s_" : ["In %n hour on %1$s then on %2$s and %3$s","Baada ya saa %n kwenye %1$s kisha %2$s na %3$s"],
"_In %n day on %1$s then on %2$s and %3$s_::_In %n days on %1$s then on %2$s and %3$s_" : ["In %n day on %1$s then on %2$s and %3$s","Baada ya siku %n mnamo %1$s kisha %2$s na %3$s"],
"_In %n week on %1$s then on %2$s and %3$s_::_In %n weeks on %1$s then on %2$s and %3$s_" : ["In %n week on %1$s then on %2$s and %3$s","Baada ya wiki %n %1$s kisha %2$s na %3$s"],
"_In %n month on %1$s then on %2$s and %3$s_::_In %n months on %1$s then on %2$s and %3$s_" : ["In %n month on %1$s then on %2$s and %3$s","Baada ya miezi %n kwenye %1$s kisha %2$s na %3$s"],
"_In %n year on %1$s then on %2$s and %3$s_::_In %n years on %1$s then on %2$s and %3$s_" : ["In %n year on %1$s then on %2$s and %3$s","Katika miaka %n kwenye %1$s kisha %2$s na %3$s"],
"Could not generate next recurrence statement" : "Haikuweza kutoa taarifa inayofuata ya kujirudia",
"Cancelled: %1$s" : "Imeghairiwa: %1$s ",
"\"%1$s\" has been canceled" : "\"%1$s\" imeghairiwa",
+30
View File
@@ -73,7 +73,19 @@ OC.L10N.register(
"Where: %s" : "Şurada: %s",
"%1$s via %2$s" : "%1$s, %2$s aracılığıyla",
"In the past on %1$s for the entire day" : "Tüm gün boyunca %1$s zamanında geçmişte",
"_In %n minute on %1$s for the entire day_::_In %n minutes on %1$s for the entire day_" : ["Tüm gün boyunca %1$s zamanında %n dakika içinde","Tüm gün boyunca %1$s zamanında %n dakika içinde"],
"_In %n hour on %1$s for the entire day_::_In %n hours on %1$s for the entire day_" : ["Tüm gün boyunca %1$s zamanında %n saat içinde","Tüm gün boyunca %1$s zamanında %n saat içinde"],
"_In %n day on %1$s for the entire day_::_In %n days on %1$s for the entire day_" : ["Tüm gün boyunca %1$s zamanında %n gün içinde","Tüm gün boyunca %1$s zamanında %n gün içinde"],
"_In %n week on %1$s for the entire day_::_In %n weeks on %1$s for the entire day_" : ["Tüm gün boyunca %1$s zamanında %n hafta içinde","Tüm gün boyunca %1$s zamanında %n hafta içinde"],
"_In %n month on %1$s for the entire day_::_In %n months on %1$s for the entire day_" : ["Tüm gün boyunca %1$s zamanında %n ay içinde","Tüm gün boyunca %1$s zamanında %n ay içinde"],
"_In %n year on %1$s for the entire day_::_In %n years on %1$s for the entire day_" : ["Tüm gün boyunca %1$s zamanında %n yıl içinde","Tüm gün boyunca %1$s zamanında %n yıl içinde"],
"In the past on %1$s between %2$s - %3$s" : "Geçmişte %1$s zamanında %2$s ile %3$s arasında",
"_In %n minute on %1$s between %2$s - %3$s_::_In %n minutes on %1$s between %2$s - %3$s_" : ["%n dakika içinde %1$s zamanında %2$s ile %3$s arasında","%n dakika içinde %1$s zamanında %2$s ile %3$s arasında"],
"_In %n hour on %1$s between %2$s - %3$s_::_In %n hours on %1$s between %2$s - %3$s_" : ["%n saat içinde %1$s zamanında %2$s ile %3$s arasında","%n saat içinde %1$s zamanında %2$s ile %3$s arasında"],
"_In %n day on %1$s between %2$s - %3$s_::_In %n days on %1$s between %2$s - %3$s_" : ["%n gün içinde %1$s zamanında %2$s ile %3$s arasında","%n gün içinde %1$s zamanında %2$s ile %3$s arasında"],
"_In %n week on %1$s between %2$s - %3$s_::_In %n weeks on %1$s between %2$s - %3$s_" : ["%n hafta içinde %1$s zamanında %2$s ile %3$s arasında","%n hafta içinde %1$s zamanında %2$s ile %3$s arasında"],
"_In %n month on %1$s between %2$s - %3$s_::_In %n months on %1$s between %2$s - %3$s_" : ["%n ay içinde %1$s zamanında %2$s ile %3$s arasında","%n ay içinde %1$s zamanında %2$s ile %3$s arasında"],
"_In %n year on %1$s between %2$s - %3$s_::_In %n years on %1$s between %2$s - %3$s_" : ["%n yıl içinde %1$s zamanında %2$s ile %3$s arasında","%n yıl içinde %1$s zamanında %2$s ile %3$s arasında"],
"Could not generate when statement" : "Zaman ifadesi oluşturulamadı",
"Every Day for the entire day" : "Her gün tüm gün boyunca",
"Every Day for the entire day until %1$s" : "%1$s zamanına kadar her gün tüm gün boyunca",
@@ -111,8 +123,26 @@ OC.L10N.register(
"On specific dates for the entire day until %1$s" : "Belirli tarihlerde tüm gün boyunca %1$s zamanına kadar",
"On specific dates between %1$s - %2$s until %3$s" : "Belirli tarihlerde %1$s ile %2$s arasında %3$s zamanına kadar",
"In the past on %1$s" : "%1$s zamanında geçmişte",
"_In %n minute on %1$s_::_In %n minutes on %1$s_" : ["%1$s zamanında %n dakika içinde","%1$s zamanında %n dakika içinde"],
"_In %n hour on %1$s_::_In %n hours on %1$s_" : ["%1$s zamanında %n saat içinde","%1$s zamanında %n saat içinde"],
"_In %n day on %1$s_::_In %n days on %1$s_" : ["%1$s zamanında %n gün içinde","%1$s zamanında %n gün içinde"],
"_In %n week on %1$s_::_In %n weeks on %1$s_" : ["%1$s zamanında %n hafta içinde","%1$s zamanında %n hafta içinde"],
"_In %n month on %1$s_::_In %n months on %1$s_" : ["%1$s zamanında %n ay içinde","%1$s zamanında %n ay içinde"],
"_In %n year on %1$s_::_In %n years on %1$s_" : ["%1$s zamanında %n yıl içinde","%1$s zamanında %n yıl içinde"],
"In the past on %1$s then on %2$s" : "Geçmişte %1$s zamanında ardından %2$s zamanında",
"_In %n minute on %1$s then on %2$s_::_In %n minutes on %1$s then on %2$s_" : ["%n dakika içinde %1$s zamanında ardından %2$s zamanında","%n dakika içinde %1$s zamanında ardından %2$s zamanında"],
"_In %n hour on %1$s then on %2$s_::_In %n hours on %1$s then on %2$s_" : ["%n saat içinde %1$s zamanında ardından %2$s zamanında","%n saat içinde %1$s zamanında ardından %2$s zamanında"],
"_In %n day on %1$s then on %2$s_::_In %n days on %1$s then on %2$s_" : ["%n gün içinde %1$s zamanında ardından %2$s zamanında","%n gün içinde %1$s zamanında ardından %2$s zamanında"],
"_In %n week on %1$s then on %2$s_::_In %n weeks on %1$s then on %2$s_" : ["%n hafta içinde %1$s zamanında ardından %2$s zamanında","%n hafta içinde %1$s zamanında ardından %2$s zamanında"],
"_In %n month on %1$s then on %2$s_::_In %n months on %1$s then on %2$s_" : ["%n ay içinde %1$s zamanında ardından %2$s zamanında","%n ay içinde %1$s zamanında ardından %2$s zamanında"],
"_In %n year on %1$s then on %2$s_::_In %n years on %1$s then on %2$s_" : ["%n yıl içinde %1$s zamanında ardından %2$s zamanında","%n yıl içinde %1$s zamanında ardından %2$s zamanında"],
"In the past on %1$s then on %2$s and %3$s" : "Geçmişte %1$s zamanında ardından %2$s ve %3$s zamanında",
"_In %n minute on %1$s then on %2$s and %3$s_::_In %n minutes on %1$s then on %2$s and %3$s_" : ["%n dakika içinde %1$s zamanında ardından %2$s ve %3$s zamanında","%n dakika içinde %1$s zamanında ardından %2$s ve %3$s zamanında"],
"_In %n hour on %1$s then on %2$s and %3$s_::_In %n hours on %1$s then on %2$s and %3$s_" : ["%n dakika içinde %1$s zamanında ardından %2$s ve %3$s zamanında","%n dakika içinde %1$s zamanında ardından %2$s ve %3$s zamanında"],
"_In %n day on %1$s then on %2$s and %3$s_::_In %n days on %1$s then on %2$s and %3$s_" : ["%n dakika içinde %1$s zamanında ardından %2$s ve %3$s zamanında","%n dakika içinde %1$s zamanında ardından %2$s ve %3$s zamanında"],
"_In %n week on %1$s then on %2$s and %3$s_::_In %n weeks on %1$s then on %2$s and %3$s_" : ["%n dakika içinde %1$s zamanında ardından %2$s ve %3$s zamanında","%n dakika içinde %1$s zamanında ardından %2$s ve %3$s zamanında"],
"_In %n month on %1$s then on %2$s and %3$s_::_In %n months on %1$s then on %2$s and %3$s_" : ["%n dakika içinde %1$s zamanında ardından %2$s ve %3$s zamanında","%n dakika içinde %1$s zamanında ardından %2$s ve %3$s zamanında"],
"_In %n year on %1$s then on %2$s and %3$s_::_In %n years on %1$s then on %2$s and %3$s_" : ["%n dakika içinde %1$s zamanında ardından %2$s ve %3$s zamanında","%n dakika içinde %1$s zamanında ardından %2$s ve %3$s zamanında"],
"Could not generate next recurrence statement" : "Sonraki yinelenme ifadesi oluşturulamadı",
"Cancelled: %1$s" : "İptal edildi: %1$s",
"\"%1$s\" has been canceled" : "\"%1$s\" iptal edildi",
+30
View File
@@ -71,7 +71,19 @@
"Where: %s" : "Şurada: %s",
"%1$s via %2$s" : "%1$s, %2$s aracılığıyla",
"In the past on %1$s for the entire day" : "Tüm gün boyunca %1$s zamanında geçmişte",
"_In %n minute on %1$s for the entire day_::_In %n minutes on %1$s for the entire day_" : ["Tüm gün boyunca %1$s zamanında %n dakika içinde","Tüm gün boyunca %1$s zamanında %n dakika içinde"],
"_In %n hour on %1$s for the entire day_::_In %n hours on %1$s for the entire day_" : ["Tüm gün boyunca %1$s zamanında %n saat içinde","Tüm gün boyunca %1$s zamanında %n saat içinde"],
"_In %n day on %1$s for the entire day_::_In %n days on %1$s for the entire day_" : ["Tüm gün boyunca %1$s zamanında %n gün içinde","Tüm gün boyunca %1$s zamanında %n gün içinde"],
"_In %n week on %1$s for the entire day_::_In %n weeks on %1$s for the entire day_" : ["Tüm gün boyunca %1$s zamanında %n hafta içinde","Tüm gün boyunca %1$s zamanında %n hafta içinde"],
"_In %n month on %1$s for the entire day_::_In %n months on %1$s for the entire day_" : ["Tüm gün boyunca %1$s zamanında %n ay içinde","Tüm gün boyunca %1$s zamanında %n ay içinde"],
"_In %n year on %1$s for the entire day_::_In %n years on %1$s for the entire day_" : ["Tüm gün boyunca %1$s zamanında %n yıl içinde","Tüm gün boyunca %1$s zamanında %n yıl içinde"],
"In the past on %1$s between %2$s - %3$s" : "Geçmişte %1$s zamanında %2$s ile %3$s arasında",
"_In %n minute on %1$s between %2$s - %3$s_::_In %n minutes on %1$s between %2$s - %3$s_" : ["%n dakika içinde %1$s zamanında %2$s ile %3$s arasında","%n dakika içinde %1$s zamanında %2$s ile %3$s arasında"],
"_In %n hour on %1$s between %2$s - %3$s_::_In %n hours on %1$s between %2$s - %3$s_" : ["%n saat içinde %1$s zamanında %2$s ile %3$s arasında","%n saat içinde %1$s zamanında %2$s ile %3$s arasında"],
"_In %n day on %1$s between %2$s - %3$s_::_In %n days on %1$s between %2$s - %3$s_" : ["%n gün içinde %1$s zamanında %2$s ile %3$s arasında","%n gün içinde %1$s zamanında %2$s ile %3$s arasında"],
"_In %n week on %1$s between %2$s - %3$s_::_In %n weeks on %1$s between %2$s - %3$s_" : ["%n hafta içinde %1$s zamanında %2$s ile %3$s arasında","%n hafta içinde %1$s zamanında %2$s ile %3$s arasında"],
"_In %n month on %1$s between %2$s - %3$s_::_In %n months on %1$s between %2$s - %3$s_" : ["%n ay içinde %1$s zamanında %2$s ile %3$s arasında","%n ay içinde %1$s zamanında %2$s ile %3$s arasında"],
"_In %n year on %1$s between %2$s - %3$s_::_In %n years on %1$s between %2$s - %3$s_" : ["%n yıl içinde %1$s zamanında %2$s ile %3$s arasında","%n yıl içinde %1$s zamanında %2$s ile %3$s arasında"],
"Could not generate when statement" : "Zaman ifadesi oluşturulamadı",
"Every Day for the entire day" : "Her gün tüm gün boyunca",
"Every Day for the entire day until %1$s" : "%1$s zamanına kadar her gün tüm gün boyunca",
@@ -109,8 +121,26 @@
"On specific dates for the entire day until %1$s" : "Belirli tarihlerde tüm gün boyunca %1$s zamanına kadar",
"On specific dates between %1$s - %2$s until %3$s" : "Belirli tarihlerde %1$s ile %2$s arasında %3$s zamanına kadar",
"In the past on %1$s" : "%1$s zamanında geçmişte",
"_In %n minute on %1$s_::_In %n minutes on %1$s_" : ["%1$s zamanında %n dakika içinde","%1$s zamanında %n dakika içinde"],
"_In %n hour on %1$s_::_In %n hours on %1$s_" : ["%1$s zamanında %n saat içinde","%1$s zamanında %n saat içinde"],
"_In %n day on %1$s_::_In %n days on %1$s_" : ["%1$s zamanında %n gün içinde","%1$s zamanında %n gün içinde"],
"_In %n week on %1$s_::_In %n weeks on %1$s_" : ["%1$s zamanında %n hafta içinde","%1$s zamanında %n hafta içinde"],
"_In %n month on %1$s_::_In %n months on %1$s_" : ["%1$s zamanında %n ay içinde","%1$s zamanında %n ay içinde"],
"_In %n year on %1$s_::_In %n years on %1$s_" : ["%1$s zamanında %n yıl içinde","%1$s zamanında %n yıl içinde"],
"In the past on %1$s then on %2$s" : "Geçmişte %1$s zamanında ardından %2$s zamanında",
"_In %n minute on %1$s then on %2$s_::_In %n minutes on %1$s then on %2$s_" : ["%n dakika içinde %1$s zamanında ardından %2$s zamanında","%n dakika içinde %1$s zamanında ardından %2$s zamanında"],
"_In %n hour on %1$s then on %2$s_::_In %n hours on %1$s then on %2$s_" : ["%n saat içinde %1$s zamanında ardından %2$s zamanında","%n saat içinde %1$s zamanında ardından %2$s zamanında"],
"_In %n day on %1$s then on %2$s_::_In %n days on %1$s then on %2$s_" : ["%n gün içinde %1$s zamanında ardından %2$s zamanında","%n gün içinde %1$s zamanında ardından %2$s zamanında"],
"_In %n week on %1$s then on %2$s_::_In %n weeks on %1$s then on %2$s_" : ["%n hafta içinde %1$s zamanında ardından %2$s zamanında","%n hafta içinde %1$s zamanında ardından %2$s zamanında"],
"_In %n month on %1$s then on %2$s_::_In %n months on %1$s then on %2$s_" : ["%n ay içinde %1$s zamanında ardından %2$s zamanında","%n ay içinde %1$s zamanında ardından %2$s zamanında"],
"_In %n year on %1$s then on %2$s_::_In %n years on %1$s then on %2$s_" : ["%n yıl içinde %1$s zamanında ardından %2$s zamanında","%n yıl içinde %1$s zamanında ardından %2$s zamanında"],
"In the past on %1$s then on %2$s and %3$s" : "Geçmişte %1$s zamanında ardından %2$s ve %3$s zamanında",
"_In %n minute on %1$s then on %2$s and %3$s_::_In %n minutes on %1$s then on %2$s and %3$s_" : ["%n dakika içinde %1$s zamanında ardından %2$s ve %3$s zamanında","%n dakika içinde %1$s zamanında ardından %2$s ve %3$s zamanında"],
"_In %n hour on %1$s then on %2$s and %3$s_::_In %n hours on %1$s then on %2$s and %3$s_" : ["%n dakika içinde %1$s zamanında ardından %2$s ve %3$s zamanında","%n dakika içinde %1$s zamanında ardından %2$s ve %3$s zamanında"],
"_In %n day on %1$s then on %2$s and %3$s_::_In %n days on %1$s then on %2$s and %3$s_" : ["%n dakika içinde %1$s zamanında ardından %2$s ve %3$s zamanında","%n dakika içinde %1$s zamanında ardından %2$s ve %3$s zamanında"],
"_In %n week on %1$s then on %2$s and %3$s_::_In %n weeks on %1$s then on %2$s and %3$s_" : ["%n dakika içinde %1$s zamanında ardından %2$s ve %3$s zamanında","%n dakika içinde %1$s zamanında ardından %2$s ve %3$s zamanında"],
"_In %n month on %1$s then on %2$s and %3$s_::_In %n months on %1$s then on %2$s and %3$s_" : ["%n dakika içinde %1$s zamanında ardından %2$s ve %3$s zamanında","%n dakika içinde %1$s zamanında ardından %2$s ve %3$s zamanında"],
"_In %n year on %1$s then on %2$s and %3$s_::_In %n years on %1$s then on %2$s and %3$s_" : ["%n dakika içinde %1$s zamanında ardından %2$s ve %3$s zamanında","%n dakika içinde %1$s zamanında ardından %2$s ve %3$s zamanında"],
"Could not generate next recurrence statement" : "Sonraki yinelenme ifadesi oluşturulamadı",
"Cancelled: %1$s" : "İptal edildi: %1$s",
"\"%1$s\" has been canceled" : "\"%1$s\" iptal edildi",
+30
View File
@@ -73,7 +73,19 @@ OC.L10N.register(
"Where: %s" : "地点:%s",
"%1$s via %2$s" : "%1$s 通过 %2$s",
"In the past on %1$s for the entire day" : "过去全天 %1$s ",
"_In %n minute on %1$s for the entire day_::_In %n minutes on %1$s for the entire day_" : ["在 %n 分钟后全天 %1$s"],
"_In %n hour on %1$s for the entire day_::_In %n hours on %1$s for the entire day_" : ["在 %n 小时后全天 %1$s"],
"_In %n day on %1$s for the entire day_::_In %n days on %1$s for the entire day_" : ["在 %n 天后全天 %1$s"],
"_In %n week on %1$s for the entire day_::_In %n weeks on %1$s for the entire day_" : ["在 %n 周后全天 %1$s"],
"_In %n month on %1$s for the entire day_::_In %n months on %1$s for the entire day_" : ["在 %n 个月后全天 %1$s"],
"_In %n year on %1$s for the entire day_::_In %n years on %1$s for the entire day_" : ["在 %n 年后全天 %1$s"],
"In the past on %1$s between %2$s - %3$s" : "过去 %2$s - %3$s %1$s",
"_In %n minute on %1$s between %2$s - %3$s_::_In %n minutes on %1$s between %2$s - %3$s_" : ["在 %2$s - %3$s %n 分钟后 %1$s"],
"_In %n hour on %1$s between %2$s - %3$s_::_In %n hours on %1$s between %2$s - %3$s_" : ["在 %2$s - %3$s %n 小时后 %1$s"],
"_In %n day on %1$s between %2$s - %3$s_::_In %n days on %1$s between %2$s - %3$s_" : ["在 %2$s - %3$s %n 天后 %1$s"],
"_In %n week on %1$s between %2$s - %3$s_::_In %n weeks on %1$s between %2$s - %3$s_" : ["在 %2$s - %3$s %n 周后 %1$s"],
"_In %n month on %1$s between %2$s - %3$s_::_In %n months on %1$s between %2$s - %3$s_" : ["在 %2$s - %3$s %n 个月后 %1$s"],
"_In %n year on %1$s between %2$s - %3$s_::_In %n years on %1$s between %2$s - %3$s_" : ["在 %2$s - %3$s %n 年后 %1$s"],
"Could not generate when statement" : "无法生成 when 语句",
"Every Day for the entire day" : "每天全天",
"Every Day for the entire day until %1$s" : "每天全天,直到 %1$s",
@@ -111,8 +123,26 @@ OC.L10N.register(
"On specific dates for the entire day until %1$s" : "在特定日期全天,直到 %1$s",
"On specific dates between %1$s - %2$s until %3$s" : "在 %1$s - %2$s 特定日期,直到 %3$s",
"In the past on %1$s" : "在过去 %1$s",
"_In %n minute on %1$s_::_In %n minutes on %1$s_" : ["%n 分钟后 %1$s"],
"_In %n hour on %1$s_::_In %n hours on %1$s_" : ["%n 小时后 %1$s"],
"_In %n day on %1$s_::_In %n days on %1$s_" : ["%n 天后 %1$s"],
"_In %n week on %1$s_::_In %n weeks on %1$s_" : ["%n 周后 %1$s"],
"_In %n month on %1$s_::_In %n months on %1$s_" : ["%n 个月后 %1$s"],
"_In %n year on %1$s_::_In %n years on %1$s_" : ["%n 年后 %1$s"],
"In the past on %1$s then on %2$s" : "过去 %1$s,然后 %2$s",
"_In %n minute on %1$s then on %2$s_::_In %n minutes on %1$s then on %2$s_" : ["%n 分钟后 %1$s,然后 %2$s"],
"_In %n hour on %1$s then on %2$s_::_In %n hours on %1$s then on %2$s_" : ["%n 小时后 %1$s,然后 %2$s"],
"_In %n day on %1$s then on %2$s_::_In %n days on %1$s then on %2$s_" : ["%n 天后 %1$s,然后 %2$s"],
"_In %n week on %1$s then on %2$s_::_In %n weeks on %1$s then on %2$s_" : ["%n 周后 %1$s,然后 %2$s"],
"_In %n month on %1$s then on %2$s_::_In %n months on %1$s then on %2$s_" : ["%n 个月后 %1$s,然后 %2$s"],
"_In %n year on %1$s then on %2$s_::_In %n years on %1$s then on %2$s_" : ["%n 年后 %1$s,然后 %2$s"],
"In the past on %1$s then on %2$s and %3$s" : "在过去 %1$s,然后 %2$s 和 %3$s",
"_In %n minute on %1$s then on %2$s and %3$s_::_In %n minutes on %1$s then on %2$s and %3$s_" : ["%n 分钟后 %1$s,然后 %2$s 和 %3$s"],
"_In %n hour on %1$s then on %2$s and %3$s_::_In %n hours on %1$s then on %2$s and %3$s_" : ["%n 小时后 %1$s,然后 %2$s 和 %3$s"],
"_In %n day on %1$s then on %2$s and %3$s_::_In %n days on %1$s then on %2$s and %3$s_" : ["%n 天后 %1$s,然后 %2$s 和 %3$s"],
"_In %n week on %1$s then on %2$s and %3$s_::_In %n weeks on %1$s then on %2$s and %3$s_" : ["%n 周后 %1$s,然后 %2$s 和 %3$s"],
"_In %n month on %1$s then on %2$s and %3$s_::_In %n months on %1$s then on %2$s and %3$s_" : ["%n 个月后 %1$s,然后 %2$s 和 %3$s"],
"_In %n year on %1$s then on %2$s and %3$s_::_In %n years on %1$s then on %2$s and %3$s_" : ["%n 年后 %1$s,然后 %2$s 和 %3$s"],
"Could not generate next recurrence statement" : "无法生成下一个重复语句",
"Cancelled: %1$s" : "已取消:%1$s",
"\"%1$s\" has been canceled" : "“%1$s”已取消",
+30
View File
@@ -71,7 +71,19 @@
"Where: %s" : "地点:%s",
"%1$s via %2$s" : "%1$s 通过 %2$s",
"In the past on %1$s for the entire day" : "过去全天 %1$s ",
"_In %n minute on %1$s for the entire day_::_In %n minutes on %1$s for the entire day_" : ["在 %n 分钟后全天 %1$s"],
"_In %n hour on %1$s for the entire day_::_In %n hours on %1$s for the entire day_" : ["在 %n 小时后全天 %1$s"],
"_In %n day on %1$s for the entire day_::_In %n days on %1$s for the entire day_" : ["在 %n 天后全天 %1$s"],
"_In %n week on %1$s for the entire day_::_In %n weeks on %1$s for the entire day_" : ["在 %n 周后全天 %1$s"],
"_In %n month on %1$s for the entire day_::_In %n months on %1$s for the entire day_" : ["在 %n 个月后全天 %1$s"],
"_In %n year on %1$s for the entire day_::_In %n years on %1$s for the entire day_" : ["在 %n 年后全天 %1$s"],
"In the past on %1$s between %2$s - %3$s" : "过去 %2$s - %3$s %1$s",
"_In %n minute on %1$s between %2$s - %3$s_::_In %n minutes on %1$s between %2$s - %3$s_" : ["在 %2$s - %3$s %n 分钟后 %1$s"],
"_In %n hour on %1$s between %2$s - %3$s_::_In %n hours on %1$s between %2$s - %3$s_" : ["在 %2$s - %3$s %n 小时后 %1$s"],
"_In %n day on %1$s between %2$s - %3$s_::_In %n days on %1$s between %2$s - %3$s_" : ["在 %2$s - %3$s %n 天后 %1$s"],
"_In %n week on %1$s between %2$s - %3$s_::_In %n weeks on %1$s between %2$s - %3$s_" : ["在 %2$s - %3$s %n 周后 %1$s"],
"_In %n month on %1$s between %2$s - %3$s_::_In %n months on %1$s between %2$s - %3$s_" : ["在 %2$s - %3$s %n 个月后 %1$s"],
"_In %n year on %1$s between %2$s - %3$s_::_In %n years on %1$s between %2$s - %3$s_" : ["在 %2$s - %3$s %n 年后 %1$s"],
"Could not generate when statement" : "无法生成 when 语句",
"Every Day for the entire day" : "每天全天",
"Every Day for the entire day until %1$s" : "每天全天,直到 %1$s",
@@ -109,8 +121,26 @@
"On specific dates for the entire day until %1$s" : "在特定日期全天,直到 %1$s",
"On specific dates between %1$s - %2$s until %3$s" : "在 %1$s - %2$s 特定日期,直到 %3$s",
"In the past on %1$s" : "在过去 %1$s",
"_In %n minute on %1$s_::_In %n minutes on %1$s_" : ["%n 分钟后 %1$s"],
"_In %n hour on %1$s_::_In %n hours on %1$s_" : ["%n 小时后 %1$s"],
"_In %n day on %1$s_::_In %n days on %1$s_" : ["%n 天后 %1$s"],
"_In %n week on %1$s_::_In %n weeks on %1$s_" : ["%n 周后 %1$s"],
"_In %n month on %1$s_::_In %n months on %1$s_" : ["%n 个月后 %1$s"],
"_In %n year on %1$s_::_In %n years on %1$s_" : ["%n 年后 %1$s"],
"In the past on %1$s then on %2$s" : "过去 %1$s,然后 %2$s",
"_In %n minute on %1$s then on %2$s_::_In %n minutes on %1$s then on %2$s_" : ["%n 分钟后 %1$s,然后 %2$s"],
"_In %n hour on %1$s then on %2$s_::_In %n hours on %1$s then on %2$s_" : ["%n 小时后 %1$s,然后 %2$s"],
"_In %n day on %1$s then on %2$s_::_In %n days on %1$s then on %2$s_" : ["%n 天后 %1$s,然后 %2$s"],
"_In %n week on %1$s then on %2$s_::_In %n weeks on %1$s then on %2$s_" : ["%n 周后 %1$s,然后 %2$s"],
"_In %n month on %1$s then on %2$s_::_In %n months on %1$s then on %2$s_" : ["%n 个月后 %1$s,然后 %2$s"],
"_In %n year on %1$s then on %2$s_::_In %n years on %1$s then on %2$s_" : ["%n 年后 %1$s,然后 %2$s"],
"In the past on %1$s then on %2$s and %3$s" : "在过去 %1$s,然后 %2$s 和 %3$s",
"_In %n minute on %1$s then on %2$s and %3$s_::_In %n minutes on %1$s then on %2$s and %3$s_" : ["%n 分钟后 %1$s,然后 %2$s 和 %3$s"],
"_In %n hour on %1$s then on %2$s and %3$s_::_In %n hours on %1$s then on %2$s and %3$s_" : ["%n 小时后 %1$s,然后 %2$s 和 %3$s"],
"_In %n day on %1$s then on %2$s and %3$s_::_In %n days on %1$s then on %2$s and %3$s_" : ["%n 天后 %1$s,然后 %2$s 和 %3$s"],
"_In %n week on %1$s then on %2$s and %3$s_::_In %n weeks on %1$s then on %2$s and %3$s_" : ["%n 周后 %1$s,然后 %2$s 和 %3$s"],
"_In %n month on %1$s then on %2$s and %3$s_::_In %n months on %1$s then on %2$s and %3$s_" : ["%n 个月后 %1$s,然后 %2$s 和 %3$s"],
"_In %n year on %1$s then on %2$s and %3$s_::_In %n years on %1$s then on %2$s and %3$s_" : ["%n 年后 %1$s,然后 %2$s 和 %3$s"],
"Could not generate next recurrence statement" : "无法生成下一个重复语句",
"Cancelled: %1$s" : "已取消:%1$s",
"\"%1$s\" has been canceled" : "“%1$s”已取消",
+3 -3
View File
@@ -187,9 +187,9 @@ class BirthdayService {
$originalYear = (int)$dateParts['year'];
}
$leapDay = ((int)$dateParts['month'] === 2
&& (int)$dateParts['date'] === 29);
if ($dateParts['year'] === null || $originalYear < 1970) {
$leapDay = ((int)$dateParts['month'] === 2 && (int)$dateParts['date'] === 29);
if ($dateParts['year'] === null) {
$birthday = ($leapDay ? '1972-' : '1970-')
. $dateParts['month'] . '-' . $dateParts['date'];
}
+3 -8
View File
@@ -1066,9 +1066,9 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
* @param int $calendarType
* @return array
*/
public function getLimitedCalendarObjects(int $calendarId, int $calendarType = self::CALENDAR_TYPE_CALENDAR):array {
public function getLimitedCalendarObjects(int $calendarId, int $calendarType = self::CALENDAR_TYPE_CALENDAR, array $fields = []):array {
$query = $this->db->getQueryBuilder();
$query->select(['id','uid', 'etag', 'uri', 'calendardata'])
$query->select($fields ?: ['id', 'uid', 'etag', 'uri', 'calendardata'])
->from('calendarobjects')
->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId)))
->andWhere($query->expr()->eq('calendartype', $query->createNamedParameter($calendarType)))
@@ -1077,12 +1077,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
$result = [];
while (($row = $stmt->fetchAssociative()) !== false) {
$result[$row['uid']] = [
'id' => $row['id'],
'etag' => $row['etag'],
'uri' => $row['uri'],
'calendardata' => $row['calendardata'],
];
$result[$row['uid']] = $row;
}
$stmt->closeCursor();
+27 -17
View File
@@ -23,9 +23,6 @@ use Sabre\VObject\UUIDUtil;
*/
class ImportService {
/** @var resource */
private $source;
public function __construct(
private CalDavBackend $backend,
) {
@@ -44,18 +41,15 @@ class ImportService {
if (!is_resource($source)) {
throw new InvalidArgumentException('Invalid import source must be a file resource');
}
$this->source = $source;
switch ($options->getFormat()) {
case 'ical':
return $this->importProcess($calendar, $options, $this->importText(...));
return $this->importProcess($source, $calendar, $options, $this->importText(...));
break;
case 'jcal':
return $this->importProcess($calendar, $options, $this->importJson(...));
return $this->importProcess($source, $calendar, $options, $this->importJson(...));
break;
case 'xcal':
return $this->importProcess($calendar, $options, $this->importXml(...));
return $this->importProcess($source, $calendar, $options, $this->importXml(...));
break;
default:
throw new InvalidArgumentException('Invalid import format');
@@ -65,10 +59,15 @@ class ImportService {
/**
* Generates object stream from a text formatted source (ical)
*
* @param resource $source
*
* @return Generator<\Sabre\VObject\Component\VCalendar>
*/
private function importText(): Generator {
$importer = new TextImporter($this->source);
public function importText($source): Generator {
if (!is_resource($source)) {
throw new InvalidArgumentException('Invalid import source must be a file resource');
}
$importer = new TextImporter($source);
$structure = $importer->structure();
$sObjectPrefix = $importer::OBJECT_PREFIX;
$sObjectSuffix = $importer::OBJECT_SUFFIX;
@@ -113,10 +112,15 @@ class ImportService {
/**
* Generates object stream from a xml formatted source (xcal)
*
* @param resource $source
*
* @return Generator<\Sabre\VObject\Component\VCalendar>
*/
private function importXml(): Generator {
$importer = new XmlImporter($this->source);
public function importXml($source): Generator {
if (!is_resource($source)) {
throw new InvalidArgumentException('Invalid import source must be a file resource');
}
$importer = new XmlImporter($source);
$structure = $importer->structure();
$sObjectPrefix = $importer::OBJECT_PREFIX;
$sObjectSuffix = $importer::OBJECT_SUFFIX;
@@ -155,11 +159,16 @@ class ImportService {
/**
* Generates object stream from a json formatted source (jcal)
*
* @param resource $source
*
* @return Generator<\Sabre\VObject\Component\VCalendar>
*/
private function importJson(): Generator {
public function importJson($source): Generator {
if (!is_resource($source)) {
throw new InvalidArgumentException('Invalid import source must be a file resource');
}
/** @var VCALENDAR $importer */
$importer = Reader::readJson($this->source);
$importer = Reader::readJson($source);
// calendar time zones
$timezones = [];
foreach ($importer->VTIMEZONE as $timezone) {
@@ -212,17 +221,18 @@ class ImportService {
*
* @since 32.0.0
*
* @param resource $source
* @param CalendarImportOptions $options
* @param callable $generator<CalendarImportOptions>: Generator<\Sabre\VObject\Component\VCalendar>
*
* @return array<string,array<string,string|array<string>>>
*/
public function importProcess(CalendarImpl $calendar, CalendarImportOptions $options, callable $generator): array {
public function importProcess($source, CalendarImpl $calendar, CalendarImportOptions $options, callable $generator): array {
$calendarId = $calendar->getKey();
$calendarUri = $calendar->getUri();
$principalUri = $calendar->getPrincipalUri();
$outcome = [];
foreach ($generator() as $vObject) {
foreach ($generator($source) as $vObject) {
$components = $vObject->getBaseComponents();
// determine if the object has no base component types
if (count($components) === 0) {
@@ -144,19 +144,31 @@ class EmailProvider extends AbstractProvider {
IL10N $l10n,
string $calendarDisplayName,
VEvent $vevent):void {
$template->addBodyListItem($calendarDisplayName, $l10n->t('Calendar:'),
$this->getAbsoluteImagePath('actions/info.png'));
$template->addBodyListItem(
htmlspecialchars($calendarDisplayName),
$l10n->t('Calendar:'),
$this->getAbsoluteImagePath('actions/info.png'),
htmlspecialchars($calendarDisplayName),
);
$template->addBodyListItem($this->generateDateString($l10n, $vevent), $l10n->t('Date:'),
$this->getAbsoluteImagePath('places/calendar.png'));
if (isset($vevent->LOCATION)) {
$template->addBodyListItem((string)$vevent->LOCATION, $l10n->t('Where:'),
$this->getAbsoluteImagePath('actions/address.png'));
$template->addBodyListItem(
htmlspecialchars((string)$vevent->LOCATION),
$l10n->t('Where:'),
$this->getAbsoluteImagePath('actions/address.png'),
htmlspecialchars((string)$vevent->LOCATION),
);
}
if (isset($vevent->DESCRIPTION)) {
$template->addBodyListItem((string)$vevent->DESCRIPTION, $l10n->t('Description:'),
$this->getAbsoluteImagePath('actions/more.png'));
$template->addBodyListItem(
htmlspecialchars((string)$vevent->DESCRIPTION),
$l10n->t('Description:'),
$this->getAbsoluteImagePath('actions/more.png'),
htmlspecialchars((string)$vevent->DESCRIPTION),
);
}
}
+15 -13
View File
@@ -25,6 +25,7 @@ use Sabre\VObject\ITip\Message;
use Sabre\VObject\Parameter;
use Sabre\VObject\Property;
use Sabre\VObject\Recur\EventIterator;
use function htmlspecialchars;
class IMipService {
@@ -80,10 +81,11 @@ class IMipService {
if (!isset($vevent->$property)) {
return $default;
}
$newstring = $vevent->$property->getValue();
$value = $vevent->$property->getValue();
$newstring = $value === null ? null : htmlspecialchars($value);
if (isset($oldVEvent->$property) && $oldVEvent->$property->getValue() !== $newstring) {
$oldstring = $oldVEvent->$property->getValue();
return sprintf($strikethrough, $oldstring, $newstring);
return sprintf($strikethrough, htmlspecialchars($oldstring), $newstring);
}
return $newstring;
}
@@ -96,8 +98,8 @@ class IMipService {
return $default;
}
/** @var string|null $newString */
$newString = $vevent->$property->getValue();
$oldString = isset($oldVEvent->$property) ? $oldVEvent->$property->getValue() : null;
$newString = htmlspecialchars($vevent->$property->getValue());
$oldString = isset($oldVEvent->$property) ? htmlspecialchars($oldVEvent->$property->getValue()) : null;
if ($oldString !== $newString) {
return sprintf(
"<span style='text-decoration: line-through'>%s</span><br />%s",
@@ -797,10 +799,10 @@ class IMipService {
$strikethrough = "<span style='text-decoration: line-through'>%s</span>";
$newMeetingWhen = $this->generateWhenString($eventReaderCurrent);
$newSummary = isset($vEvent->SUMMARY) && (string)$vEvent->SUMMARY !== '' ? (string)$vEvent->SUMMARY : $this->l10n->t('Untitled event');
$newDescription = isset($vEvent->DESCRIPTION) && (string)$vEvent->DESCRIPTION !== '' ? (string)$vEvent->DESCRIPTION : $defaultVal;
$newSummary = htmlspecialchars(isset($vEvent->SUMMARY) && (string)$vEvent->SUMMARY !== '' ? (string)$vEvent->SUMMARY : $this->l10n->t('Untitled event'));
$newDescription = htmlspecialchars(isset($vEvent->DESCRIPTION) && (string)$vEvent->DESCRIPTION !== '' ? (string)$vEvent->DESCRIPTION : $defaultVal);
$newUrl = isset($vEvent->URL) && (string)$vEvent->URL !== '' ? sprintf('<a href="%1$s">%1$s</a>', $vEvent->URL) : $defaultVal;
$newLocation = isset($vEvent->LOCATION) && (string)$vEvent->LOCATION !== '' ? (string)$vEvent->LOCATION : $defaultVal;
$newLocation = htmlspecialchars(isset($vEvent->LOCATION) && (string)$vEvent->LOCATION !== '' ? (string)$vEvent->LOCATION : $defaultVal);
$newLocationHtml = $this->linkify($newLocation) ?? $newLocation;
$data = [];
@@ -1067,22 +1069,22 @@ class IMipService {
*/
public function addBulletList(IEMailTemplate $template, VEvent $vevent, $data) {
$template->addBodyListItem(
$data['meeting_title_html'] ?? $data['meeting_title'], $this->l10n->t('Title:'),
$data['meeting_title_html'] ?? htmlspecialchars($data['meeting_title']), $this->l10n->t('Title:'),
$this->getAbsoluteImagePath('caldav/title.png'), $data['meeting_title'], '', IMipPlugin::IMIP_INDENT);
if ($data['meeting_when'] !== '') {
$template->addBodyListItem($data['meeting_when_html'] ?? $data['meeting_when'], $this->l10n->t('When:'),
$template->addBodyListItem($data['meeting_when_html'] ?? htmlspecialchars($data['meeting_when']), $this->l10n->t('When:'),
$this->getAbsoluteImagePath('caldav/time.png'), $data['meeting_when'], '', IMipPlugin::IMIP_INDENT);
}
if ($data['meeting_location'] !== '') {
$template->addBodyListItem($data['meeting_location_html'] ?? $data['meeting_location'], $this->l10n->t('Location:'),
$template->addBodyListItem($data['meeting_location_html'] ?? htmlspecialchars($data['meeting_location']), $this->l10n->t('Location:'),
$this->getAbsoluteImagePath('caldav/location.png'), $data['meeting_location'], '', IMipPlugin::IMIP_INDENT);
}
if ($data['meeting_url'] !== '') {
$template->addBodyListItem($data['meeting_url_html'] ?? $data['meeting_url'], $this->l10n->t('Link:'),
$template->addBodyListItem($data['meeting_url_html'] ?? htmlspecialchars($data['meeting_url']), $this->l10n->t('Link:'),
$this->getAbsoluteImagePath('caldav/link.png'), $data['meeting_url'], '', IMipPlugin::IMIP_INDENT);
}
if (isset($data['meeting_occurring'])) {
$template->addBodyListItem($data['meeting_occurring_html'] ?? $data['meeting_occurring'], $this->l10n->t('Occurring:'),
$template->addBodyListItem($data['meeting_occurring_html'] ?? htmlspecialchars($data['meeting_occurring']), $this->l10n->t('Occurring:'),
$this->getAbsoluteImagePath('caldav/time.png'), $data['meeting_occurring'], '', IMipPlugin::IMIP_INDENT);
}
@@ -1090,7 +1092,7 @@ class IMipService {
/* Put description last, like an email body, since it can be arbitrarily long */
if ($data['meeting_description']) {
$template->addBodyListItem($data['meeting_description_html'] ?? $data['meeting_description'], $this->l10n->t('Description:'),
$template->addBodyListItem($data['meeting_description_html'] ?? htmlspecialchars($data['meeting_description']), $this->l10n->t('Description:'),
$this->getAbsoluteImagePath('caldav/description.png'), $data['meeting_description'], '', IMipPlugin::IMIP_INDENT);
}
}
@@ -14,7 +14,6 @@ use OCP\Http\Client\IClientService;
use OCP\Http\Client\LocalServerException;
use OCP\IAppConfig;
use Psr\Log\LoggerInterface;
use Sabre\VObject\Reader;
class Connection {
public function __construct(
@@ -26,8 +25,10 @@ class Connection {
/**
* gets webcal feed from remote server
*
* @return array{data: resource, format: string}|null
*/
public function queryWebcalFeed(array $subscription): ?string {
public function queryWebcalFeed(array $subscription): ?array {
$subscriptionId = $subscription['id'];
$url = $this->cleanURL($subscription['source']);
if ($url === null) {
@@ -54,6 +55,7 @@ class Connection {
'User-Agent' => $uaString,
'Accept' => 'text/calendar, application/calendar+json, application/calendar+xml',
],
'stream' => true,
];
$user = parse_url($subscription['source'], PHP_URL_USER);
@@ -77,42 +79,22 @@ class Connection {
return null;
}
$body = $response->getBody();
$contentType = $response->getHeader('Content-Type');
$contentType = explode(';', $contentType, 2)[0];
switch ($contentType) {
case 'application/calendar+json':
try {
$jCalendar = Reader::readJson($body, Reader::OPTION_FORGIVING);
} catch (Exception $ex) {
// In case of a parsing error return null
$this->logger->warning("Subscription $subscriptionId could not be parsed", ['exception' => $ex]);
return null;
}
return $jCalendar->serialize();
case 'application/calendar+xml':
try {
$xCalendar = Reader::readXML($body);
} catch (Exception $ex) {
// In case of a parsing error return null
$this->logger->warning("Subscription $subscriptionId could not be parsed", ['exception' => $ex]);
return null;
}
return $xCalendar->serialize();
$format = match ($contentType) {
'application/calendar+json' => 'jcal',
'application/calendar+xml' => 'xcal',
default => 'ical',
};
case 'text/calendar':
default:
try {
$vCalendar = Reader::read($body);
} catch (Exception $ex) {
// In case of a parsing error return null
$this->logger->warning("Subscription $subscriptionId could not be parsed", ['exception' => $ex]);
return null;
}
return $vCalendar->serialize();
// With 'stream' => true, getBody() returns the underlying stream resource
$stream = $response->getBody();
if (!is_resource($stream)) {
return null;
}
return ['data' => $stream, 'format' => $format];
}
/**
@@ -9,18 +9,14 @@ declare(strict_types=1);
namespace OCA\DAV\CalDAV\WebcalCaching;
use OCA\DAV\CalDAV\CalDavBackend;
use OCA\DAV\CalDAV\Import\ImportService;
use OCP\AppFramework\Utility\ITimeFactory;
use Psr\Log\LoggerInterface;
use Sabre\DAV\Exception\BadRequest;
use Sabre\DAV\Exception\Forbidden;
use Sabre\DAV\PropPatch;
use Sabre\VObject\Component;
use Sabre\VObject\DateTimeParser;
use Sabre\VObject\InvalidDataException;
use Sabre\VObject\ParseException;
use Sabre\VObject\Reader;
use Sabre\VObject\Recur\NoInstancesException;
use Sabre\VObject\Splitter\ICalendar;
use Sabre\VObject\UUIDUtil;
use function count;
@@ -36,20 +32,20 @@ class RefreshWebcalService {
private LoggerInterface $logger,
private Connection $connection,
private ITimeFactory $time,
private ImportService $importService,
) {
}
public function refreshSubscription(string $principalUri, string $uri) {
$subscription = $this->getSubscription($principalUri, $uri);
$mutations = [];
if (!$subscription) {
return;
}
// Check the refresh rate if there is any
if (!empty($subscription['{http://apple.com/ns/ical/}refreshrate'])) {
// add the refresh interval to the lastmodified timestamp
$refreshInterval = new \DateInterval($subscription['{http://apple.com/ns/ical/}refreshrate']);
if (!empty($subscription[self::REFRESH_RATE])) {
// add the refresh interval to the last modified timestamp
$refreshInterval = new \DateInterval($subscription[self::REFRESH_RATE]);
$updateTime = $this->time->getDateTime();
$updateTime->setTimestamp($subscription['lastmodified'])->add($refreshInterval);
if ($updateTime->getTimestamp() > $this->time->getTime()) {
@@ -57,109 +53,116 @@ class RefreshWebcalService {
}
}
$webcalData = $this->connection->queryWebcalFeed($subscription);
if (!$webcalData) {
$result = $this->connection->queryWebcalFeed($subscription);
if (!$result) {
return;
}
$localData = $this->calDavBackend->getLimitedCalendarObjects((int)$subscription['id'], CalDavBackend::CALENDAR_TYPE_SUBSCRIPTION);
$data = $result['data'];
$format = $result['format'];
$stripTodos = ($subscription[self::STRIP_TODOS] ?? 1) === 1;
$stripAlarms = ($subscription[self::STRIP_ALARMS] ?? 1) === 1;
$stripAttachments = ($subscription[self::STRIP_ATTACHMENTS] ?? 1) === 1;
try {
$splitter = new ICalendar($webcalData, Reader::OPTION_FORGIVING);
$existingObjects = $this->calDavBackend->getLimitedCalendarObjects((int)$subscription['id'], CalDavBackend::CALENDAR_TYPE_SUBSCRIPTION, ['id', 'uid', 'etag', 'uri']);
while ($vObject = $splitter->getNext()) {
/** @var Component $vObject */
$compName = null;
$uid = null;
$generator = match ($format) {
'xcal' => $this->importService->importXml(...),
'jcal' => $this->importService->importJson(...),
default => $this->importService->importText(...)
};
foreach ($vObject->getComponents() as $component) {
if ($component->name === 'VTIMEZONE') {
continue;
foreach ($generator($data) as $vObject) {
/** @var Component\VCalendar $vObject */
$vBase = $vObject->getBaseComponent();
if (!$vBase->UID) {
continue;
}
// Some calendar providers (e.g. Google, MS) use very long UIDs
if (strlen($vBase->UID->getValue()) > 512) {
$this->logger->warning('Skipping calendar object with overly long UID from subscription "{subscriptionId}"', [
'subscriptionId' => $subscription['id'],
'uid' => $vBase->UID->getValue(),
]);
continue;
}
if ($stripTodos && $vBase->name === 'VTODO') {
continue;
}
if ($stripAlarms || $stripAttachments) {
foreach ($vObject->getComponents() as $component) {
if ($component->name === 'VTIMEZONE') {
continue;
}
if ($stripAlarms) {
$component->remove('VALARM');
}
if ($stripAttachments) {
$component->remove('ATTACH');
}
}
}
$compName = $component->name;
$sObject = $vObject->serialize();
$uid = $vBase->UID->getValue();
$etag = md5($sObject);
if ($stripAlarms) {
unset($component->{'VALARM'});
// No existing object with this UID, create it
if (!isset($existingObjects[$uid])) {
try {
$this->calDavBackend->createCalendarObject(
$subscription['id'],
UUIDUtil::getUUID() . '.ics',
$sObject,
CalDavBackend::CALENDAR_TYPE_SUBSCRIPTION
);
} catch (\Exception $ex) {
$this->logger->warning('Unable to create calendar object from subscription {subscriptionId}', [
'exception' => $ex,
'subscriptionId' => $subscription['id'],
'source' => $subscription['source'],
]);
}
if ($stripAttachments) {
unset($component->{'ATTACH'});
}
$uid = $component->{ 'UID' }->getValue();
}
if ($stripTodos && $compName === 'VTODO') {
continue;
}
if (!isset($uid)) {
continue;
}
try {
$denormalized = $this->calDavBackend->getDenormalizedData($vObject->serialize());
} catch (InvalidDataException|Forbidden $ex) {
$this->logger->warning('Unable to denormalize calendar object from subscription {subscriptionId}', ['exception' => $ex, 'subscriptionId' => $subscription['id'], 'source' => $subscription['source']]);
continue;
}
// Find all identical sets and remove them from the update
if (isset($localData[$uid]) && $denormalized['etag'] === $localData[$uid]['etag']) {
unset($localData[$uid]);
continue;
}
$vObjectCopy = clone $vObject;
$identical = isset($localData[$uid]) && $this->compareWithoutDtstamp($vObjectCopy, $localData[$uid]);
if ($identical) {
unset($localData[$uid]);
continue;
}
// Find all modified sets and update them
if (isset($localData[$uid]) && $denormalized['etag'] !== $localData[$uid]['etag']) {
$this->calDavBackend->updateCalendarObject($subscription['id'], $localData[$uid]['uri'], $vObject->serialize(), CalDavBackend::CALENDAR_TYPE_SUBSCRIPTION);
unset($localData[$uid]);
continue;
}
// Only entirely new events get created here
try {
$objectUri = $this->getRandomCalendarObjectUri();
$this->calDavBackend->createCalendarObject($subscription['id'], $objectUri, $vObject->serialize(), CalDavBackend::CALENDAR_TYPE_SUBSCRIPTION);
} catch (NoInstancesException|BadRequest $ex) {
$this->logger->warning('Unable to create calendar object from subscription {subscriptionId}', ['exception' => $ex, 'subscriptionId' => $subscription['id'], 'source' => $subscription['source']]);
} elseif ($existingObjects[$uid]['etag'] !== $etag) {
// Existing object with this UID but different etag, update it
$this->calDavBackend->updateCalendarObject(
$subscription['id'],
$existingObjects[$uid]['uri'],
$sObject,
CalDavBackend::CALENDAR_TYPE_SUBSCRIPTION
);
unset($existingObjects[$uid]);
} else {
// Existing object with same etag, just remove from tracking
unset($existingObjects[$uid]);
}
}
$ids = array_map(static function ($dataSet): int {
return (int)$dataSet['id'];
}, $localData);
$uris = array_map(static function ($dataSet): string {
return $dataSet['uri'];
}, $localData);
if (!empty($ids) && !empty($uris)) {
// Clean up on aisle 5
// The only events left over in the $localData array should be those that don't exist upstream
// All deleted VObjects from upstream are removed
$this->calDavBackend->purgeCachedEventsForSubscription($subscription['id'], $ids, $uris);
// Clean up objects that no longer exist in the remote feed
// The only events left over should be those not found upstream
if (!empty($existingObjects)) {
$ids = array_map('intval', array_column($existingObjects, 'id'));
$uris = array_column($existingObjects, 'uri');
$this->calDavBackend->purgeCachedEventsForSubscription((int)$subscription['id'], $ids, $uris);
}
$newRefreshRate = $this->checkWebcalDataForRefreshRate($subscription, $webcalData);
if ($newRefreshRate) {
$mutations[self::REFRESH_RATE] = $newRefreshRate;
// Update refresh rate from the last processed object
if (isset($vObject)) {
$this->updateRefreshRate($subscription, $vObject);
}
$this->updateSubscription($subscription, $mutations);
} catch (ParseException $ex) {
$this->logger->error('Subscription {subscriptionId} could not be refreshed due to a parsing error', ['exception' => $ex, 'subscriptionId' => $subscription['id']]);
} finally {
// Close the data stream to free resources
if (is_resource($data)) {
fclose($data);
}
}
}
@@ -181,84 +184,34 @@ class RefreshWebcalService {
return $subscriptions[0];
}
/**
* check if:
* - current subscription stores a refreshrate
* - the webcal feed suggests a refreshrate
* - return suggested refreshrate if user didn't set a custom one
*
* Update refresh rate from calendar object if:
* - current subscription does not store a refreshrate
* - the webcal feed suggests a valid refreshrate
*/
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) {
return null;
}
/** @var Component\VCalendar $vCalendar */
$vCalendar = Reader::read($webcalData);
$newRefreshRate = null;
if (isset($vCalendar->{'X-PUBLISHED-TTL'})) {
$newRefreshRate = $vCalendar->{'X-PUBLISHED-TTL'}->getValue();
}
if (isset($vCalendar->{'REFRESH-INTERVAL'})) {
$newRefreshRate = $vCalendar->{'REFRESH-INTERVAL'}->getValue();
}
if (!$newRefreshRate) {
return null;
}
// check if new refresh rate is even valid
try {
DateTimeParser::parseDuration($newRefreshRate);
} catch (InvalidDataException $ex) {
return null;
}
return $newRefreshRate;
}
/**
* update subscription stored in database
* used to set:
* - refreshrate
* - source
*
* @param array $subscription
* @param array $mutations
*/
private function updateSubscription(array $subscription, array $mutations) {
if (empty($mutations)) {
private function updateRefreshRate(array $subscription, Component\VCalendar $vCalendar): void {
// if there is already a refreshrate stored in the database, don't override it
if (!empty($subscription[self::REFRESH_RATE])) {
return;
}
$propPatch = new PropPatch($mutations);
$refreshRate = $vCalendar->{'REFRESH-INTERVAL'}?->getValue()
?? $vCalendar->{'X-PUBLISHED-TTL'}?->getValue();
if ($refreshRate === null) {
return;
}
// check if refresh rate is valid
try {
DateTimeParser::parseDuration($refreshRate);
} catch (InvalidDataException) {
return;
}
$propPatch = new PropPatch([self::REFRESH_RATE => $refreshRate]);
$this->calDavBackend->updateSubscription($subscription['id'], $propPatch);
$propPatch->commit();
}
/**
* Returns a random uri for a calendar-object
*
* @return string
*/
public function getRandomCalendarObjectUri():string {
return UUIDUtil::getUUID() . '.ics';
}
private function compareWithoutDtstamp(Component $vObject, array $calendarObject): bool {
foreach ($vObject->getComponents() as $component) {
unset($component->{'DTSTAMP'});
}
$localVobject = Reader::read($calendarObject['calendardata']);
foreach ($localVobject->getComponents() as $component) {
unset($component->{'DTSTAMP'});
}
return strcasecmp($localVobject->serialize(), $vObject->serialize()) === 0;
}
}
+7 -2
View File
@@ -77,6 +77,10 @@ class EntityCollection extends RootCollection implements IProperties {
public function getChild($name) {
try {
$comment = $this->commentsManager->get($name);
if ($comment->getObjectType() !== $this->name
|| $comment->getObjectId() !== $this->id) {
throw new NotFound();
}
return new CommentNode(
$this->commentsManager,
$comment,
@@ -130,8 +134,9 @@ class EntityCollection extends RootCollection implements IProperties {
*/
public function childExists($name) {
try {
$this->commentsManager->get($name);
return true;
$comment = $this->commentsManager->get($name);
return $comment->getObjectType() === $this->name
&& $comment->getObjectId() === $this->id;
} catch (NotFoundException $e) {
return false;
}
@@ -49,7 +49,7 @@ class BlockLegacyClientPlugin extends ServerPlugin {
return;
}
$minimumSupportedDesktopVersion = $this->config->getSystemValueString('minimum.supported.desktop.version', '3.1.0');
$minimumSupportedDesktopVersion = $this->config->getSystemValueString('minimum.supported.desktop.version', '3.0.82');
$maximumSupportedDesktopVersion = $this->config->getSystemValueString('maximum.supported.desktop.version', '99.99.99');
// Check if the client is a desktop client
+84 -2
View File
@@ -8,6 +8,7 @@
namespace OCA\DAV\Connector\Sabre;
use OC\Files\Mount\MoveableMount;
use OC\Files\Utils\PathHelper;
use OC\Files\View;
use OCA\DAV\AppInfo\Application;
use OCA\DAV\Connector\Sabre\Exception\FileLocked;
@@ -38,8 +39,14 @@ use Sabre\DAV\Exception\NotFound;
use Sabre\DAV\Exception\ServiceUnavailable;
use Sabre\DAV\IFile;
use Sabre\DAV\INode;
use Sabre\DAV\INodeByPath;
class Directory extends Node implements \Sabre\DAV\ICollection, \Sabre\DAV\IQuota, \Sabre\DAV\IMoveTarget, \Sabre\DAV\ICopyTarget {
class Directory extends Node implements
\Sabre\DAV\ICollection,
\Sabre\DAV\IQuota,
\Sabre\DAV\IMoveTarget,
\Sabre\DAV\ICopyTarget,
INodeByPath {
/**
* Cached directory content
* @var FileInfo[]
@@ -181,7 +188,7 @@ class Directory extends Node implements \Sabre\DAV\ICollection, \Sabre\DAV\IQuot
// If we are, then only PUT and MKCOL are allowed (see plugin)
// so we are safe to return the directory without a risk of
// leaking files and folders structure.
if ($storage instanceof PublicShareWrapper) {
if ($storage->instanceOfStorage(PublicShareWrapper::class)) {
$share = $storage->getShare();
$allowDirectory = ($share->getPermissions() & Constants::PERMISSION_READ) !== Constants::PERMISSION_READ;
}
@@ -490,4 +497,79 @@ class Directory extends Node implements \Sabre\DAV\ICollection, \Sabre\DAV\IQuot
public function getNode(): Folder {
return $this->node;
}
public function getNodeForPath($path): INode {
$storage = $this->info->getStorage();
$allowDirectory = false;
// Checking if we're in a file drop
// If we are, then only PUT and MKCOL are allowed (see plugin)
// so we are safe to return the directory without a risk of
// leaking files and folders structure.
if ($storage->instanceOfStorage(PublicShareWrapper::class)) {
$share = $storage->getShare();
$allowDirectory = ($share->getPermissions() & Constants::PERMISSION_READ) !== Constants::PERMISSION_READ;
}
// For file drop we need to be allowed to read the directory with the nickname
if (!$allowDirectory && !$this->info->isReadable()) {
// avoid detecting files through this way
throw new NotFound();
}
$destinationPath = PathHelper::normalizePath($this->getPath() . '/' . $path);
$destinationDir = dirname($destinationPath);
try {
$info = $this->getNode()->get($path);
} catch (NotFoundException $e) {
throw new \Sabre\DAV\Exception\NotFound('File with name ' . $destinationPath
. ' could not be located');
} catch (StorageNotAvailableException $e) {
throw new \Sabre\DAV\Exception\ServiceUnavailable($e->getMessage(), 0, $e);
} catch (NotPermittedException $ex) {
throw new InvalidPath($ex->getMessage(), false, $ex);
}
// if not in a public share with no read permissions, throw Forbidden
if (!$allowDirectory && !$info->isReadable()) {
if (Server::get(IAppManager::class)->isEnabledForAnyone('files_accesscontrol')) {
throw new Forbidden('No read permissions. This might be caused by files_accesscontrol, check your configured rules');
}
throw new Forbidden('No read permissions');
}
if ($info->getMimeType() === FileInfo::MIMETYPE_FOLDER) {
$node = new \OCA\DAV\Connector\Sabre\Directory($this->fileView, $info, $this->tree, $this->shareManager);
} else {
// In case reading a directory was allowed but it turns out the node was a not a directory, reject it now.
if (!$this->info->isReadable()) {
throw new NotFound();
}
$node = new File($this->fileView, $info, $this->shareManager);
}
$this->tree?->cacheNode($node);
// recurse upwards until the root and check for read permissions to keep
// ACL checks working in files_accesscontrol
if (!$allowDirectory && $destinationDir !== '') {
$scanPath = $destinationPath;
while (($scanPath = dirname($scanPath)) !== '/') {
// fileView can get the parent info in a cheaper way compared
// to the node API
/** @psalm-suppress InternalMethod */
$info = $this->fileView->getFileInfo($scanPath, false);
$directory = new Directory($this->fileView, $info, $this->tree, $this->shareManager);
$readable = $directory->getNode()->isReadable();
if (!$readable) {
throw new \Sabre\DAV\Exception\NotFound('File with name ' . $destinationPath
. ' could not be located');
}
}
}
return $node;
}
}
+14 -7
View File
@@ -18,6 +18,7 @@ use OCA\DAV\Connector\Sabre\Exception\FileLocked;
use OCA\DAV\Connector\Sabre\Exception\Forbidden as DAVForbiddenException;
use OCA\DAV\Connector\Sabre\Exception\UnsupportedMediaType;
use OCP\App\IAppManager;
use OCP\Constants;
use OCP\Encryption\Exceptions\GenericEncryptionException;
use OCP\Files;
use OCP\Files\EntityTooLargeException;
@@ -539,18 +540,24 @@ class File extends Node implements IFile {
}
/**
* @return array|bool
* @throws NotFoundException
* @throws NotPermittedException
*/
public function getDirectDownload() {
public function getDirectDownload(): array|false {
if (Server::get(IAppManager::class)->isEnabledForUser('encryption')) {
return [];
return false;
}
[$storage, $internalPath] = $this->fileView->resolvePath($this->path);
if (is_null($storage)) {
return [];
$node = $this->getNode();
$storage = $node->getStorage();
if (!$storage) {
return false;
}
return $storage->getDirectDownload($internalPath);
if (!($node->getPermissions() & Constants::PERMISSION_READ)) {
return false;
}
return $storage->getDirectDownloadById((string)$node->getId());
}
/**
+20 -7
View File
@@ -50,6 +50,7 @@ class FilesPlugin extends ServerPlugin {
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 DOWNLOADURL_EXPIRATION_PROPERTYNAME = '{http://nextcloud.org/ns}download-url-expiration';
public const SIZE_PROPERTYNAME = '{http://owncloud.org/ns}size';
public const GETETAG_PROPERTYNAME = '{DAV:}getetag';
public const LASTMODIFIED_PROPERTYNAME = '{DAV:}lastmodified';
@@ -120,6 +121,7 @@ class FilesPlugin extends ServerPlugin {
$server->protectedProperties[] = self::SHARE_ATTRIBUTES_PROPERTYNAME;
$server->protectedProperties[] = self::SIZE_PROPERTYNAME;
$server->protectedProperties[] = self::DOWNLOADURL_PROPERTYNAME;
$server->protectedProperties[] = self::DOWNLOADURL_EXPIRATION_PROPERTYNAME;
$server->protectedProperties[] = self::OWNER_ID_PROPERTYNAME;
$server->protectedProperties[] = self::OWNER_DISPLAY_NAME_PROPERTYNAME;
$server->protectedProperties[] = self::CHECKSUMS_PROPERTYNAME;
@@ -471,19 +473,30 @@ class FilesPlugin extends ServerPlugin {
}
if ($node instanceof File) {
$propFind->handle(self::DOWNLOADURL_PROPERTYNAME, function () use ($node) {
$requestProperties = $propFind->getRequestedProperties();
if (in_array(self::DOWNLOADURL_PROPERTYNAME, $requestProperties, true)
|| in_array(self::DOWNLOADURL_EXPIRATION_PROPERTYNAME, $requestProperties, true)) {
try {
$directDownloadUrl = $node->getDirectDownload();
if (isset($directDownloadUrl['url'])) {
} catch (StorageNotAvailableException|ForbiddenException) {
$directDownloadUrl = null;
}
$propFind->handle(self::DOWNLOADURL_PROPERTYNAME, function () use ($node, $directDownloadUrl) {
if ($directDownloadUrl && isset($directDownloadUrl['url'])) {
return $directDownloadUrl['url'];
}
} catch (StorageNotAvailableException $e) {
return false;
} catch (ForbiddenException $e) {
});
$propFind->handle(self::DOWNLOADURL_EXPIRATION_PROPERTYNAME, function () use ($node, $directDownloadUrl) {
if ($directDownloadUrl && isset($directDownloadUrl['expiration'])) {
return $directDownloadUrl['expiration'];
}
return false;
}
return false;
});
});
}
$propFind->handle(self::CHECKSUMS_PROPERTYNAME, function () use ($node) {
$checksum = $node->getChecksum();
+2 -2
View File
@@ -9,11 +9,11 @@
namespace OCA\DAV\Connector\Sabre;
use OC\Files\View;
use OCA\DAV\Upload\FutureFile;
use OCA\DAV\Upload\UploadFolder;
use OCP\Files\StorageNotAvailableException;
use Sabre\DAV\Exception\InsufficientStorage;
use Sabre\DAV\Exception\ServiceUnavailable;
use Sabre\DAV\IFile;
use Sabre\DAV\INode;
use Sabre\HTTP\RequestInterface;
use Sabre\HTTP\ResponseInterface;
@@ -138,7 +138,7 @@ class QuotaPlugin extends \Sabre\DAV\ServerPlugin {
*/
public function beforeMove(string $sourcePath, string $destinationPath): bool {
$sourceNode = $this->server->tree->getNodeForPath($sourcePath);
if (!$sourceNode instanceof FutureFile) {
if (!$sourceNode instanceof IFile) {
return true;
}
+69 -41
View File
@@ -37,6 +37,7 @@ use OCP\IRequest;
use OCP\ITagManager;
use OCP\IUserManager;
use OCP\IUserSession;
use OCP\L10N\IFactory;
use OCP\SabrePluginEvent;
use OCP\SystemTag\ISystemTagManager;
use OCP\SystemTag\ISystemTagObjectMapper;
@@ -70,15 +71,13 @@ class ServerFactory {
Plugin $authPlugin,
callable $viewCallBack,
): Server {
// /public.php/webdav/ shows the files in the share in the root itself
// and not under /public.php/webdav/files/{token} so we should keep
// compatibility for that.
$needsSharesInRoot = $baseUri === '/public.php/webdav/';
$useCollection = $isPublicShare && !$needsSharesInRoot;
$debugEnabled = $this->config->getSystemValue('debug', false);
// Fire up server
if ($isPublicShare) {
$rootCollection = new SimpleCollection('root');
$tree = new CachingTree($rootCollection);
} else {
$rootCollection = null;
$tree = new ObjectTree();
}
[$tree, $rootCollection] = $this->getTree($useCollection);
$server = new Server($tree);
// Set URL explicitly due to reverse-proxy situations
$server->httpRequest->setUrl($requestUri);
@@ -127,8 +126,8 @@ class ServerFactory {
}
// wait with registering these until auth is handled and the filesystem is setup
$server->on('beforeMethod:*', function () use ($server, $tree,
$viewCallBack, $isPublicShare, $rootCollection, $debugEnabled): void {
$server->on('beforeMethod:*', function () use ($server,
$tree, $viewCallBack, $isPublicShare, $rootCollection, $debugEnabled): void {
// ensure the skeleton is copied
$userFolder = \OC::$server->getUserFolder();
@@ -147,36 +146,8 @@ class ServerFactory {
$root = new File($view, $rootInfo);
}
if ($isPublicShare) {
$userPrincipalBackend = new Principal(
\OCP\Server::get(IUserManager::class),
\OCP\Server::get(IGroupManager::class),
\OCP\Server::get(IAccountManager::class),
\OCP\Server::get(\OCP\Share\IManager::class),
\OCP\Server::get(IUserSession::class),
\OCP\Server::get(IAppManager::class),
\OCP\Server::get(ProxyMapper::class),
\OCP\Server::get(KnownUserService::class),
\OCP\Server::get(IConfig::class),
\OC::$server->getL10NFactory(),
);
// Mount the share collection at /public.php/dav/shares/<share token>
$rootCollection->addChild(new RootCollection(
$root,
$userPrincipalBackend,
'principals/shares',
));
// Mount the upload collection at /public.php/dav/uploads/<share token>
$rootCollection->addChild(new \OCA\DAV\Upload\RootCollection(
$userPrincipalBackend,
'principals/shares',
\OCP\Server::get(CleanupService::class),
\OCP\Server::get(IRootFolder::class),
\OCP\Server::get(IUserSession::class),
\OCP\Server::get(\OCP\Share\IManager::class),
));
if ($rootCollection !== null) {
$this->initRootCollection($rootCollection, $root);
} else {
/** @var ObjectTree $tree */
$tree->init($root, $view, $this->mountManager);
@@ -191,7 +162,7 @@ class ServerFactory {
$this->userSession,
\OCP\Server::get(IFilenameValidator::class),
\OCP\Server::get(IAccountManager::class),
false,
$isPublicShare,
!$debugEnabled
)
);
@@ -252,4 +223,61 @@ class ServerFactory {
}, 30); // priority 30: after auth (10) and acl(20), before lock(50) and handling the request
return $server;
}
/**
* Returns a Tree object and, if $useCollection is true, the collection used
* as root.
*
* @param bool $useCollection Whether to use a collection or the legacy
* ObjectTree, which doesn't use collections.
* @return array{0: CachingTree|ObjectTree, 1: SimpleCollection|null}
*/
public function getTree(bool $useCollection): array {
if ($useCollection) {
$rootCollection = new SimpleCollection('root');
$tree = new CachingTree($rootCollection);
return [$tree, $rootCollection];
}
return [new ObjectTree(), null];
}
/**
* Adds the user's principal backend to $rootCollection.
*/
private function initRootCollection(SimpleCollection $rootCollection, Directory|File $root): void {
$userPrincipalBackend = new Principal(
\OCP\Server::get(IUserManager::class),
\OCP\Server::get(IGroupManager::class),
\OCP\Server::get(IAccountManager::class),
\OCP\Server::get(\OCP\Share\IManager::class),
\OCP\Server::get(IUserSession::class),
\OCP\Server::get(IAppManager::class),
\OCP\Server::get(ProxyMapper::class),
\OCP\Server::get(KnownUserService::class),
\OCP\Server::get(IConfig::class),
\OCP\Server::get(IFactory::class),
);
// Mount the share collection at /public.php/dav/files/<share token>
$rootCollection->addChild(
new RootCollection(
$root,
$userPrincipalBackend,
'principals/shares',
)
);
// Mount the upload collection at /public.php/dav/uploads/<share token>
$rootCollection->addChild(
new \OCA\DAV\Upload\RootCollection(
$userPrincipalBackend,
'principals/shares',
\OCP\Server::get(CleanupService::class),
\OCP\Server::get(IRootFolder::class),
\OCP\Server::get(IUserSession::class),
\OCP\Server::get(\OCP\Share\IManager::class),
)
);
}
}
@@ -0,0 +1,56 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\DAV\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\Attributes\ColumnType;
use OCP\Migration\Attributes\ModifyColumn;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
use Override;
#[ModifyColumn(table: 'calendarobjects', name: 'uid', type: ColumnType::STRING, description: 'Increase uid length to 512 characters')]
#[ModifyColumn(table: 'calendar_reminders', name: 'uid', type: ColumnType::STRING, description: 'Increase uid length to 512 characters')]
#[ModifyColumn(table: 'calendar_invitations', name: 'uid', type: ColumnType::STRING, description: 'Increase uid length to 512 characters')]
class Version1036Date20251202000000 extends SimpleMigrationStep {
/**
* @param Closure(): ISchemaWrapper $schemaClosure
*/
#[Override]
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$modified = false;
$table = $schema->getTable('calendarobjects');
$column = $table->getColumn('uid');
if ($column->getLength() < 512) {
$column->setLength(512);
$modified = true;
}
$table = $schema->getTable('calendar_reminders');
$column = $table->getColumn('uid');
if ($column->getLength() < 512) {
$column->setLength(512);
$modified = true;
}
$table = $schema->getTable('calendar_invitations');
$column = $table->getColumn('uid');
if ($column->getLength() < 512) {
$column->setLength(512);
$modified = true;
}
return $modified ? $schema : null;
}
}
@@ -45,7 +45,7 @@ class RefreshWebcalJobTest extends TestCase {
#[\PHPUnit\Framework\Attributes\DataProvider('runDataProvider')]
public function testRun(int $lastRun, int $time, bool $process): void {
$backgroundJob = new RefreshWebcalJob($this->refreshWebcalService, $this->config, $this->logger, $this->timeFactory);
$backgroundJob->setId(42);
$backgroundJob->setId('42');
$backgroundJob->setArgument([
'principaluri' => 'principals/users/testuser',
@@ -89,12 +89,8 @@ class ConnectionTest extends TestCase {
}
/**
* @param string $result
* @param string $contentType
*/
#[\PHPUnit\Framework\Attributes\DataProvider('urlDataProvider')]
public function testConnection(string $url, string $result, string $contentType): void {
public function testConnection(string $url, string $contentType, string $expectedFormat): void {
$client = $this->createMock(IClient::class);
$response = $this->createMock(IResponse::class);
$subscription = [
@@ -123,16 +119,76 @@ class ConnectionTest extends TestCase {
->with('https://foo.bar/bla2')
->willReturn($response);
$response->expects($this->once())
->method('getBody')
->with()
->willReturn($result);
$response->expects($this->once())
->method('getHeader')
->with('Content-Type')
->willReturn($contentType);
$this->connection->queryWebcalFeed($subscription);
// Create a stream resource to simulate streaming response
$stream = fopen('php://temp', 'r+');
fwrite($stream, 'test calendar data');
rewind($stream);
$response->expects($this->once())
->method('getBody')
->willReturn($stream);
$output = $this->connection->queryWebcalFeed($subscription);
$this->assertIsArray($output);
$this->assertArrayHasKey('data', $output);
$this->assertArrayHasKey('format', $output);
$this->assertIsResource($output['data']);
$this->assertEquals($expectedFormat, $output['format']);
// Cleanup
if (is_resource($output['data'])) {
fclose($output['data']);
}
}
public function testConnectionReturnsNullWhenBodyIsNotResource(): void {
$client = $this->createMock(IClient::class);
$response = $this->createMock(IResponse::class);
$subscription = [
'id' => 42,
'uri' => 'sub123',
'refreshreate' => 'P1H',
'striptodos' => 1,
'stripalarms' => 1,
'stripattachments' => 1,
'source' => 'https://foo.bar/bla2',
'lastmodified' => 0,
];
$this->clientService->expects($this->once())
->method('newClient')
->with()
->willReturn($client);
$this->config->expects($this->once())
->method('getValueString')
->with('dav', 'webcalAllowLocalAccess', 'no')
->willReturn('no');
$client->expects($this->once())
->method('get')
->with('https://foo.bar/bla2')
->willReturn($response);
$response->expects($this->once())
->method('getHeader')
->with('Content-Type')
->willReturn('text/calendar');
// Return a string instead of a resource
$response->expects($this->once())
->method('getBody')
->willReturn('not a resource');
$output = $this->connection->queryWebcalFeed($subscription);
$this->assertNull($output);
}
public static function runLocalURLDataProvider(): array {
@@ -156,21 +212,9 @@ class ConnectionTest extends TestCase {
public static function urlDataProvider(): array {
return [
[
'https://foo.bar/bla2',
"BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:12345\r\nDTSTAMP:20160218T133704Z\r\nDTSTART;VALUE=DATE:19000101\r\nDTEND;VALUE=DATE:19000102\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:12345's Birthday (1900)\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n",
'text/calendar;charset=utf8',
],
[
'https://foo.bar/bla2',
'["vcalendar",[["prodid",{},"text","-//Example Corp.//Example Client//EN"],["version",{},"text","2.0"]],[["vtimezone",[["last-modified",{},"date-time","2004-01-10T03:28:45Z"],["tzid",{},"text","US/Eastern"]],[["daylight",[["dtstart",{},"date-time","2000-04-04T02:00:00"],["rrule",{},"recur",{"freq":"YEARLY","byday":"1SU","bymonth":4}],["tzname",{},"text","EDT"],["tzoffsetfrom",{},"utc-offset","-05:00"],["tzoffsetto",{},"utc-offset","-04:00"]],[]],["standard",[["dtstart",{},"date-time","2000-10-26T02:00:00"],["rrule",{},"recur",{"freq":"YEARLY","byday":"1SU","bymonth":10}],["tzname",{},"text","EST"],["tzoffsetfrom",{},"utc-offset","-04:00"],["tzoffsetto",{},"utc-offset","-05:00"]],[]]]],["vevent",[["dtstamp",{},"date-time","2006-02-06T00:11:21Z"],["dtstart",{"tzid":"US/Eastern"},"date-time","2006-01-02T14:00:00"],["duration",{},"duration","PT1H"],["recurrence-id",{"tzid":"US/Eastern"},"date-time","2006-01-04T12:00:00"],["summary",{},"text","Event #2"],["uid",{},"text","12345"]],[]]]]',
'application/calendar+json',
],
[
'https://foo.bar/bla2',
'<?xml version="1.0" encoding="utf-8" ?><icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"><vcalendar><properties><prodid><text>-//Example Inc.//Example Client//EN</text></prodid><version><text>2.0</text></version></properties><components><vevent><properties><dtstamp><date-time>2006-02-06T00:11:21Z</date-time></dtstamp><dtstart><parameters><tzid><text>US/Eastern</text></tzid></parameters><date-time>2006-01-04T14:00:00</date-time></dtstart><duration><duration>PT1H</duration></duration><recurrence-id><parameters><tzid><text>US/Eastern</text></tzid></parameters><date-time>2006-01-04T12:00:00</date-time></recurrence-id><summary><text>Event #2 bis</text></summary><uid><text>12345</text></uid></properties></vevent></components></vcalendar></icalendar>',
'application/calendar+xml',
],
['https://foo.bar/bla2', 'text/calendar;charset=utf8', 'ical'],
['https://foo.bar/bla2', 'application/calendar+json', 'jcal'],
['https://foo.bar/bla2', 'application/calendar+xml', 'xcal'],
];
}
}
@@ -8,6 +8,7 @@ declare(strict_types=1);
namespace OCA\DAV\Tests\unit\CalDAV\WebcalCaching;
use OCA\DAV\CalDAV\CalDavBackend;
use OCA\DAV\CalDAV\Import\ImportService;
use OCA\DAV\CalDAV\WebcalCaching\Connection;
use OCA\DAV\CalDAV\WebcalCaching\RefreshWebcalService;
use OCP\AppFramework\Utility\ITimeFactory;
@@ -23,7 +24,8 @@ class RefreshWebcalServiceTest extends TestCase {
private CalDavBackend&MockObject $caldavBackend;
private Connection&MockObject $connection;
private LoggerInterface&MockObject $logger;
private ITimeFactory&MockObject $time;
private ImportService&MockObject $importService;
private ITimeFactory&MockObject $timeFactory;
protected function setUp(): void {
parent::setUp();
@@ -31,19 +33,32 @@ class RefreshWebcalServiceTest extends TestCase {
$this->caldavBackend = $this->createMock(CalDavBackend::class);
$this->connection = $this->createMock(Connection::class);
$this->logger = $this->createMock(LoggerInterface::class);
$this->time = $this->createMock(ITimeFactory::class);
$this->importService = $this->createMock(ImportService::class);
$this->timeFactory = $this->createMock(ITimeFactory::class);
// Default time factory behavior: current time is far in the future so refresh always happens
$this->timeFactory->method('getTime')->willReturn(PHP_INT_MAX);
$this->timeFactory->method('getDateTime')->willReturn(new \DateTime());
}
/**
* Helper to create a resource stream from string content
*/
private function createStreamFromString(string $content) {
$stream = fopen('php://temp', 'r+');
fwrite($stream, $content);
rewind($stream);
return $stream;
}
#[\PHPUnit\Framework\Attributes\DataProvider('runDataProvider')]
public function testRun(string $body, string $contentType, string $result): void {
$refreshWebcalService = $this->getMockBuilder(RefreshWebcalService::class)
->onlyMethods(['getRandomCalendarObjectUri'])
->setConstructorArgs([$this->caldavBackend, $this->logger, $this->connection, $this->time])
->getMock();
$refreshWebcalService
->method('getRandomCalendarObjectUri')
->willReturn('uri-1.ics');
public function testRun(string $body, string $format, string $result): void {
$refreshWebcalService = new RefreshWebcalService(
$this->caldavBackend,
$this->logger,
$this->connection,
$this->timeFactory,
$this->importService
);
$this->caldavBackend->expects(self::once())
->method('getSubscriptionsForUser')
@@ -71,26 +86,48 @@ class RefreshWebcalServiceTest extends TestCase {
],
]);
$stream = $this->createStreamFromString($body);
$this->connection->expects(self::once())
->method('queryWebcalFeed')
->willReturn($result);
->willReturn(['data' => $stream, 'format' => $format]);
$this->caldavBackend->expects(self::once())
->method('getLimitedCalendarObjects')
->willReturn([]);
// Create a VCalendar object that will be yielded by the import service
$vCalendar = VObject\Reader::read($result);
$generator = function () use ($vCalendar) {
yield $vCalendar;
};
$this->importService->expects(self::once())
->method('importText')
->willReturn($generator());
$this->caldavBackend->expects(self::once())
->method('createCalendarObject')
->with(42, 'uri-1.ics', $result, 1);
->with(
'42',
self::matchesRegularExpression('/^[a-f0-9-]+\.ics$/'),
$result,
CalDavBackend::CALENDAR_TYPE_SUBSCRIPTION
);
$refreshWebcalService->refreshSubscription('principals/users/testuser', 'sub123');
}
#[\PHPUnit\Framework\Attributes\DataProvider('identicalDataProvider')]
public function testRunIdentical(string $uid, array $calendarObject, string $body, string $contentType, string $result): void {
$refreshWebcalService = $this->getMockBuilder(RefreshWebcalService::class)
->onlyMethods(['getRandomCalendarObjectUri'])
->setConstructorArgs([$this->caldavBackend, $this->logger, $this->connection, $this->time])
->getMock();
$refreshWebcalService
->method('getRandomCalendarObjectUri')
->willReturn('uri-1.ics');
public function testRunIdentical(string $uid, array $calendarObject, string $body, string $format, string $result): void {
$refreshWebcalService = new RefreshWebcalService(
$this->caldavBackend,
$this->logger,
$this->connection,
$this->timeFactory,
$this->importService
);
$this->caldavBackend->expects(self::once())
->method('getSubscriptionsForUser')
@@ -118,78 +155,199 @@ class RefreshWebcalServiceTest extends TestCase {
],
]);
$stream = $this->createStreamFromString($body);
$this->connection->expects(self::once())
->method('queryWebcalFeed')
->willReturn(['data' => $stream, 'format' => $format]);
$this->caldavBackend->expects(self::once())
->method('getLimitedCalendarObjects')
->willReturn($calendarObject);
// Create a VCalendar object that will be yielded by the import service
$vCalendar = VObject\Reader::read($result);
$generator = function () use ($vCalendar) {
yield $vCalendar;
};
$this->importService->expects(self::once())
->method('importText')
->willReturn($generator());
$this->caldavBackend->expects(self::never())
->method('createCalendarObject');
$refreshWebcalService->refreshSubscription('principals/users/testuser', 'sub123');
}
public function testSubscriptionNotFound(): void {
$refreshWebcalService = new RefreshWebcalService(
$this->caldavBackend,
$this->logger,
$this->connection,
$this->timeFactory,
$this->importService
);
$this->caldavBackend->expects(self::once())
->method('getSubscriptionsForUser')
->with('principals/users/testuser')
->willReturn([]);
$this->connection->expects(self::never())
->method('queryWebcalFeed');
$refreshWebcalService->refreshSubscription('principals/users/testuser', 'sub123');
}
public function testConnectionReturnsNull(): void {
$refreshWebcalService = new RefreshWebcalService(
$this->caldavBackend,
$this->logger,
$this->connection,
$this->timeFactory,
$this->importService
);
$this->caldavBackend->expects(self::once())
->method('getSubscriptionsForUser')
->with('principals/users/testuser')
->willReturn([
[
'id' => '42',
'uri' => 'sub123',
RefreshWebcalService::STRIP_TODOS => '1',
RefreshWebcalService::STRIP_ALARMS => '1',
RefreshWebcalService::STRIP_ATTACHMENTS => '1',
'source' => 'webcal://foo.bar/bla2',
'lastmodified' => 0,
],
]);
$this->connection->expects(self::once())
->method('queryWebcalFeed')
->willReturn($result);
->willReturn(null);
$this->caldavBackend->expects(self::once())
->method('getLimitedCalendarObjects')
->willReturn($calendarObject);
$denormalised = [
'etag' => 100,
'size' => strlen($calendarObject[$uid]['calendardata']),
'uid' => 'sub456'
];
$this->caldavBackend->expects(self::once())
->method('getDenormalizedData')
->willReturn($denormalised);
$this->importService->expects(self::never())
->method('importText');
$this->caldavBackend->expects(self::never())
->method('createCalendarObject');
$refreshWebcalService->refreshSubscription('principals/users/testuser', 'sub456');
$refreshWebcalService->refreshSubscription('principals/users/testuser', 'sub123');
}
public function testRunJustUpdated(): void {
$refreshWebcalService = $this->getMockBuilder(RefreshWebcalService::class)
->onlyMethods(['getRandomCalendarObjectUri'])
->setConstructorArgs([$this->caldavBackend, $this->logger, $this->connection, $this->time])
->getMock();
$refreshWebcalService
->method('getRandomCalendarObjectUri')
->willReturn('uri-1.ics');
public function testDeletedObjectsArePurged(): void {
$refreshWebcalService = new RefreshWebcalService(
$this->caldavBackend,
$this->logger,
$this->connection,
$this->timeFactory,
$this->importService
);
$this->caldavBackend->expects(self::once())
->method('getSubscriptionsForUser')
->with('principals/users/testuser')
->willReturn([
[
'id' => '99',
'uri' => 'sub456',
RefreshWebcalService::REFRESH_RATE => 'P1D',
RefreshWebcalService::STRIP_TODOS => '1',
RefreshWebcalService::STRIP_ALARMS => '1',
RefreshWebcalService::STRIP_ATTACHMENTS => '1',
'source' => 'webcal://foo.bar/bla',
'lastmodified' => time(),
],
[
'id' => '42',
'uri' => 'sub123',
RefreshWebcalService::REFRESH_RATE => 'PT1H',
RefreshWebcalService::STRIP_TODOS => '1',
RefreshWebcalService::STRIP_ALARMS => '1',
RefreshWebcalService::STRIP_ATTACHMENTS => '1',
'source' => 'webcal://foo.bar/bla2',
'lastmodified' => time(),
'lastmodified' => 0,
],
]);
$timeMock = $this->createMock(\DateTime::class);
$this->time->expects(self::once())
->method('getDateTime')
->willReturn($timeMock);
$timeMock->expects(self::once())
->method('getTimestamp')
->willReturn(2101724667);
$this->time->expects(self::once())
->method('getTime')
->willReturn(time());
$this->connection->expects(self::never())
->method('queryWebcalFeed');
$body = "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Test//Test//EN\r\nBEGIN:VEVENT\r\nUID:new-event\r\nDTSTAMP:20160218T133704Z\r\nDTSTART:20160218T133704Z\r\nSUMMARY:New Event\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
$stream = $this->createStreamFromString($body);
$this->connection->expects(self::once())
->method('queryWebcalFeed')
->willReturn(['data' => $stream, 'format' => 'ical']);
// Existing objects include one that won't be in the feed
$this->caldavBackend->expects(self::once())
->method('getLimitedCalendarObjects')
->willReturn([
'old-deleted-event' => [
'id' => 99,
'uid' => 'old-deleted-event',
'etag' => 'old-etag',
'uri' => 'old-event.ics',
],
]);
$vCalendar = VObject\Reader::read($body);
$generator = function () use ($vCalendar) {
yield $vCalendar;
};
$this->importService->expects(self::once())
->method('importText')
->willReturn($generator());
$this->caldavBackend->expects(self::once())
->method('createCalendarObject');
$this->caldavBackend->expects(self::once())
->method('purgeCachedEventsForSubscription')
->with(42, [99], ['old-event.ics']);
$refreshWebcalService->refreshSubscription('principals/users/testuser', 'sub123');
}
public function testLongUidIsSkipped(): void {
$refreshWebcalService = new RefreshWebcalService(
$this->caldavBackend,
$this->logger,
$this->connection,
$this->timeFactory,
$this->importService
);
$this->caldavBackend->expects(self::once())
->method('getSubscriptionsForUser')
->with('principals/users/testuser')
->willReturn([
[
'id' => '42',
'uri' => 'sub123',
RefreshWebcalService::STRIP_TODOS => '1',
RefreshWebcalService::STRIP_ALARMS => '1',
RefreshWebcalService::STRIP_ATTACHMENTS => '1',
'source' => 'webcal://foo.bar/bla2',
'lastmodified' => 0,
],
]);
// Create a UID that is longer than 512 characters
$longUid = str_repeat('a', 513);
$body = "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Test//Test//EN\r\nBEGIN:VEVENT\r\nUID:$longUid\r\nDTSTAMP:20160218T133704Z\r\nDTSTART:20160218T133704Z\r\nSUMMARY:Event with long UID\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
$stream = $this->createStreamFromString($body);
$this->connection->expects(self::once())
->method('queryWebcalFeed')
->willReturn(['data' => $stream, 'format' => 'ical']);
$this->caldavBackend->expects(self::once())
->method('getLimitedCalendarObjects')
->willReturn([]);
$vCalendar = VObject\Reader::read($body);
$generator = function () use ($vCalendar) {
yield $vCalendar;
};
$this->importService->expects(self::once())
->method('importText')
->willReturn($generator());
// Event with long UID should be skipped, so createCalendarObject should never be called
$this->caldavBackend->expects(self::never())
->method('createCalendarObject');
@@ -197,16 +355,12 @@ class RefreshWebcalServiceTest extends TestCase {
}
#[\PHPUnit\Framework\Attributes\DataProvider('runDataProvider')]
public function testRunCreateCalendarNoException(string $body, string $contentType, string $result): void {
public function testRunCreateCalendarNoException(string $body, string $format, string $result): void {
$refreshWebcalService = $this->getMockBuilder(RefreshWebcalService::class)
->onlyMethods(['getRandomCalendarObjectUri', 'getSubscription',])
->setConstructorArgs([$this->caldavBackend, $this->logger, $this->connection, $this->time])
->onlyMethods(['getSubscription'])
->setConstructorArgs([$this->caldavBackend, $this->logger, $this->connection, $this->timeFactory, $this->importService])
->getMock();
$refreshWebcalService
->method('getRandomCalendarObjectUri')
->willReturn('uri-1.ics');
$refreshWebcalService
->method('getSubscription')
->willReturn([
@@ -220,13 +374,26 @@ class RefreshWebcalServiceTest extends TestCase {
'lastmodified' => 0,
]);
$stream = $this->createStreamFromString($body);
$this->connection->expects(self::once())
->method('queryWebcalFeed')
->willReturn($result);
->willReturn(['data' => $stream, 'format' => $format]);
$this->caldavBackend->expects(self::once())
->method('createCalendarObject')
->with(42, 'uri-1.ics', $result, 1);
->method('getLimitedCalendarObjects')
->willReturn([]);
// Create a VCalendar object that will be yielded by the import service
$vCalendar = VObject\Reader::read($result);
$generator = function () use ($vCalendar) {
yield $vCalendar;
};
$this->importService->expects(self::once())
->method('importText')
->willReturn($generator());
$noInstanceException = new NoInstancesException("can't add calendar object");
$this->caldavBackend->expects(self::once())
@@ -241,16 +408,12 @@ class RefreshWebcalServiceTest extends TestCase {
}
#[\PHPUnit\Framework\Attributes\DataProvider('runDataProvider')]
public function testRunCreateCalendarBadRequest(string $body, string $contentType, string $result): void {
public function testRunCreateCalendarBadRequest(string $body, string $format, string $result): void {
$refreshWebcalService = $this->getMockBuilder(RefreshWebcalService::class)
->onlyMethods(['getRandomCalendarObjectUri', 'getSubscription'])
->setConstructorArgs([$this->caldavBackend, $this->logger, $this->connection, $this->time])
->onlyMethods(['getSubscription'])
->setConstructorArgs([$this->caldavBackend, $this->logger, $this->connection, $this->timeFactory, $this->importService])
->getMock();
$refreshWebcalService
->method('getRandomCalendarObjectUri')
->willReturn('uri-1.ics');
$refreshWebcalService
->method('getSubscription')
->willReturn([
@@ -264,13 +427,26 @@ class RefreshWebcalServiceTest extends TestCase {
'lastmodified' => 0,
]);
$stream = $this->createStreamFromString($body);
$this->connection->expects(self::once())
->method('queryWebcalFeed')
->willReturn($result);
->willReturn(['data' => $stream, 'format' => $format]);
$this->caldavBackend->expects(self::once())
->method('createCalendarObject')
->with(42, 'uri-1.ics', $result, 1);
->method('getLimitedCalendarObjects')
->willReturn([]);
// Create a VCalendar object that will be yielded by the import service
$vCalendar = VObject\Reader::read($result);
$generator = function () use ($vCalendar) {
yield $vCalendar;
};
$this->importService->expects(self::once())
->method('importText')
->willReturn($generator());
$badRequestException = new BadRequest("can't add reach calendar url");
$this->caldavBackend->expects(self::once())
@@ -285,20 +461,22 @@ class RefreshWebcalServiceTest extends TestCase {
}
public static function identicalDataProvider(): array {
$icalBody = "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject " . VObject\Version::VERSION . "//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:12345\r\nDTSTAMP:20160218T133704Z\r\nDTSTART;VALUE=DATE:19000101\r\nDTEND;VALUE=DATE:19000102\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:12345's Birthday (1900)\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
$etag = md5($icalBody);
return [
[
'12345',
[
'12345' => [
'id' => 42,
'etag' => 100,
'uri' => 'sub456',
'calendardata' => "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:12345\r\nDTSTAMP:20160218T133704Z\r\nDTSTART;VALUE=DATE:19000101\r\nDTEND;VALUE=DATE:19000102\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:12345's Birthday (1900)\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n",
'etag' => $etag,
'uri' => 'sub456.ics',
],
],
"BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:12345\r\nDTSTAMP:20160218T133704Z\r\nDTSTART;VALUE=DATE:19000101\r\nDTEND;VALUE=DATE:19000102\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:12345's Birthday (1900)\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n",
'text/calendar;charset=utf8',
"BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:12345\r\nDTSTAMP:20180218T133704Z\r\nDTSTART;VALUE=DATE:19000101\r\nDTEND;VALUE=DATE:19000102\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:12345's Birthday (1900)\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n",
'ical',
$icalBody,
],
];
}
@@ -307,19 +485,9 @@ class RefreshWebcalServiceTest extends TestCase {
return [
[
"BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:12345\r\nDTSTAMP:20160218T133704Z\r\nDTSTART;VALUE=DATE:19000101\r\nDTEND;VALUE=DATE:19000102\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:12345's Birthday (1900)\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n",
'text/calendar;charset=utf8',
'ical',
"BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject " . VObject\Version::VERSION . "//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:12345\r\nDTSTAMP:20160218T133704Z\r\nDTSTART;VALUE=DATE:19000101\r\nDTEND;VALUE=DATE:19000102\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:12345's Birthday (1900)\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n",
],
[
'["vcalendar",[["prodid",{},"text","-//Example Corp.//Example Client//EN"],["version",{},"text","2.0"]],[["vtimezone",[["last-modified",{},"date-time","2004-01-10T03:28:45Z"],["tzid",{},"text","US/Eastern"]],[["daylight",[["dtstart",{},"date-time","2000-04-04T02:00:00"],["rrule",{},"recur",{"freq":"YEARLY","byday":"1SU","bymonth":4}],["tzname",{},"text","EDT"],["tzoffsetfrom",{},"utc-offset","-05:00"],["tzoffsetto",{},"utc-offset","-04:00"]],[]],["standard",[["dtstart",{},"date-time","2000-10-26T02:00:00"],["rrule",{},"recur",{"freq":"YEARLY","byday":"1SU","bymonth":10}],["tzname",{},"text","EST"],["tzoffsetfrom",{},"utc-offset","-04:00"],["tzoffsetto",{},"utc-offset","-05:00"]],[]]]],["vevent",[["dtstamp",{},"date-time","2006-02-06T00:11:21Z"],["dtstart",{"tzid":"US/Eastern"},"date-time","2006-01-02T14:00:00"],["duration",{},"duration","PT1H"],["recurrence-id",{"tzid":"US/Eastern"},"date-time","2006-01-04T12:00:00"],["summary",{},"text","Event #2"],["uid",{},"text","12345"]],[]]]]',
'application/calendar+json',
"BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject " . VObject\Version::VERSION . "//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VTIMEZONE\r\nLAST-MODIFIED:20040110T032845Z\r\nTZID:US/Eastern\r\nBEGIN:DAYLIGHT\r\nDTSTART:20000404T020000\r\nRRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4\r\nTZNAME:EDT\r\nTZOFFSETFROM:-0500\r\nTZOFFSETTO:-0400\r\nEND:DAYLIGHT\r\nBEGIN:STANDARD\r\nDTSTART:20001026T020000\r\nRRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=10\r\nTZNAME:EST\r\nTZOFFSETFROM:-0400\r\nTZOFFSETTO:-0500\r\nEND:STANDARD\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nDTSTAMP:20060206T001121Z\r\nDTSTART;TZID=US/Eastern:20060102T140000\r\nDURATION:PT1H\r\nRECURRENCE-ID;TZID=US/Eastern:20060104T120000\r\nSUMMARY:Event #2\r\nUID:12345\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"
],
[
'<?xml version="1.0" encoding="utf-8" ?><icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0"><vcalendar><properties><prodid><text>-//Example Inc.//Example Client//EN</text></prodid><version><text>2.0</text></version></properties><components><vevent><properties><dtstamp><date-time>2006-02-06T00:11:21Z</date-time></dtstamp><dtstart><parameters><tzid><text>US/Eastern</text></tzid></parameters><date-time>2006-01-04T14:00:00</date-time></dtstart><duration><duration>PT1H</duration></duration><recurrence-id><parameters><tzid><text>US/Eastern</text></tzid></parameters><date-time>2006-01-04T12:00:00</date-time></recurrence-id><summary><text>Event #2 bis</text></summary><uid><text>12345</text></uid></properties></vevent></components></vcalendar></icalendar>',
'application/calendar+xml',
"BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject " . VObject\Version::VERSION . "//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nDTSTAMP:20060206T001121Z\r\nDTSTART;TZID=US/Eastern:20060104T140000\r\nDURATION:PT1H\r\nRECURRENCE-ID;TZID=US/Eastern:20060104T120000\r\nSUMMARY:Event #2 bis\r\nUID:12345\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"
]
];
}
}
@@ -403,31 +403,31 @@ class BirthdayServiceTest extends TestCase {
[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, 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, 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', 'FREQ=YEARLY', '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', 'FREQ=YEARLY', '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', 'FREQ=YEARLY', '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', 'FREQ=YEARLY', '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', 'FREQ=YEARLY', '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', 'FREQ=YEARLY', '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 (1900)', '19000101', 'FREQ=YEARLY', '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)', '19001231', 'FREQ=YEARLY', '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)', '19001231', 'FREQ=YEARLY', '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)', '19001231', 'FREQ=YEARLY', '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)', '19001231', 'FREQ=YEARLY', '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)', '19001231', 'FREQ=YEARLY', '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', 'FREQ=YEARLY', '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', 'FREQ=YEARLY', '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, 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, 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', 'FREQ=YEARLY', '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', 'FREQ=YEARLY', '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', 'FREQ=YEARLY', '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 (900)', '09001231', 'FREQ=YEARLY', '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)', '19000101', 'FREQ=YEARLY', '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)', '19001231', 'FREQ=YEARLY', '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', 'FREQ=YEARLY', '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', 'FREQ=YEARLY', '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, 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, 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', 'FREQ=YEARLY', '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', 'FREQ=YEARLY', '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', 'FREQ=YEARLY', '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', 'FREQ=YEARLY', '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'],
['12345 (*900)', '09001231', 'FREQ=YEARLY', '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)', '19001231', 'FREQ=YEARLY', '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)', '19001231', 'FREQ=YEARLY', '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)', '19001231', 'FREQ=YEARLY', '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'],
[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:19000101\r\nX-NC-EXCLUDE-FROM-BIRTHDAY-CALENDAR;TYPE=boolean:true\r\nEND:VCARD\r\n", 'BDAY', '', true, null],
[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\nX-NC-EXCLUDE-FROM-BIRTHDAY-CALENDAR;TYPE=boolean:true\r\nDEATHDATE:19001231\r\nEND:VCARD\r\n", 'DEATHDATE', '-death', true, null],
[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\nANNIVERSARY:19001231\r\nX-NC-EXCLUDE-FROM-BIRTHDAY-CALENDAR;TYPE=boolean:true\r\nEND:VCARD\r\n", 'ANNIVERSARY', '-anniversary', true, null],
['🎂 12345 (1902)', '19720229', 'FREQ=YEARLY;BYMONTH=2;BYMONTHDAY=-1', 'BDAY', '0', 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:19020229\r\nEND:VCARD\r\n", 'BDAY', '', true, null],
['🎂 12345 (1904)', '19040229', 'FREQ=YEARLY;BYMONTH=2;BYMONTHDAY=-1', 'BDAY', '0', '1904', 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:19040229\r\nEND:VCARD\r\n", 'BDAY', '', true, null],
];
}
}
@@ -48,14 +48,16 @@ class EntityCollectionTest extends \Test\TestCase {
}
public function testGetChild(): void {
$comment = $this->createMock(IComment::class);
$comment->method('getObjectType')
->willReturn('files');
$comment->method('getObjectId')
->willReturn('19');
$this->commentsManager->expects($this->once())
->method('get')
->with('55')
->willReturn(
$this->getMockBuilder(IComment::class)
->disableOriginalConstructor()
->getMock()
);
->willReturn($comment);
$node = $this->collection->getChild('55');
$this->assertInstanceOf(CommentNode::class, $node);
@@ -107,6 +109,17 @@ class EntityCollectionTest extends \Test\TestCase {
}
public function testChildExistsTrue(): void {
$comment = $this->createMock(IComment::class);
$comment->method('getObjectType')
->willReturn('files');
$comment->method('getObjectId')
->willReturn('19');
$this->commentsManager->expects($this->once())
->method('get')
->with('44')
->willReturn($comment);
$this->assertTrue($this->collection->childExists('44'));
}
@@ -10,6 +10,7 @@ namespace OCA\DAV\Tests\unit\Connector\Sabre;
use OC\Files\FileInfo;
use OC\Files\Filesystem;
use OC\Files\Node\Folder;
use OC\Files\Node\Node;
use OC\Files\Storage\Wrapper\Quota;
use OC\Files\View;
@@ -21,8 +22,10 @@ use OCP\Constants;
use OCP\Files\ForbiddenException;
use OCP\Files\InvalidPathException;
use OCP\Files\Mount\IMountPoint;
use OCP\Files\Storage\IStorage;
use OCP\Files\StorageNotAvailableException;
use PHPUnit\Framework\MockObject\MockObject;
use Sabre\DAV\Exception\NotFound;
use Test\Traits\UserTrait;
class TestViewDirectory extends View {
@@ -61,12 +64,16 @@ class DirectoryTest extends \Test\TestCase {
private View&MockObject $view;
private FileInfo&MockObject $info;
private IStorage&MockObject $storage;
protected function setUp(): void {
parent::setUp();
$this->view = $this->createMock(View::class);
$this->info = $this->createMock(FileInfo::class);
$this->storage = $this->createMock(IStorage::class);
$this->info->method('getStorage')
->willReturn($this->storage);
$this->info->method('isReadable')
->willReturn(true);
$this->info->method('getType')
@@ -266,6 +273,146 @@ class DirectoryTest extends \Test\TestCase {
$dir->getChild('.');
}
public function testGetNodeForPath(): void {
$directoryNode = $this->createMock(Folder::class);
$pathNode = $this->createMock(Folder::class);
$pathParentNode = $this->createMock(Folder::class);
$storage = $this->createMock(IStorage::class);
$directoryNode->expects($this->once())
->method('getStorage')
->willReturn($storage);
$storage->expects($this->once())
->method('instanceOfStorage')
->willReturn(false);
$directoryNode->expects($this->once())
->method('isReadable')
->willReturn(true);
$directoryNode->expects($this->once())
->method('getPath')
->willReturn('/admin/files/');
$directoryNode->expects($this->once())
->method('get')
->willReturn($pathNode);
$pathNode->expects($this->once())
->method('getPath')
->willReturn('/admin/files/my/deep/folder/');
$pathNode->expects($this->once())
->method('isReadable')
->willReturn(true);
$pathNode->expects($this->once())
->method('getMimetype')
->willReturn(FileInfo::MIMETYPE_FOLDER);
$this->view->method('getRelativePath')
->willReturnCallback(function ($path) {
return str_replace('/admin/files/', '', $path);
});
$this->view->expects($this->exactly(2))
->method('getFileInfo')
->willReturn($pathParentNode);
$pathParentNode->expects($this->exactly(2))
->method('getPath')
->willReturnOnConsecutiveCalls('/my/deep', '/my');
$pathParentNode->expects($this->exactly(2))
->method('isReadable')
->willReturn(true);
$dir = new Directory($this->view, $directoryNode);
$dir->getNodeForPath('/my/deep/folder/');
}
public function testGetNodeForPathFailsWithNoReadPermissionsForParent(): void {
$directoryNode = $this->createMock(Folder::class);
$pathNode = $this->createMock(Folder::class);
$pathParentNode = $this->createMock(Folder::class);
$storage = $this->createMock(IStorage::class);
$directoryNode->expects($this->once())
->method('getStorage')
->willReturn($storage);
$storage->expects($this->once())
->method('instanceOfStorage')
->willReturn(false);
$directoryNode->expects($this->once())
->method('isReadable')
->willReturn(true);
$directoryNode->expects($this->once())
->method('getPath')
->willReturn('/admin/files/');
$directoryNode->expects($this->once())
->method('get')
->willReturn($pathNode);
$pathNode->expects($this->once())
->method('getPath')
->willReturn('/admin/files/my/deep/folder/');
$pathNode->expects($this->once())
->method('isReadable')
->willReturn(true);
$pathNode->expects($this->once())
->method('getMimetype')
->willReturn(FileInfo::MIMETYPE_FOLDER);
$this->view->method('getRelativePath')
->willReturnCallback(function ($path) {
return str_replace('/admin/files/', '', $path);
});
$this->view->expects($this->exactly(2))
->method('getFileInfo')
->willReturn($pathParentNode);
$pathParentNode->expects($this->exactly(2))
->method('getPath')
->willReturnOnConsecutiveCalls('/my/deep', '/my');
$pathParentNode->expects($this->exactly(2))
->method('isReadable')
->willReturnOnConsecutiveCalls(true, false);
$this->expectException(NotFound::class);
$dir = new Directory($this->view, $directoryNode);
$dir->getNodeForPath('/my/deep/folder/');
}
public function testGetNodeForPathFailsWithNoReadPermissionsForPath(): void {
$directoryNode = $this->createMock(Folder::class);
$pathNode = $this->createMock(Folder::class);
$storage = $this->createMock(IStorage::class);
$directoryNode->expects($this->once())
->method('getStorage')
->willReturn($storage);
$storage->expects($this->once())
->method('instanceOfStorage')
->willReturn(false);
$directoryNode->expects($this->once())
->method('isReadable')
->willReturn(true);
$directoryNode->expects($this->once())
->method('getPath')
->willReturn('/admin/files/');
$directoryNode->expects($this->once())
->method('get')
->willReturn($pathNode);
$pathNode->expects($this->once())
->method('isReadable')
->willReturn(false);
$this->expectException(\Sabre\DAV\Exception\Forbidden::class);
$dir = new Directory($this->view, $directoryNode);
$dir->getNodeForPath('/my/deep/folder/');
}
public function testGetQuotaInfoUnlimited(): void {
$this->createUser('user', 'password');
self::loginAsUser('user');
@@ -7,14 +7,14 @@ namespace Composer\Autoload;
class ComposerStaticInitEncryption
{
public static $prefixLengthsPsr4 = array (
'O' =>
'O' =>
array (
'OCA\\Encryption\\' => 15,
),
);
public static $prefixDirsPsr4 = array (
'OCA\\Encryption\\' =>
'OCA\\Encryption\\' =>
array (
0 => __DIR__ . '/..' . '/../lib',
),
@@ -7,14 +7,14 @@ namespace Composer\Autoload;
class ComposerStaticInitFederatedFileSharing
{
public static $prefixLengthsPsr4 = array (
'O' =>
'O' =>
array (
'OCA\\FederatedFileSharing\\' => 25,
),
);
public static $prefixDirsPsr4 = array (
'OCA\\FederatedFileSharing\\' =>
'OCA\\FederatedFileSharing\\' =>
array (
0 => __DIR__ . '/..' . '/../lib',
),
+5 -5
View File
@@ -25,14 +25,14 @@ OC.L10N.register(
"Provide federated file sharing across servers" : "توفير مشاركة الملفات عبر خوادم السحابة الاتحادية",
"Confirm data upload to lookup server" : "تأكيد تحميل البيانات لخادوم البحث",
"When enabled, all account properties (e.g. email address) with scope visibility set to \"published\", will be automatically synced and transmitted to an external system and made available in a public, global address book." : "عند تفعيل هذا الخيار، ستتم تلقائياً مزامنة جميع خصائص الحساب (على سبيل المثال عنوان البريد الإلكتروني) التي تم تعيين \"نطاق الرؤية\" visibility scope فيها على \"منشور published\"، وإرسالها إلى نظام خارجي وإتاحتها في دفتر عناوين عمومي شامل.",
"Disable upload" : "تعطيل الرفع",
"Enable data upload" : "تمكين رفع البيانات",
"Disable upload" : "تعطيل الرفع",
"Confirm querying lookup server" : "تأكيد استعلام خادوم البحث",
"When enabled, the search input when creating shares will be sent to an external system that provides a public and global address book." : "عند تمكين هذا الخيار، سيتم إرسال إدخال البحث عند إنشاء المشاركات إلى نظام خارجي يوفر دفتر عناوين شامل وعمومي.",
"This is used to retrieve the federated cloud ID to make federated sharing easier." : "يستعمل هذا لاسترجاع معرف السحابة الاتحادية وذلك لتسهيل المشاركات الاتحادية",
"Moreover, email addresses of users might be sent to that system in order to verify them." : "علاوة على ذلك، قد يتم إرسال عناوين البريد الإلكتروني للمستخدِمين إلى ذلك النظام للتحقق منها.",
"Disable querying" : "تعطيل الاستعلام",
"Enable querying" : "تمكين الاستعلام",
"Disable querying" : "تعطيل الاستعلام",
"Unable to update federated files sharing config" : "تعذر تحديث تهيئة مشاركة الملفات عبر السحابة الاتحادية",
"Adjust how people can share between servers. This includes shares between people on this server as well if they are using federated sharing." : "اضبط كيفية مشاركة الأشخاص بين الخوادم. هذا يشمل المشاركات بين الأشخاص على هذا الخادوم أيضاً إذا كانوا يستعملون المشاركة عبر السحابة الاتحادية.",
"Allow people on this server to send shares to other servers (this option also allows WebDAV access to public shares)" : "السماح للأشخاص على هذا الخادوم بإرسال مشاركات إلى خوادم أخرى (هذا الخيار يسمح أيضاً بالوصول عبر WebDAV إلى المشاركات العمومية)",
@@ -54,8 +54,6 @@ OC.L10N.register(
"Your Federated Cloud ID" : "مُعرِّف شبكتك الاتحادية",
"Share it so your friends can share files with you:" : "شاركه مع أصدقائك بحيث يمكنهم مُشاركة الملفات معك:",
"Facebook" : "فيسبوك",
"X (formerly Twitter)" : "منصة X (تويتر سابقاً)",
"formerly Twitter" : "تويتر سابقاً",
"Mastodon" : "برنامج ماستودون Mastodon",
"Add to your website" : "أضِف إلى موقعك على الويب",
"HTML Code:" : "كود HTML: ",
@@ -67,6 +65,8 @@ OC.L10N.register(
"Incoming share could not be processed" : "لا يمكن معالجة المشاركة الواردة",
"Cloud ID copied to the clipboard" : "تمّ نسخ مُعرِّف السحابة إلى الحافظة",
"Copy to clipboard" : "نسخ الرابط",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "يُمكنك المشاركة مع أي شخص يستخدم خادم نكست كلاود أو خوادم وخدمات أخرى متوافقة مع بروتوكول Open Cloud Mesh (OCM)! فقط ضع مُعرّف السحابة الاتحادية في مربع حوار المُشاركة؛ و الذي سيكون شكله على هذا النسق: person@cloud.example.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "يُمكنك المشاركة مع أي شخص يستخدم خادم نكست كلاود أو خوادم وخدمات أخرى متوافقة مع بروتوكول Open Cloud Mesh (OCM)! فقط ضع مُعرّف السحابة الاتحادية في مربع حوار المُشاركة؛ و الذي سيكون شكله على هذا النسق: person@cloud.example.com",
"X (formerly Twitter)" : "منصة X (تويتر سابقاً)",
"formerly Twitter" : "تويتر سابقاً"
},
"nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;");
+5 -5
View File
@@ -23,14 +23,14 @@
"Provide federated file sharing across servers" : "توفير مشاركة الملفات عبر خوادم السحابة الاتحادية",
"Confirm data upload to lookup server" : "تأكيد تحميل البيانات لخادوم البحث",
"When enabled, all account properties (e.g. email address) with scope visibility set to \"published\", will be automatically synced and transmitted to an external system and made available in a public, global address book." : "عند تفعيل هذا الخيار، ستتم تلقائياً مزامنة جميع خصائص الحساب (على سبيل المثال عنوان البريد الإلكتروني) التي تم تعيين \"نطاق الرؤية\" visibility scope فيها على \"منشور published\"، وإرسالها إلى نظام خارجي وإتاحتها في دفتر عناوين عمومي شامل.",
"Disable upload" : "تعطيل الرفع",
"Enable data upload" : "تمكين رفع البيانات",
"Disable upload" : "تعطيل الرفع",
"Confirm querying lookup server" : "تأكيد استعلام خادوم البحث",
"When enabled, the search input when creating shares will be sent to an external system that provides a public and global address book." : "عند تمكين هذا الخيار، سيتم إرسال إدخال البحث عند إنشاء المشاركات إلى نظام خارجي يوفر دفتر عناوين شامل وعمومي.",
"This is used to retrieve the federated cloud ID to make federated sharing easier." : "يستعمل هذا لاسترجاع معرف السحابة الاتحادية وذلك لتسهيل المشاركات الاتحادية",
"Moreover, email addresses of users might be sent to that system in order to verify them." : "علاوة على ذلك، قد يتم إرسال عناوين البريد الإلكتروني للمستخدِمين إلى ذلك النظام للتحقق منها.",
"Disable querying" : "تعطيل الاستعلام",
"Enable querying" : "تمكين الاستعلام",
"Disable querying" : "تعطيل الاستعلام",
"Unable to update federated files sharing config" : "تعذر تحديث تهيئة مشاركة الملفات عبر السحابة الاتحادية",
"Adjust how people can share between servers. This includes shares between people on this server as well if they are using federated sharing." : "اضبط كيفية مشاركة الأشخاص بين الخوادم. هذا يشمل المشاركات بين الأشخاص على هذا الخادوم أيضاً إذا كانوا يستعملون المشاركة عبر السحابة الاتحادية.",
"Allow people on this server to send shares to other servers (this option also allows WebDAV access to public shares)" : "السماح للأشخاص على هذا الخادوم بإرسال مشاركات إلى خوادم أخرى (هذا الخيار يسمح أيضاً بالوصول عبر WebDAV إلى المشاركات العمومية)",
@@ -52,8 +52,6 @@
"Your Federated Cloud ID" : "مُعرِّف شبكتك الاتحادية",
"Share it so your friends can share files with you:" : "شاركه مع أصدقائك بحيث يمكنهم مُشاركة الملفات معك:",
"Facebook" : "فيسبوك",
"X (formerly Twitter)" : "منصة X (تويتر سابقاً)",
"formerly Twitter" : "تويتر سابقاً",
"Mastodon" : "برنامج ماستودون Mastodon",
"Add to your website" : "أضِف إلى موقعك على الويب",
"HTML Code:" : "كود HTML: ",
@@ -65,6 +63,8 @@
"Incoming share could not be processed" : "لا يمكن معالجة المشاركة الواردة",
"Cloud ID copied to the clipboard" : "تمّ نسخ مُعرِّف السحابة إلى الحافظة",
"Copy to clipboard" : "نسخ الرابط",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "يُمكنك المشاركة مع أي شخص يستخدم خادم نكست كلاود أو خوادم وخدمات أخرى متوافقة مع بروتوكول Open Cloud Mesh (OCM)! فقط ضع مُعرّف السحابة الاتحادية في مربع حوار المُشاركة؛ و الذي سيكون شكله على هذا النسق: person@cloud.example.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "يُمكنك المشاركة مع أي شخص يستخدم خادم نكست كلاود أو خوادم وخدمات أخرى متوافقة مع بروتوكول Open Cloud Mesh (OCM)! فقط ضع مُعرّف السحابة الاتحادية في مربع حوار المُشاركة؛ و الذي سيكون شكله على هذا النسق: person@cloud.example.com",
"X (formerly Twitter)" : "منصة X (تويتر سابقاً)",
"formerly Twitter" : "تويتر سابقاً"
},"pluralForm" :"nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;"
}
+2 -2
View File
@@ -39,7 +39,6 @@ OC.L10N.register(
"Federated Cloud" : "Nube federada",
"Share it so your friends can share files with you:" : "Compártilu pa que los tos amigos puedan compartir ficheros contigo:",
"Facebook" : "Facebook",
"X (formerly Twitter)" : "X (anteriormente Twitter)",
"Mastodon" : "Mastodon",
"Add to your website" : "Amestar al to sitiu web",
"HTML Code:" : "Códigu HTML:",
@@ -50,6 +49,7 @@ OC.L10N.register(
"Remote share password" : "Contraseña de la compartición remota",
"Cloud ID copied to the clipboard" : "La ID de la nube copióse nel cartafueyu",
"Copy to clipboard" : "Copiar nel cartafueyu",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Pues compartir conteníu con cualesquier persona qu'use un sirvidor de Nextcloud o otros sirvidores y servicios compatibles con Open Cloud Mesh (OCM). Namás indica la ID de na nube federada nel cuadru de diálogu d'usu compartíu. Aseméyase a persona@nube.exemplu.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Pues compartir conteníu con cualesquier persona qu'use un sirvidor de Nextcloud o otros sirvidores y servicios compatibles con Open Cloud Mesh (OCM). Namás indica la ID de na nube federada nel cuadru de diálogu d'usu compartíu. Aseméyase a persona@nube.exemplu.com",
"X (formerly Twitter)" : "X (anteriormente Twitter)"
},
"nplurals=2; plural=(n != 1);");
+2 -2
View File
@@ -37,7 +37,6 @@
"Federated Cloud" : "Nube federada",
"Share it so your friends can share files with you:" : "Compártilu pa que los tos amigos puedan compartir ficheros contigo:",
"Facebook" : "Facebook",
"X (formerly Twitter)" : "X (anteriormente Twitter)",
"Mastodon" : "Mastodon",
"Add to your website" : "Amestar al to sitiu web",
"HTML Code:" : "Códigu HTML:",
@@ -48,6 +47,7 @@
"Remote share password" : "Contraseña de la compartición remota",
"Cloud ID copied to the clipboard" : "La ID de la nube copióse nel cartafueyu",
"Copy to clipboard" : "Copiar nel cartafueyu",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Pues compartir conteníu con cualesquier persona qu'use un sirvidor de Nextcloud o otros sirvidores y servicios compatibles con Open Cloud Mesh (OCM). Namás indica la ID de na nube federada nel cuadru de diálogu d'usu compartíu. Aseméyase a persona@nube.exemplu.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Pues compartir conteníu con cualesquier persona qu'use un sirvidor de Nextcloud o otros sirvidores y servicios compatibles con Open Cloud Mesh (OCM). Namás indica la ID de na nube federada nel cuadru de diálogu d'usu compartíu. Aseméyase a persona@nube.exemplu.com",
"X (formerly Twitter)" : "X (anteriormente Twitter)"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}
+4 -4
View File
@@ -30,10 +30,9 @@ OC.L10N.register(
"Copied!" : "Копирано!",
"Federated Cloud" : "Федериран облак",
"Share it so your friends can share files with you:" : "Споделете, за да могат приятелите ви да споделят файлове, с вас:",
"Facebook" : "Фейсбук",
"X (formerly Twitter)" : "X (преди Twitter)",
"Mastodon" : "Mastodon",
"Bluesky" : "Bluesky",
"Facebook" : "Фейсбук",
"Mastodon" : "Mastodon",
"Add to your website" : "Добавете към вашия уеб сайт",
"HTML Code:" : "HTML код:",
"Cancel" : "Отказ",
@@ -43,6 +42,7 @@ OC.L10N.register(
"Remote share password" : "Парола за отдалечено споделяне",
"Cloud ID copied to the clipboard" : "Cloud идентификатора е копиран в клипборда",
"Copy to clipboard" : "Копиране в клипборда",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Можете да споделяте с всеки, който използва сървър Nextcloud или други сървъри и услуги, съвместими с Open Cloud Mesh (OCM)! Просто поставете техния идентификатор за Федериран облак в диалоговия прозорец за споделяне. Изглежда като person@cloud.example.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Можете да споделяте с всеки, който използва сървър Nextcloud или други сървъри и услуги, съвместими с Open Cloud Mesh (OCM)! Просто поставете техния идентификатор за Федериран облак в диалоговия прозорец за споделяне. Изглежда като person@cloud.example.com",
"X (formerly Twitter)" : "X (преди Twitter)"
},
"nplurals=2; plural=(n != 1);");
+4 -4
View File
@@ -28,10 +28,9 @@
"Copied!" : "Копирано!",
"Federated Cloud" : "Федериран облак",
"Share it so your friends can share files with you:" : "Споделете, за да могат приятелите ви да споделят файлове, с вас:",
"Facebook" : "Фейсбук",
"X (formerly Twitter)" : "X (преди Twitter)",
"Mastodon" : "Mastodon",
"Bluesky" : "Bluesky",
"Facebook" : "Фейсбук",
"Mastodon" : "Mastodon",
"Add to your website" : "Добавете към вашия уеб сайт",
"HTML Code:" : "HTML код:",
"Cancel" : "Отказ",
@@ -41,6 +40,7 @@
"Remote share password" : "Парола за отдалечено споделяне",
"Cloud ID copied to the clipboard" : "Cloud идентификатора е копиран в клипборда",
"Copy to clipboard" : "Копиране в клипборда",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Можете да споделяте с всеки, който използва сървър Nextcloud или други сървъри и услуги, съвместими с Open Cloud Mesh (OCM)! Просто поставете техния идентификатор за Федериран облак в диалоговия прозорец за споделяне. Изглежда като person@cloud.example.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Можете да споделяте с всеки, който използва сървър Nextcloud или други сървъри и услуги, съвместими с Open Cloud Mesh (OCM)! Просто поставете техния идентификатор за Федериран облак в диалоговия прозорец за споделяне. Изглежда като person@cloud.example.com",
"X (formerly Twitter)" : "X (преди Twitter)"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}
+3 -3
View File
@@ -44,8 +44,6 @@ OC.L10N.register(
"Your Federated Cloud ID" : "El vostre ID de núvol federat",
"Share it so your friends can share files with you:" : "Compartiu-lo perquè els vostres amics puguin enviar-vos fitxers compartits:",
"Facebook" : "Facebook",
"X (formerly Twitter)" : "X (abans Twitter)",
"formerly Twitter" : "abans Twitter",
"Mastodon" : "Mastodon",
"Add to your website" : "Afegiu-lo al vostre lloc web",
"HTML Code:" : "Codi HTML:",
@@ -57,6 +55,8 @@ OC.L10N.register(
"Incoming share could not be processed" : "No s'ha pogut processar la compartició entrant",
"Cloud ID copied to the clipboard" : "S'ha copiat l'ID del núvol al porta-retalls",
"Copy to clipboard" : "Copia-ho al porta-retalls",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Podeu compartir contingut amb qualsevol persona que utilitzi un servidor del Nextcloud o altres servidors i serveis compatibles amb Open Cloud Mesh (OCM)! Només cal que n'indiqueu l'ID de núvol federat al quadre de diàleg d'ús compatit. És semblant a persona@nuvol.exemple.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Podeu compartir contingut amb qualsevol persona que utilitzi un servidor del Nextcloud o altres servidors i serveis compatibles amb Open Cloud Mesh (OCM)! Només cal que n'indiqueu l'ID de núvol federat al quadre de diàleg d'ús compatit. És semblant a persona@nuvol.exemple.com",
"X (formerly Twitter)" : "X (abans Twitter)",
"formerly Twitter" : "abans Twitter"
},
"nplurals=2; plural=(n != 1);");
+3 -3
View File
@@ -42,8 +42,6 @@
"Your Federated Cloud ID" : "El vostre ID de núvol federat",
"Share it so your friends can share files with you:" : "Compartiu-lo perquè els vostres amics puguin enviar-vos fitxers compartits:",
"Facebook" : "Facebook",
"X (formerly Twitter)" : "X (abans Twitter)",
"formerly Twitter" : "abans Twitter",
"Mastodon" : "Mastodon",
"Add to your website" : "Afegiu-lo al vostre lloc web",
"HTML Code:" : "Codi HTML:",
@@ -55,6 +53,8 @@
"Incoming share could not be processed" : "No s'ha pogut processar la compartició entrant",
"Cloud ID copied to the clipboard" : "S'ha copiat l'ID del núvol al porta-retalls",
"Copy to clipboard" : "Copia-ho al porta-retalls",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Podeu compartir contingut amb qualsevol persona que utilitzi un servidor del Nextcloud o altres servidors i serveis compatibles amb Open Cloud Mesh (OCM)! Només cal que n'indiqueu l'ID de núvol federat al quadre de diàleg d'ús compatit. És semblant a persona@nuvol.exemple.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Podeu compartir contingut amb qualsevol persona que utilitzi un servidor del Nextcloud o altres servidors i serveis compatibles amb Open Cloud Mesh (OCM)! Només cal que n'indiqueu l'ID de núvol federat al quadre de diàleg d'ús compatit. És semblant a persona@nuvol.exemple.com",
"X (formerly Twitter)" : "X (abans Twitter)",
"formerly Twitter" : "abans Twitter"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}
+7 -7
View File
@@ -25,14 +25,14 @@ OC.L10N.register(
"Provide federated file sharing across servers" : "Poskytnout federované sdílení souborů napříč servery",
"Confirm data upload to lookup server" : "Potvrdit nahrávání dat na vyhledávací server",
"When enabled, all account properties (e.g. email address) with scope visibility set to \"published\", will be automatically synced and transmitted to an external system and made available in a public, global address book." : "Pokud zapnuto, veškeré vlastnosti účtu (např. e-mailová adresa) s rozsahem viditelnosti nastavené na „zveřejněné“ budou automaticky synchronizovány a přenášeny do externího systému a veřejně k dispozici v globální adresáři kontaktů.",
"Disable upload" : "Vypnout nahrávání",
"Enable data upload" : "Zapnout nahrávání dat",
"Disable upload" : "Vypnout nahrávání",
"Confirm querying lookup server" : "Potvrdit dotazování vyhledávacího serveru",
"When enabled, the search input when creating shares will be sent to an external system that provides a public and global address book." : "Pokud zapnuto, obsah hledání při vytváření sdílení bude odeslán na externí systém, který poskytuje veřejný a globální adresář kontaktů.",
"This is used to retrieve the federated cloud ID to make federated sharing easier." : "Toto slouží k získávání identifikátorů v rámci federovaného cloudu pro usnadnění federovaného sdílení.",
"Moreover, email addresses of users might be sent to that system in order to verify them." : "Dále mohou být pro ověření odeslány na server e-mailové adresy uživatelů.",
"Disable querying" : "Vypnout dotazování",
"Enable querying" : "Zapnout dotazování",
"Disable querying" : "Vypnout dotazování",
"Unable to update federated files sharing config" : "Nedaří se aktualizovat nastavení federovaného sdílení souborů",
"Adjust how people can share between servers. This includes shares between people on this server as well if they are using federated sharing." : "Upravte, jak mohou lidé sdílet mezi servery. Týká se sdílení mezi lidmi na tomto serveru a stejně tak uživatelů federovaného sdílení.",
"Allow people on this server to send shares to other servers (this option also allows WebDAV access to public shares)" : "Umožnit lidem na tomto serveru posílat sdílení na ostatní servery (tato volba také umožňuje WebDAV přístup k veřejným sdílením)",
@@ -55,11 +55,9 @@ OC.L10N.register(
"You can share with anyone who uses a {productName} server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Můžete sdílet s kýmkoliv, kdo používá {productName} nebo jiný server či služby, kompatibilní se standardem Open Cloud Mesh (OCM)! Stačí do dialogu pro sdílení zadat jejich jejich identif. v rámci sdruženého cloudu. Má podobu person@cloud.example.com",
"Your Federated Cloud ID" : "Váš identifikátor v rámci fedorovaného cloudu",
"Share it so your friends can share files with you:" : "Podělte se o to, aby mohli vaši přátelé s vámi mohli sdílet soubory:",
"Facebook" : "Facebook",
"X (formerly Twitter)" : "X (dříve Twitter)",
"formerly Twitter" : "dříve Twitter",
"Mastodon" : "Mastodon",
"Bluesky" : "Bluesky",
"Facebook" : "Facebook",
"Mastodon" : "Mastodon",
"Add to your website" : "Přidat na svou webovou stránku",
"Share with me via {productName}" : "Nasdíleno mě prostřednictvím {productName}",
"HTML Code:" : "HTML kód:",
@@ -71,6 +69,8 @@ OC.L10N.register(
"Incoming share could not be processed" : "Příchozí sdílení se nepodařilo zpracovat",
"Cloud ID copied to the clipboard" : "Cloudový identifikátor zkopírován do schránky",
"Copy to clipboard" : "Zkopírovat do schránky",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Můžete sdílet s kýmkoliv, kdo používá Nextcloud nebo jiný server či služby, kompatibilní se standardem Open Cloud Mesh (OCM)! Stačí do dialogu pro sdílení zadat jejich jejich identif. v rámci sdruženého cloudu. Má podobu person@cloud.example.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Můžete sdílet s kýmkoliv, kdo používá Nextcloud nebo jiný server či služby, kompatibilní se standardem Open Cloud Mesh (OCM)! Stačí do dialogu pro sdílení zadat jejich jejich identif. v rámci sdruženého cloudu. Má podobu person@cloud.example.com",
"X (formerly Twitter)" : "X (dříve Twitter)",
"formerly Twitter" : "dříve Twitter"
},
"nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;");
+7 -7
View File
@@ -23,14 +23,14 @@
"Provide federated file sharing across servers" : "Poskytnout federované sdílení souborů napříč servery",
"Confirm data upload to lookup server" : "Potvrdit nahrávání dat na vyhledávací server",
"When enabled, all account properties (e.g. email address) with scope visibility set to \"published\", will be automatically synced and transmitted to an external system and made available in a public, global address book." : "Pokud zapnuto, veškeré vlastnosti účtu (např. e-mailová adresa) s rozsahem viditelnosti nastavené na „zveřejněné“ budou automaticky synchronizovány a přenášeny do externího systému a veřejně k dispozici v globální adresáři kontaktů.",
"Disable upload" : "Vypnout nahrávání",
"Enable data upload" : "Zapnout nahrávání dat",
"Disable upload" : "Vypnout nahrávání",
"Confirm querying lookup server" : "Potvrdit dotazování vyhledávacího serveru",
"When enabled, the search input when creating shares will be sent to an external system that provides a public and global address book." : "Pokud zapnuto, obsah hledání při vytváření sdílení bude odeslán na externí systém, který poskytuje veřejný a globální adresář kontaktů.",
"This is used to retrieve the federated cloud ID to make federated sharing easier." : "Toto slouží k získávání identifikátorů v rámci federovaného cloudu pro usnadnění federovaného sdílení.",
"Moreover, email addresses of users might be sent to that system in order to verify them." : "Dále mohou být pro ověření odeslány na server e-mailové adresy uživatelů.",
"Disable querying" : "Vypnout dotazování",
"Enable querying" : "Zapnout dotazování",
"Disable querying" : "Vypnout dotazování",
"Unable to update federated files sharing config" : "Nedaří se aktualizovat nastavení federovaného sdílení souborů",
"Adjust how people can share between servers. This includes shares between people on this server as well if they are using federated sharing." : "Upravte, jak mohou lidé sdílet mezi servery. Týká se sdílení mezi lidmi na tomto serveru a stejně tak uživatelů federovaného sdílení.",
"Allow people on this server to send shares to other servers (this option also allows WebDAV access to public shares)" : "Umožnit lidem na tomto serveru posílat sdílení na ostatní servery (tato volba také umožňuje WebDAV přístup k veřejným sdílením)",
@@ -53,11 +53,9 @@
"You can share with anyone who uses a {productName} server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Můžete sdílet s kýmkoliv, kdo používá {productName} nebo jiný server či služby, kompatibilní se standardem Open Cloud Mesh (OCM)! Stačí do dialogu pro sdílení zadat jejich jejich identif. v rámci sdruženého cloudu. Má podobu person@cloud.example.com",
"Your Federated Cloud ID" : "Váš identifikátor v rámci fedorovaného cloudu",
"Share it so your friends can share files with you:" : "Podělte se o to, aby mohli vaši přátelé s vámi mohli sdílet soubory:",
"Facebook" : "Facebook",
"X (formerly Twitter)" : "X (dříve Twitter)",
"formerly Twitter" : "dříve Twitter",
"Mastodon" : "Mastodon",
"Bluesky" : "Bluesky",
"Facebook" : "Facebook",
"Mastodon" : "Mastodon",
"Add to your website" : "Přidat na svou webovou stránku",
"Share with me via {productName}" : "Nasdíleno mě prostřednictvím {productName}",
"HTML Code:" : "HTML kód:",
@@ -69,6 +67,8 @@
"Incoming share could not be processed" : "Příchozí sdílení se nepodařilo zpracovat",
"Cloud ID copied to the clipboard" : "Cloudový identifikátor zkopírován do schránky",
"Copy to clipboard" : "Zkopírovat do schránky",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Můžete sdílet s kýmkoliv, kdo používá Nextcloud nebo jiný server či služby, kompatibilní se standardem Open Cloud Mesh (OCM)! Stačí do dialogu pro sdílení zadat jejich jejich identif. v rámci sdruženého cloudu. Má podobu person@cloud.example.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Můžete sdílet s kýmkoliv, kdo používá Nextcloud nebo jiný server či služby, kompatibilní se standardem Open Cloud Mesh (OCM)! Stačí do dialogu pro sdílení zadat jejich jejich identif. v rámci sdruženého cloudu. Má podobu person@cloud.example.com",
"X (formerly Twitter)" : "X (dříve Twitter)",
"formerly Twitter" : "dříve Twitter"
},"pluralForm" :"nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;"
}
+8 -8
View File
@@ -25,14 +25,14 @@ OC.L10N.register(
"Provide federated file sharing across servers" : "Leverer fødereret fildeling på tværs af servere",
"Confirm data upload to lookup server" : "Bekræft dataoverførsel til opslagsserver",
"When enabled, all account properties (e.g. email address) with scope visibility set to \"published\", will be automatically synced and transmitted to an external system and made available in a public, global address book." : "Når det er aktiveret, så vil alle kontoegenskaber (f.eks. e-mailadresse) med omfangssynlighed indstillet til \"publiceret\", automatisk blive synkroniseret og transmitteret til et eksternt system og gjort tilgængelige i en offentlig, global adressebog.",
"Disable upload" : "Deaktivér upload",
"Enable data upload" : "Aktivér data upload",
"Disable upload" : "Deaktivér upload",
"Confirm querying lookup server" : "Bekræft forespørgsel til opslagsserver",
"When enabled, the search input when creating shares will be sent to an external system that provides a public and global address book." : "Når det er aktiveret, vil søgeinputtet, når der oprettes delinger, blive sendt til et eksternt system, der leverer en offentlig og global adressebog.",
"This is used to retrieve the federated cloud ID to make federated sharing easier." : "Dette bruges til at hente det fødererede cloud ID for at gøre fødereret deling nemmere.",
"Moreover, email addresses of users might be sent to that system in order to verify them." : "Desuden kan e-mailadresser på brugere blive sendt til dette system for at verificere dem.",
"Disable querying" : "Deaktivér forespørgsler",
"Enable querying" : "Aktivér forespørgsler",
"Disable querying" : "Deaktivér forespørgsler",
"Unable to update federated files sharing config" : "Kan ikke opdatere fødereret fildelingskonfiguration",
"Adjust how people can share between servers. This includes shares between people on this server as well if they are using federated sharing." : "Juster, hvordan brugere kan dele mellem servere. Dette inkluderer også delinger mellem brugere på denne server, hvis de bruger fødereret deling.",
"Allow people on this server to send shares to other servers (this option also allows WebDAV access to public shares)" : "Tillad brugere på denne server at sende shares til andre servere (denne mulighed giver også WebDAV adgang til offentlige shares)",
@@ -55,15 +55,13 @@ OC.L10N.register(
"You can share with anyone who uses a {productName} server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Du kan dele med enhver der anvender en {productName} server eller andre Open Cloud Mesh (OCM) kompatible serverer og services! Angiv blot deres fødererede Cloud ID i delings dialogen. Det ser ud som følger: person@cloud.example.com",
"Your Federated Cloud ID" : "Dit sammenkoblings Cloud ID",
"Share it so your friends can share files with you:" : "Del så dine venner kan dele filer med dig:",
"Facebook" : "Facebook",
"X (formerly Twitter)" : "X (tidligere Twitter)",
"formerly Twitter" : "tidligere Twitter",
"Mastodon" : "Mastodont",
"Bluesky" : "Bluesky",
"Facebook" : "Facebook",
"Mastodon" : "Mastodont",
"Add to your website" : "Tilføj til dit websted",
"Share with me via {productName}" : "Del med mig via {productName}",
"HTML Code:" : "HTML kode:",
"Cancel" : "Annuller",
"Cancel" : "Annullér",
"Add remote share" : "Tilføj ekstern deling",
"Remote share" : "Eksterne drev",
"Do you want to add the remote share {name} from {owner}@{remote}?" : "Ønsker du at tilføje det eksterne drev {name} fra {owner}@{remote}?",
@@ -71,6 +69,8 @@ OC.L10N.register(
"Incoming share could not be processed" : "Indgående deling kunne ikke behandles",
"Cloud ID copied to the clipboard" : "Cloud ID er kopieret til udklipsholderen.",
"Copy to clipboard" : "Kopier til udklipsholder",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Du kan dele med alle, der bruger en Nextcloud-server eller andre Open Cloud Mesh (OCM)-kompatible servere og tjenester! Indsæt blot deres Sammenkoblings Cloud ID i delingsdialogen. Det ligner person@cloud.example.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Du kan dele med alle, der bruger en Nextcloud-server eller andre Open Cloud Mesh (OCM)-kompatible servere og tjenester! Indsæt blot deres Sammenkoblings Cloud ID i delingsdialogen. Det ligner person@cloud.example.com",
"X (formerly Twitter)" : "X (tidligere Twitter)",
"formerly Twitter" : "tidligere Twitter"
},
"nplurals=2; plural=(n != 1);");
+8 -8
View File
@@ -23,14 +23,14 @@
"Provide federated file sharing across servers" : "Leverer fødereret fildeling på tværs af servere",
"Confirm data upload to lookup server" : "Bekræft dataoverførsel til opslagsserver",
"When enabled, all account properties (e.g. email address) with scope visibility set to \"published\", will be automatically synced and transmitted to an external system and made available in a public, global address book." : "Når det er aktiveret, så vil alle kontoegenskaber (f.eks. e-mailadresse) med omfangssynlighed indstillet til \"publiceret\", automatisk blive synkroniseret og transmitteret til et eksternt system og gjort tilgængelige i en offentlig, global adressebog.",
"Disable upload" : "Deaktivér upload",
"Enable data upload" : "Aktivér data upload",
"Disable upload" : "Deaktivér upload",
"Confirm querying lookup server" : "Bekræft forespørgsel til opslagsserver",
"When enabled, the search input when creating shares will be sent to an external system that provides a public and global address book." : "Når det er aktiveret, vil søgeinputtet, når der oprettes delinger, blive sendt til et eksternt system, der leverer en offentlig og global adressebog.",
"This is used to retrieve the federated cloud ID to make federated sharing easier." : "Dette bruges til at hente det fødererede cloud ID for at gøre fødereret deling nemmere.",
"Moreover, email addresses of users might be sent to that system in order to verify them." : "Desuden kan e-mailadresser på brugere blive sendt til dette system for at verificere dem.",
"Disable querying" : "Deaktivér forespørgsler",
"Enable querying" : "Aktivér forespørgsler",
"Disable querying" : "Deaktivér forespørgsler",
"Unable to update federated files sharing config" : "Kan ikke opdatere fødereret fildelingskonfiguration",
"Adjust how people can share between servers. This includes shares between people on this server as well if they are using federated sharing." : "Juster, hvordan brugere kan dele mellem servere. Dette inkluderer også delinger mellem brugere på denne server, hvis de bruger fødereret deling.",
"Allow people on this server to send shares to other servers (this option also allows WebDAV access to public shares)" : "Tillad brugere på denne server at sende shares til andre servere (denne mulighed giver også WebDAV adgang til offentlige shares)",
@@ -53,15 +53,13 @@
"You can share with anyone who uses a {productName} server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Du kan dele med enhver der anvender en {productName} server eller andre Open Cloud Mesh (OCM) kompatible serverer og services! Angiv blot deres fødererede Cloud ID i delings dialogen. Det ser ud som følger: person@cloud.example.com",
"Your Federated Cloud ID" : "Dit sammenkoblings Cloud ID",
"Share it so your friends can share files with you:" : "Del så dine venner kan dele filer med dig:",
"Facebook" : "Facebook",
"X (formerly Twitter)" : "X (tidligere Twitter)",
"formerly Twitter" : "tidligere Twitter",
"Mastodon" : "Mastodont",
"Bluesky" : "Bluesky",
"Facebook" : "Facebook",
"Mastodon" : "Mastodont",
"Add to your website" : "Tilføj til dit websted",
"Share with me via {productName}" : "Del med mig via {productName}",
"HTML Code:" : "HTML kode:",
"Cancel" : "Annuller",
"Cancel" : "Annullér",
"Add remote share" : "Tilføj ekstern deling",
"Remote share" : "Eksterne drev",
"Do you want to add the remote share {name} from {owner}@{remote}?" : "Ønsker du at tilføje det eksterne drev {name} fra {owner}@{remote}?",
@@ -69,6 +67,8 @@
"Incoming share could not be processed" : "Indgående deling kunne ikke behandles",
"Cloud ID copied to the clipboard" : "Cloud ID er kopieret til udklipsholderen.",
"Copy to clipboard" : "Kopier til udklipsholder",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Du kan dele med alle, der bruger en Nextcloud-server eller andre Open Cloud Mesh (OCM)-kompatible servere og tjenester! Indsæt blot deres Sammenkoblings Cloud ID i delingsdialogen. Det ligner person@cloud.example.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Du kan dele med alle, der bruger en Nextcloud-server eller andre Open Cloud Mesh (OCM)-kompatible servere og tjenester! Indsæt blot deres Sammenkoblings Cloud ID i delingsdialogen. Det ligner person@cloud.example.com",
"X (formerly Twitter)" : "X (tidligere Twitter)",
"formerly Twitter" : "tidligere Twitter"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}
+7 -7
View File
@@ -25,14 +25,14 @@ OC.L10N.register(
"Provide federated file sharing across servers" : "Bietet Federated Datei-Freigaben über Servergrenzen hinweg",
"Confirm data upload to lookup server" : "Hochladen der Daten zum Lookup-Server bestätigen",
"When enabled, all account properties (e.g. email address) with scope visibility set to \"published\", will be automatically synced and transmitted to an external system and made available in a public, global address book." : "Wenn diese Option aktiviert ist, werden alle Kontoeigenschaften (z. B. E-Mail-Adresse) mit der auf \"veröffentlicht\" eingestellten Bereichssichtbarkeit automatisch synchronisiert und an ein externes System übertragen sowie in einem öffentlichen, globalen Adressbuch verfügbar gemacht.",
"Disable upload" : "Hochladen deaktivieren",
"Enable data upload" : "Hochladen von Daten aktivieren",
"Disable upload" : "Hochladen deaktivieren",
"Confirm querying lookup server" : "Abfrage des Lookup-Servers bestätigen",
"When enabled, the search input when creating shares will be sent to an external system that provides a public and global address book." : "Wenn aktiviert, wird die Sucheingabe beim Erstellen von Freigaben an ein externes System gesendet, das ein öffentliches und globales Adressbuch bereitstellt.",
"This is used to retrieve the federated cloud ID to make federated sharing easier." : "Dies wird verwendet, um die federierte Cloud-ID abzurufen und so die federierte Freigabe zu vereinfachen.",
"Moreover, email addresses of users might be sent to that system in order to verify them." : "Darüber hinaus können E-Mail-Adressen von Benutzern an dieses System gesendet werden, um sie zu überprüfen.",
"Disable querying" : "Abfragen deaktivieren",
"Enable querying" : "Abfragen aktivieren",
"Disable querying" : "Abfragen deaktivieren",
"Unable to update federated files sharing config" : "Einstellungen zum federierten Teilen konnten nicht aktualisiert werden",
"Adjust how people can share between servers. This includes shares between people on this server as well if they are using federated sharing." : "Legt fest, wie Personen zwischen Servern teilen können. Dies gilt auch für Freigaben zwischen Personen auf diesem Server, wenn sie Federated-Sharing verwenden.",
"Allow people on this server to send shares to other servers (this option also allows WebDAV access to public shares)" : "Personen auf diesem Server das Senden von Freigaben an andere Server erlauben (Diese Option ermöglicht auch den WebDAV-Zugriff auf öffentliche Freigaben)",
@@ -55,11 +55,9 @@ OC.L10N.register(
"You can share with anyone who uses a {productName} server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Du kannst mit jedem teilen, der einen {productName}-Server oder andere Open Cloud Mesh (OCM) kompatible Server und Dienste verwendet! Gebe einfach deren Federated-Cloud-ID in den Teilen-Dialog ein. Diese sieht wie folgt aus: person@cloud.example.com",
"Your Federated Cloud ID" : "Deine Federated-Cloud-ID",
"Share it so your friends can share files with you:" : "Teile es, damit deine Freunde Dateien mit dir teilen können:",
"Facebook" : "Facebook",
"X (formerly Twitter)" : "X (früher Twitter)",
"formerly Twitter" : "früher Twitter",
"Mastodon" : "Mastodon",
"Bluesky" : "Bluesky",
"Facebook" : "Facebook",
"Mastodon" : "Mastodon",
"Add to your website" : "Zu deiner Webseite hinzufügen",
"Share with me via {productName}" : "Mit mir über {productName} teilen",
"HTML Code:" : "HTML-Code:",
@@ -71,6 +69,8 @@ OC.L10N.register(
"Incoming share could not be processed" : "Eingehende Freigabe konnte nicht verarbeitet werden",
"Cloud ID copied to the clipboard" : "Cloud-ID in die Zwischenablage kopiert",
"Copy to clipboard" : "In die Zwischenablage kopieren",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Du kannst mit jedem teilen, der einen Nextcloud-Server oder andere Open Cloud Mesh (OCM) kompatible Server und Dienste verwendet! Gib einfach deren Federated-Cloud-ID in den Teilen-Dialog ein. Diese sieht wie folgt aus: person@cloud.example.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Du kannst mit jedem teilen, der einen Nextcloud-Server oder andere Open Cloud Mesh (OCM) kompatible Server und Dienste verwendet! Gib einfach deren Federated-Cloud-ID in den Teilen-Dialog ein. Diese sieht wie folgt aus: person@cloud.example.com",
"X (formerly Twitter)" : "X (früher Twitter)",
"formerly Twitter" : "früher Twitter"
},
"nplurals=2; plural=(n != 1);");
+7 -7
View File
@@ -23,14 +23,14 @@
"Provide federated file sharing across servers" : "Bietet Federated Datei-Freigaben über Servergrenzen hinweg",
"Confirm data upload to lookup server" : "Hochladen der Daten zum Lookup-Server bestätigen",
"When enabled, all account properties (e.g. email address) with scope visibility set to \"published\", will be automatically synced and transmitted to an external system and made available in a public, global address book." : "Wenn diese Option aktiviert ist, werden alle Kontoeigenschaften (z. B. E-Mail-Adresse) mit der auf \"veröffentlicht\" eingestellten Bereichssichtbarkeit automatisch synchronisiert und an ein externes System übertragen sowie in einem öffentlichen, globalen Adressbuch verfügbar gemacht.",
"Disable upload" : "Hochladen deaktivieren",
"Enable data upload" : "Hochladen von Daten aktivieren",
"Disable upload" : "Hochladen deaktivieren",
"Confirm querying lookup server" : "Abfrage des Lookup-Servers bestätigen",
"When enabled, the search input when creating shares will be sent to an external system that provides a public and global address book." : "Wenn aktiviert, wird die Sucheingabe beim Erstellen von Freigaben an ein externes System gesendet, das ein öffentliches und globales Adressbuch bereitstellt.",
"This is used to retrieve the federated cloud ID to make federated sharing easier." : "Dies wird verwendet, um die federierte Cloud-ID abzurufen und so die federierte Freigabe zu vereinfachen.",
"Moreover, email addresses of users might be sent to that system in order to verify them." : "Darüber hinaus können E-Mail-Adressen von Benutzern an dieses System gesendet werden, um sie zu überprüfen.",
"Disable querying" : "Abfragen deaktivieren",
"Enable querying" : "Abfragen aktivieren",
"Disable querying" : "Abfragen deaktivieren",
"Unable to update federated files sharing config" : "Einstellungen zum federierten Teilen konnten nicht aktualisiert werden",
"Adjust how people can share between servers. This includes shares between people on this server as well if they are using federated sharing." : "Legt fest, wie Personen zwischen Servern teilen können. Dies gilt auch für Freigaben zwischen Personen auf diesem Server, wenn sie Federated-Sharing verwenden.",
"Allow people on this server to send shares to other servers (this option also allows WebDAV access to public shares)" : "Personen auf diesem Server das Senden von Freigaben an andere Server erlauben (Diese Option ermöglicht auch den WebDAV-Zugriff auf öffentliche Freigaben)",
@@ -53,11 +53,9 @@
"You can share with anyone who uses a {productName} server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Du kannst mit jedem teilen, der einen {productName}-Server oder andere Open Cloud Mesh (OCM) kompatible Server und Dienste verwendet! Gebe einfach deren Federated-Cloud-ID in den Teilen-Dialog ein. Diese sieht wie folgt aus: person@cloud.example.com",
"Your Federated Cloud ID" : "Deine Federated-Cloud-ID",
"Share it so your friends can share files with you:" : "Teile es, damit deine Freunde Dateien mit dir teilen können:",
"Facebook" : "Facebook",
"X (formerly Twitter)" : "X (früher Twitter)",
"formerly Twitter" : "früher Twitter",
"Mastodon" : "Mastodon",
"Bluesky" : "Bluesky",
"Facebook" : "Facebook",
"Mastodon" : "Mastodon",
"Add to your website" : "Zu deiner Webseite hinzufügen",
"Share with me via {productName}" : "Mit mir über {productName} teilen",
"HTML Code:" : "HTML-Code:",
@@ -69,6 +67,8 @@
"Incoming share could not be processed" : "Eingehende Freigabe konnte nicht verarbeitet werden",
"Cloud ID copied to the clipboard" : "Cloud-ID in die Zwischenablage kopiert",
"Copy to clipboard" : "In die Zwischenablage kopieren",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Du kannst mit jedem teilen, der einen Nextcloud-Server oder andere Open Cloud Mesh (OCM) kompatible Server und Dienste verwendet! Gib einfach deren Federated-Cloud-ID in den Teilen-Dialog ein. Diese sieht wie folgt aus: person@cloud.example.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Du kannst mit jedem teilen, der einen Nextcloud-Server oder andere Open Cloud Mesh (OCM) kompatible Server und Dienste verwendet! Gib einfach deren Federated-Cloud-ID in den Teilen-Dialog ein. Diese sieht wie folgt aus: person@cloud.example.com",
"X (formerly Twitter)" : "X (früher Twitter)",
"formerly Twitter" : "früher Twitter"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}
+7 -7
View File
@@ -25,14 +25,14 @@ OC.L10N.register(
"Provide federated file sharing across servers" : "Bietet Cloud-übergreifende Datei-Freigaben",
"Confirm data upload to lookup server" : "Datenupload zum Lookup-Server bestätigen",
"When enabled, all account properties (e.g. email address) with scope visibility set to \"published\", will be automatically synced and transmitted to an external system and made available in a public, global address book." : "Wenn diese Option aktiviert ist, werden alle Kontoeigenschaften (z. B. E-Mail-Adresse) mit der auf \"veröffentlicht\" eingestellten Bereichssichtbarkeit automatisch synchronisiert und an ein externes System übertragen sowie in einem öffentlichen, globalen Adressbuch verfügbar gemacht.",
"Disable upload" : "Hochladen deaktivieren",
"Enable data upload" : "Datenhochladen aktivieren",
"Disable upload" : "Hochladen deaktivieren",
"Confirm querying lookup server" : "Abfrage des Lookup-Servers bestätigen",
"When enabled, the search input when creating shares will be sent to an external system that provides a public and global address book." : "Wenn aktiviert, wird die Sucheingabe beim Erstellen von Freigaben an ein externes System gesendet, das ein öffentliches und globales Adressbuch bereitstellt.",
"This is used to retrieve the federated cloud ID to make federated sharing easier." : "Dies wird verwendet, um die Federated-Cloud-ID abzurufen und so die federierte Freigabe zu vereinfachen.",
"Moreover, email addresses of users might be sent to that system in order to verify them." : "Darüber hinaus können E-Mail-Adressen von Benutzern an dieses System gesendet werden, um sie zu überprüfen.",
"Disable querying" : "Abfragen deaktivieren",
"Enable querying" : "Abfragen aktivieren",
"Disable querying" : "Abfragen deaktivieren",
"Unable to update federated files sharing config" : "Einstellungen zum Federated-Teilen konnten nicht aktualisiert werden",
"Adjust how people can share between servers. This includes shares between people on this server as well if they are using federated sharing." : "Legt fest, wie Personen zwischen Servern teilen können. Dies gilt auch für Freigaben zwischen Personen auf diesem Server, wenn sie Federated-Sharing verwenden.",
"Allow people on this server to send shares to other servers (this option also allows WebDAV access to public shares)" : "Personen auf diesem Server das Senden von Freigaben an andere Server erlauben (Diese Option ermöglicht auch den WebDAV-Zugriff auf öffentliche Freigaben)",
@@ -55,11 +55,9 @@ OC.L10N.register(
"You can share with anyone who uses a {productName} server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Sie können mit jedem teilen, der einen {productName}-Server oder andere Open Cloud Mesh (OCM) kompatible Server und Dienste verwendet! Geben Sie einfach deren Federated-Cloud-ID in den Teilen-Dialog ein. Diese sieht wie folgt aus: person@cloud.example.com",
"Your Federated Cloud ID" : "Ihre Federated-Cloud-ID",
"Share it so your friends can share files with you:" : "Teilen Sie es, damit Ihre Freunde Dateien mit Ihnen teilen können:",
"Facebook" : "Facebook",
"X (formerly Twitter)" : "X (früher Twitter)",
"formerly Twitter" : "früher Twitter",
"Mastodon" : "Mastodon",
"Bluesky" : "Bluesky",
"Facebook" : "Facebook",
"Mastodon" : "Mastodon",
"Add to your website" : "Zu Ihrer Webseite hinzufügen",
"Share with me via {productName}" : "Mit mir über {productName} teilen",
"HTML Code:" : "HTML-Code:",
@@ -71,6 +69,8 @@ OC.L10N.register(
"Incoming share could not be processed" : "Eingehende Freigabe konnte nicht verarbeitet werden",
"Cloud ID copied to the clipboard" : "Cloud-ID wurde in die Zwischenablage kopiert",
"Copy to clipboard" : "In die Zwischenablage kopieren",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Sie können mit jedem teilen, der einen Nextcloud-Server oder andere Open Cloud Mesh (OCM) kompatible Server und Dienste verwendet! Geben Sie einfach deren Federated-Cloud-ID in den Teilen-Dialog ein. Diese sieht wie folgt aus: person@cloud.example.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Sie können mit jedem teilen, der einen Nextcloud-Server oder andere Open Cloud Mesh (OCM) kompatible Server und Dienste verwendet! Geben Sie einfach deren Federated-Cloud-ID in den Teilen-Dialog ein. Diese sieht wie folgt aus: person@cloud.example.com",
"X (formerly Twitter)" : "X (früher Twitter)",
"formerly Twitter" : "früher Twitter"
},
"nplurals=2; plural=(n != 1);");
+7 -7
View File
@@ -23,14 +23,14 @@
"Provide federated file sharing across servers" : "Bietet Cloud-übergreifende Datei-Freigaben",
"Confirm data upload to lookup server" : "Datenupload zum Lookup-Server bestätigen",
"When enabled, all account properties (e.g. email address) with scope visibility set to \"published\", will be automatically synced and transmitted to an external system and made available in a public, global address book." : "Wenn diese Option aktiviert ist, werden alle Kontoeigenschaften (z. B. E-Mail-Adresse) mit der auf \"veröffentlicht\" eingestellten Bereichssichtbarkeit automatisch synchronisiert und an ein externes System übertragen sowie in einem öffentlichen, globalen Adressbuch verfügbar gemacht.",
"Disable upload" : "Hochladen deaktivieren",
"Enable data upload" : "Datenhochladen aktivieren",
"Disable upload" : "Hochladen deaktivieren",
"Confirm querying lookup server" : "Abfrage des Lookup-Servers bestätigen",
"When enabled, the search input when creating shares will be sent to an external system that provides a public and global address book." : "Wenn aktiviert, wird die Sucheingabe beim Erstellen von Freigaben an ein externes System gesendet, das ein öffentliches und globales Adressbuch bereitstellt.",
"This is used to retrieve the federated cloud ID to make federated sharing easier." : "Dies wird verwendet, um die Federated-Cloud-ID abzurufen und so die federierte Freigabe zu vereinfachen.",
"Moreover, email addresses of users might be sent to that system in order to verify them." : "Darüber hinaus können E-Mail-Adressen von Benutzern an dieses System gesendet werden, um sie zu überprüfen.",
"Disable querying" : "Abfragen deaktivieren",
"Enable querying" : "Abfragen aktivieren",
"Disable querying" : "Abfragen deaktivieren",
"Unable to update federated files sharing config" : "Einstellungen zum Federated-Teilen konnten nicht aktualisiert werden",
"Adjust how people can share between servers. This includes shares between people on this server as well if they are using federated sharing." : "Legt fest, wie Personen zwischen Servern teilen können. Dies gilt auch für Freigaben zwischen Personen auf diesem Server, wenn sie Federated-Sharing verwenden.",
"Allow people on this server to send shares to other servers (this option also allows WebDAV access to public shares)" : "Personen auf diesem Server das Senden von Freigaben an andere Server erlauben (Diese Option ermöglicht auch den WebDAV-Zugriff auf öffentliche Freigaben)",
@@ -53,11 +53,9 @@
"You can share with anyone who uses a {productName} server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Sie können mit jedem teilen, der einen {productName}-Server oder andere Open Cloud Mesh (OCM) kompatible Server und Dienste verwendet! Geben Sie einfach deren Federated-Cloud-ID in den Teilen-Dialog ein. Diese sieht wie folgt aus: person@cloud.example.com",
"Your Federated Cloud ID" : "Ihre Federated-Cloud-ID",
"Share it so your friends can share files with you:" : "Teilen Sie es, damit Ihre Freunde Dateien mit Ihnen teilen können:",
"Facebook" : "Facebook",
"X (formerly Twitter)" : "X (früher Twitter)",
"formerly Twitter" : "früher Twitter",
"Mastodon" : "Mastodon",
"Bluesky" : "Bluesky",
"Facebook" : "Facebook",
"Mastodon" : "Mastodon",
"Add to your website" : "Zu Ihrer Webseite hinzufügen",
"Share with me via {productName}" : "Mit mir über {productName} teilen",
"HTML Code:" : "HTML-Code:",
@@ -69,6 +67,8 @@
"Incoming share could not be processed" : "Eingehende Freigabe konnte nicht verarbeitet werden",
"Cloud ID copied to the clipboard" : "Cloud-ID wurde in die Zwischenablage kopiert",
"Copy to clipboard" : "In die Zwischenablage kopieren",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Sie können mit jedem teilen, der einen Nextcloud-Server oder andere Open Cloud Mesh (OCM) kompatible Server und Dienste verwendet! Geben Sie einfach deren Federated-Cloud-ID in den Teilen-Dialog ein. Diese sieht wie folgt aus: person@cloud.example.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Sie können mit jedem teilen, der einen Nextcloud-Server oder andere Open Cloud Mesh (OCM) kompatible Server und Dienste verwendet! Geben Sie einfach deren Federated-Cloud-ID in den Teilen-Dialog ein. Diese sieht wie folgt aus: person@cloud.example.com",
"X (formerly Twitter)" : "X (früher Twitter)",
"formerly Twitter" : "früher Twitter"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}
+7 -7
View File
@@ -25,14 +25,14 @@ OC.L10N.register(
"Provide federated file sharing across servers" : "Παρέχει κοινής χρήσης αρχεία μεταξύ διακομιστών",
"Confirm data upload to lookup server" : "Επιβεβαίωση μεταφόρτωσης δεδομένων στον διακομιστή αναζήτησης",
"When enabled, all account properties (e.g. email address) with scope visibility set to \"published\", will be automatically synced and transmitted to an external system and made available in a public, global address book." : "Όταν είναι ενεργοποιημένο, όλες οι ιδιότητες λογαριασμού (π.χ. διεύθυνση ηλεκτρονικού ταχυδρομείου) με ορατότητα ορισμένη ως «δημοσιευμένη», θα συγχρονίζονται και μεταφέρονται αυτόματα σε ένα εξωτερικό σύστημα, όπου θα είναι διαθέσιμες σε έναν δημόσιο, παγκόσμιο κατάλογο διευθύνσεων.",
"Disable upload" : "Απενεργοποίηση μεταφόρτωσης",
"Enable data upload" : "Ενεργοποίηση μεταφόρτωσης δεδομένων",
"Disable upload" : "Απενεργοποίηση μεταφόρτωσης",
"Confirm querying lookup server" : "Επιβεβαίωση ερώτησης στον διακομιστή αναζήτησης",
"When enabled, the search input when creating shares will be sent to an external system that provides a public and global address book." : "Όταν είναι ενεργοποιημένο, η είσοδος αναζήτησης κατά τη δημιουργία κοινών χρήσεων θα αποστέλλεται σε ένα εξωτερικό σύστημα που παρέχει έναν δημόσιο και παγκόσμιο κατάλογο διευθύνσεων.",
"This is used to retrieve the federated cloud ID to make federated sharing easier." : "Αυτό χρησιμοποιείται για την ανάκτηση του συνενωμένου αναγνωριστικού νέφους για να διευκολύνεται η συνενωμένη κοινή χρήση.",
"Moreover, email addresses of users might be sent to that system in order to verify them." : "Επιπλέον, οι διευθύνσεις ηλεκτρονικού ταχυδρομείου των χρηστών ενδέχεται να αποστέλλονται σε αυτό το σύστημα για επαλήθευση.",
"Disable querying" : "Απενεργοποίηση ερώτησης",
"Enable querying" : "Ενεργοποίηση ερώτησης",
"Disable querying" : "Απενεργοποίηση ερώτησης",
"Unable to update federated files sharing config" : "Αδυναμία ενημέρωσης ρυθμίσεων συνενωμένης κοινής χρήσης αρχείων",
"Adjust how people can share between servers. This includes shares between people on this server as well if they are using federated sharing." : "Ρυθμίστε τον τρόπο με τον οποίο οι χρήστες μπορούν να μοιράζονται μεταξύ διακομιστών. Αυτό περιλαμβάνει και κοινές χρήσεις μεταξύ χρηστών σε αυτόν τον διακομιστή, εφόσον χρησιμοποιούν συνενωμένη κοινή χρήση.",
"Allow people on this server to send shares to other servers (this option also allows WebDAV access to public shares)" : "Επιτρέψτε στους χρήστες αυτού του διακομιστή να αποστέλλουν κοινές χρήσεις σε άλλους διακομιστές (αυτή η επιλογή επιτρέπει επίσης πρόσβαση μέσω WebDAV σε δημόσιες κοινές χρήσεις)",
@@ -55,11 +55,9 @@ OC.L10N.register(
"You can share with anyone who uses a {productName} server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Μπορείτε να μοιραστείτε με οποιονδήποτε χρησιμοποιεί έναν διακομιστή {productName} ή άλλους συμβατούς διακομιστές και υπηρεσίες Open Cloud Mesh (OCM)! Απλά εισάγετε το αναγνωριστικό του ομοσπονδοποιημένου υπολογιστικού νέφους τους στο παράθυρο κοινής χρήσης. Μοιάζει με person@cloud.example.com",
"Your Federated Cloud ID" : "Το αναγνωριστικό του ομοσπονδοποιημένου υπολογιστικού νέφους σας",
"Share it so your friends can share files with you:" : "Διαμοιραστείτε το ώστε οι φίλοι σας να μπορούν να διαμοιράζονται αρχεία με εσάς:",
"Facebook" : "Facebook",
"X (formerly Twitter)" : "X (πρώην Twitter)",
"formerly Twitter" : "πρώην Twitter",
"Mastodon" : "Mastodon",
"Bluesky" : "Bluesky",
"Facebook" : "Facebook",
"Mastodon" : "Mastodon",
"Add to your website" : "Προσθήκη στην ιστοσελίδα σας",
"Share with me via {productName}" : "Μοιραστείτε μαζί μου μέσω {productName}",
"HTML Code:" : "Κώδικας HTML:",
@@ -71,6 +69,8 @@ OC.L10N.register(
"Incoming share could not be processed" : "Η εισερχόμενη κοινή χρήση δεν μπορούσε να επεξεργαστεί",
"Cloud ID copied to the clipboard" : "Το αναγνωριστικό νέφους αντιγράφηκε στο πρόχειρο",
"Copy to clipboard" : "Αντιγραφή στο πρόχειρο",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Μπορείτε να διαμοιράζεστε με οποιονδήποτε χρησιμοποιεί Nextcloud ή άλλο συμβατό διακομιστή και υπηρεσιών Open Cloud Mesh (OCM)! Απλά προσθέστε το Federated Cloud ID στο πλαίσιο διαλόγου διαμοιρασμού. Θα μοιάζει με person@cloud.example.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Μπορείτε να διαμοιράζεστε με οποιονδήποτε χρησιμοποιεί Nextcloud ή άλλο συμβατό διακομιστή και υπηρεσιών Open Cloud Mesh (OCM)! Απλά προσθέστε το Federated Cloud ID στο πλαίσιο διαλόγου διαμοιρασμού. Θα μοιάζει με person@cloud.example.com",
"X (formerly Twitter)" : "X (πρώην Twitter)",
"formerly Twitter" : "πρώην Twitter"
},
"nplurals=2; plural=(n != 1);");
+7 -7
View File
@@ -23,14 +23,14 @@
"Provide federated file sharing across servers" : "Παρέχει κοινής χρήσης αρχεία μεταξύ διακομιστών",
"Confirm data upload to lookup server" : "Επιβεβαίωση μεταφόρτωσης δεδομένων στον διακομιστή αναζήτησης",
"When enabled, all account properties (e.g. email address) with scope visibility set to \"published\", will be automatically synced and transmitted to an external system and made available in a public, global address book." : "Όταν είναι ενεργοποιημένο, όλες οι ιδιότητες λογαριασμού (π.χ. διεύθυνση ηλεκτρονικού ταχυδρομείου) με ορατότητα ορισμένη ως «δημοσιευμένη», θα συγχρονίζονται και μεταφέρονται αυτόματα σε ένα εξωτερικό σύστημα, όπου θα είναι διαθέσιμες σε έναν δημόσιο, παγκόσμιο κατάλογο διευθύνσεων.",
"Disable upload" : "Απενεργοποίηση μεταφόρτωσης",
"Enable data upload" : "Ενεργοποίηση μεταφόρτωσης δεδομένων",
"Disable upload" : "Απενεργοποίηση μεταφόρτωσης",
"Confirm querying lookup server" : "Επιβεβαίωση ερώτησης στον διακομιστή αναζήτησης",
"When enabled, the search input when creating shares will be sent to an external system that provides a public and global address book." : "Όταν είναι ενεργοποιημένο, η είσοδος αναζήτησης κατά τη δημιουργία κοινών χρήσεων θα αποστέλλεται σε ένα εξωτερικό σύστημα που παρέχει έναν δημόσιο και παγκόσμιο κατάλογο διευθύνσεων.",
"This is used to retrieve the federated cloud ID to make federated sharing easier." : "Αυτό χρησιμοποιείται για την ανάκτηση του συνενωμένου αναγνωριστικού νέφους για να διευκολύνεται η συνενωμένη κοινή χρήση.",
"Moreover, email addresses of users might be sent to that system in order to verify them." : "Επιπλέον, οι διευθύνσεις ηλεκτρονικού ταχυδρομείου των χρηστών ενδέχεται να αποστέλλονται σε αυτό το σύστημα για επαλήθευση.",
"Disable querying" : "Απενεργοποίηση ερώτησης",
"Enable querying" : "Ενεργοποίηση ερώτησης",
"Disable querying" : "Απενεργοποίηση ερώτησης",
"Unable to update federated files sharing config" : "Αδυναμία ενημέρωσης ρυθμίσεων συνενωμένης κοινής χρήσης αρχείων",
"Adjust how people can share between servers. This includes shares between people on this server as well if they are using federated sharing." : "Ρυθμίστε τον τρόπο με τον οποίο οι χρήστες μπορούν να μοιράζονται μεταξύ διακομιστών. Αυτό περιλαμβάνει και κοινές χρήσεις μεταξύ χρηστών σε αυτόν τον διακομιστή, εφόσον χρησιμοποιούν συνενωμένη κοινή χρήση.",
"Allow people on this server to send shares to other servers (this option also allows WebDAV access to public shares)" : "Επιτρέψτε στους χρήστες αυτού του διακομιστή να αποστέλλουν κοινές χρήσεις σε άλλους διακομιστές (αυτή η επιλογή επιτρέπει επίσης πρόσβαση μέσω WebDAV σε δημόσιες κοινές χρήσεις)",
@@ -53,11 +53,9 @@
"You can share with anyone who uses a {productName} server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Μπορείτε να μοιραστείτε με οποιονδήποτε χρησιμοποιεί έναν διακομιστή {productName} ή άλλους συμβατούς διακομιστές και υπηρεσίες Open Cloud Mesh (OCM)! Απλά εισάγετε το αναγνωριστικό του ομοσπονδοποιημένου υπολογιστικού νέφους τους στο παράθυρο κοινής χρήσης. Μοιάζει με person@cloud.example.com",
"Your Federated Cloud ID" : "Το αναγνωριστικό του ομοσπονδοποιημένου υπολογιστικού νέφους σας",
"Share it so your friends can share files with you:" : "Διαμοιραστείτε το ώστε οι φίλοι σας να μπορούν να διαμοιράζονται αρχεία με εσάς:",
"Facebook" : "Facebook",
"X (formerly Twitter)" : "X (πρώην Twitter)",
"formerly Twitter" : "πρώην Twitter",
"Mastodon" : "Mastodon",
"Bluesky" : "Bluesky",
"Facebook" : "Facebook",
"Mastodon" : "Mastodon",
"Add to your website" : "Προσθήκη στην ιστοσελίδα σας",
"Share with me via {productName}" : "Μοιραστείτε μαζί μου μέσω {productName}",
"HTML Code:" : "Κώδικας HTML:",
@@ -69,6 +67,8 @@
"Incoming share could not be processed" : "Η εισερχόμενη κοινή χρήση δεν μπορούσε να επεξεργαστεί",
"Cloud ID copied to the clipboard" : "Το αναγνωριστικό νέφους αντιγράφηκε στο πρόχειρο",
"Copy to clipboard" : "Αντιγραφή στο πρόχειρο",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Μπορείτε να διαμοιράζεστε με οποιονδήποτε χρησιμοποιεί Nextcloud ή άλλο συμβατό διακομιστή και υπηρεσιών Open Cloud Mesh (OCM)! Απλά προσθέστε το Federated Cloud ID στο πλαίσιο διαλόγου διαμοιρασμού. Θα μοιάζει με person@cloud.example.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Μπορείτε να διαμοιράζεστε με οποιονδήποτε χρησιμοποιεί Nextcloud ή άλλο συμβατό διακομιστή και υπηρεσιών Open Cloud Mesh (OCM)! Απλά προσθέστε το Federated Cloud ID στο πλαίσιο διαλόγου διαμοιρασμού. Θα μοιάζει με person@cloud.example.com",
"X (formerly Twitter)" : "X (πρώην Twitter)",
"formerly Twitter" : "πρώην Twitter"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}
+7 -7
View File
@@ -25,14 +25,14 @@ OC.L10N.register(
"Provide federated file sharing across servers" : "Provide federated file sharing across servers",
"Confirm data upload to lookup server" : "Confirm data upload to lookup server",
"When enabled, all account properties (e.g. email address) with scope visibility set to \"published\", will be automatically synced and transmitted to an external system and made available in a public, global address book." : "When enabled, all account properties (e.g. email address) with scope visibility set to \"published\", will be automatically synced and transmitted to an external system and made available in a public, global address book.",
"Disable upload" : "Disable upload",
"Enable data upload" : "Enable data upload",
"Disable upload" : "Disable upload",
"Confirm querying lookup server" : "Confirm querying lookup server",
"When enabled, the search input when creating shares will be sent to an external system that provides a public and global address book." : "When enabled, the search input when creating shares will be sent to an external system that provides a public and global address book.",
"This is used to retrieve the federated cloud ID to make federated sharing easier." : "This is used to retrieve the federated cloud ID to make federated sharing easier.",
"Moreover, email addresses of users might be sent to that system in order to verify them." : "Moreover, email addresses of users might be sent to that system in order to verify them.",
"Disable querying" : "Disable querying",
"Enable querying" : "Enable querying",
"Disable querying" : "Disable querying",
"Unable to update federated files sharing config" : "Unable to update federated files sharing config",
"Adjust how people can share between servers. This includes shares between people on this server as well if they are using federated sharing." : "Adjust how people can share between servers. This includes shares between people on this server as well if they are using federated sharing.",
"Allow people on this server to send shares to other servers (this option also allows WebDAV access to public shares)" : "Allow people on this server to send shares to other servers (this option also allows WebDAV access to public shares)",
@@ -55,11 +55,9 @@ OC.L10N.register(
"You can share with anyone who uses a {productName} server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "You can share with anyone who uses a {productName} server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com",
"Your Federated Cloud ID" : "Your Federated Cloud ID",
"Share it so your friends can share files with you:" : "Share it so your friends can share files with you:",
"Facebook" : "Facebook",
"X (formerly Twitter)" : "X (formerly Twitter)",
"formerly Twitter" : "formerly Twitter",
"Mastodon" : "Mastodon",
"Bluesky" : "Bluesky",
"Facebook" : "Facebook",
"Mastodon" : "Mastodon",
"Add to your website" : "Add to your website",
"Share with me via {productName}" : "Share with me via {productName}",
"HTML Code:" : "HTML Code:",
@@ -71,6 +69,8 @@ OC.L10N.register(
"Incoming share could not be processed" : "Incoming share could not be processed",
"Cloud ID copied to the clipboard" : "Cloud ID copied to the clipboard",
"Copy to clipboard" : "Copy to clipboard",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialogue. It looks like person@cloud.example.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialogue. It looks like person@cloud.example.com",
"X (formerly Twitter)" : "X (formerly Twitter)",
"formerly Twitter" : "formerly Twitter"
},
"nplurals=2; plural=(n != 1);");
+7 -7
View File
@@ -23,14 +23,14 @@
"Provide federated file sharing across servers" : "Provide federated file sharing across servers",
"Confirm data upload to lookup server" : "Confirm data upload to lookup server",
"When enabled, all account properties (e.g. email address) with scope visibility set to \"published\", will be automatically synced and transmitted to an external system and made available in a public, global address book." : "When enabled, all account properties (e.g. email address) with scope visibility set to \"published\", will be automatically synced and transmitted to an external system and made available in a public, global address book.",
"Disable upload" : "Disable upload",
"Enable data upload" : "Enable data upload",
"Disable upload" : "Disable upload",
"Confirm querying lookup server" : "Confirm querying lookup server",
"When enabled, the search input when creating shares will be sent to an external system that provides a public and global address book." : "When enabled, the search input when creating shares will be sent to an external system that provides a public and global address book.",
"This is used to retrieve the federated cloud ID to make federated sharing easier." : "This is used to retrieve the federated cloud ID to make federated sharing easier.",
"Moreover, email addresses of users might be sent to that system in order to verify them." : "Moreover, email addresses of users might be sent to that system in order to verify them.",
"Disable querying" : "Disable querying",
"Enable querying" : "Enable querying",
"Disable querying" : "Disable querying",
"Unable to update federated files sharing config" : "Unable to update federated files sharing config",
"Adjust how people can share between servers. This includes shares between people on this server as well if they are using federated sharing." : "Adjust how people can share between servers. This includes shares between people on this server as well if they are using federated sharing.",
"Allow people on this server to send shares to other servers (this option also allows WebDAV access to public shares)" : "Allow people on this server to send shares to other servers (this option also allows WebDAV access to public shares)",
@@ -53,11 +53,9 @@
"You can share with anyone who uses a {productName} server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "You can share with anyone who uses a {productName} server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com",
"Your Federated Cloud ID" : "Your Federated Cloud ID",
"Share it so your friends can share files with you:" : "Share it so your friends can share files with you:",
"Facebook" : "Facebook",
"X (formerly Twitter)" : "X (formerly Twitter)",
"formerly Twitter" : "formerly Twitter",
"Mastodon" : "Mastodon",
"Bluesky" : "Bluesky",
"Facebook" : "Facebook",
"Mastodon" : "Mastodon",
"Add to your website" : "Add to your website",
"Share with me via {productName}" : "Share with me via {productName}",
"HTML Code:" : "HTML Code:",
@@ -69,6 +67,8 @@
"Incoming share could not be processed" : "Incoming share could not be processed",
"Cloud ID copied to the clipboard" : "Cloud ID copied to the clipboard",
"Copy to clipboard" : "Copy to clipboard",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialogue. It looks like person@cloud.example.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialogue. It looks like person@cloud.example.com",
"X (formerly Twitter)" : "X (formerly Twitter)",
"formerly Twitter" : "formerly Twitter"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}
+7 -7
View File
@@ -25,14 +25,14 @@ OC.L10N.register(
"Provide federated file sharing across servers" : "Provee compartición federada de archivos entre servidores",
"Confirm data upload to lookup server" : "Confirmar la carga de datos para el servidor de búsqueda",
"When enabled, all account properties (e.g. email address) with scope visibility set to \"published\", will be automatically synced and transmitted to an external system and made available in a public, global address book." : "Cuando está habilitado, todas las propiedades de las cuentas (p.ej. direcciones de correo electrónico) que se posean el ámbito de visibilidad establecido a \"publicada\" serán automáticamente sincronizadas y transmitidas a un sistema externo y se harán disponible en una libreta de direcciones pública global.",
"Disable upload" : "Deshabilitar subidas",
"Enable data upload" : "Habilitar la subida de datos",
"Disable upload" : "Deshabilitar subidas",
"Confirm querying lookup server" : "Confirmar la consulta al servidor de búsqueda",
"When enabled, the search input when creating shares will be sent to an external system that provides a public and global address book." : "Cuando está habilitado, cualquier entrada en la búsqueda cuando se crean recursos compartidos será enviada a un sistema externo que provee una libreta de direcciones pública global.",
"This is used to retrieve the federated cloud ID to make federated sharing easier." : "Esto se utiliza para obtener el ID de nube federada para hacer más sencilla la compartición federada. ",
"Moreover, email addresses of users might be sent to that system in order to verify them." : "Además, las direcciones de correo electrónico de los usuarios podrían ser enviadas a este sistema de manera de verificarlas.",
"Disable querying" : "Deshabilitar consultas",
"Enable querying" : "Habilitar consultas",
"Disable querying" : "Deshabilitar consultas",
"Unable to update federated files sharing config" : "No fue posible actualizar la configuración de los recursos compartidos federados de archivos",
"Adjust how people can share between servers. This includes shares between people on this server as well if they are using federated sharing." : "Ajustar la forma en que los usuarios pueden compartir entre servidores. Esto incluye a los recursos compartidos entre usuarios en este servidor tanto como a aquellos que usan compartición federada",
"Allow people on this server to send shares to other servers (this option also allows WebDAV access to public shares)" : "Permitir a los usuarios en este servidor enviar recursos compartidos a otros servidores (esta opción también permite el acceso público vía WebDAV a los recursos compartidos públicos)",
@@ -55,11 +55,9 @@ OC.L10N.register(
"You can share with anyone who uses a {productName} server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "¡Puede compartir con cualquier persona que use un servidor {productName} u otros servicios compatibles con Open Cloud Mesh (OCM)!. Solo coloque el ID de Nube Federada de esta(s) persona(s) en el diálogo de compartir. Se verán así: persona@nube.ejemplo.com",
"Your Federated Cloud ID" : "Su ID de Nube Federada",
"Share it so your friends can share files with you:" : "Compártalo para que sus amigos puedan compartir archivos con Ud.:",
"Facebook" : "Facebook",
"X (formerly Twitter)" : "X (anteriormente Twitter)",
"formerly Twitter" : "anteriormente Twitter",
"Mastodon" : "Mastodon",
"Bluesky" : "Bluesky",
"Facebook" : "Facebook",
"Mastodon" : "Mastodon",
"Add to your website" : "Añadir a su sitio web",
"Share with me via {productName}" : "Compartir conmigo a través de {productName}",
"HTML Code:" : "Código HTML:",
@@ -71,6 +69,8 @@ OC.L10N.register(
"Incoming share could not be processed" : "Elemento compartido entrante no pudo ser procesado",
"Cloud ID copied to the clipboard" : "ID de nube copiado al portapapeles",
"Copy to clipboard" : "Copiar al portapapeles",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "¡Puede compartir con cualquier persona que use un servidor Nextcloud u otros servidores y servicios compatibles con Open Cloud Mesh (OCM)!. Solo coloque el ID de Nube Federada de esta(s) persona(s) en el diálogo de compartir. Se verán así: persona@nube.ejemplo.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "¡Puede compartir con cualquier persona que use un servidor Nextcloud u otros servidores y servicios compatibles con Open Cloud Mesh (OCM)!. Solo coloque el ID de Nube Federada de esta(s) persona(s) en el diálogo de compartir. Se verán así: persona@nube.ejemplo.com",
"X (formerly Twitter)" : "X (anteriormente Twitter)",
"formerly Twitter" : "anteriormente Twitter"
},
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
+7 -7
View File
@@ -23,14 +23,14 @@
"Provide federated file sharing across servers" : "Provee compartición federada de archivos entre servidores",
"Confirm data upload to lookup server" : "Confirmar la carga de datos para el servidor de búsqueda",
"When enabled, all account properties (e.g. email address) with scope visibility set to \"published\", will be automatically synced and transmitted to an external system and made available in a public, global address book." : "Cuando está habilitado, todas las propiedades de las cuentas (p.ej. direcciones de correo electrónico) que se posean el ámbito de visibilidad establecido a \"publicada\" serán automáticamente sincronizadas y transmitidas a un sistema externo y se harán disponible en una libreta de direcciones pública global.",
"Disable upload" : "Deshabilitar subidas",
"Enable data upload" : "Habilitar la subida de datos",
"Disable upload" : "Deshabilitar subidas",
"Confirm querying lookup server" : "Confirmar la consulta al servidor de búsqueda",
"When enabled, the search input when creating shares will be sent to an external system that provides a public and global address book." : "Cuando está habilitado, cualquier entrada en la búsqueda cuando se crean recursos compartidos será enviada a un sistema externo que provee una libreta de direcciones pública global.",
"This is used to retrieve the federated cloud ID to make federated sharing easier." : "Esto se utiliza para obtener el ID de nube federada para hacer más sencilla la compartición federada. ",
"Moreover, email addresses of users might be sent to that system in order to verify them." : "Además, las direcciones de correo electrónico de los usuarios podrían ser enviadas a este sistema de manera de verificarlas.",
"Disable querying" : "Deshabilitar consultas",
"Enable querying" : "Habilitar consultas",
"Disable querying" : "Deshabilitar consultas",
"Unable to update federated files sharing config" : "No fue posible actualizar la configuración de los recursos compartidos federados de archivos",
"Adjust how people can share between servers. This includes shares between people on this server as well if they are using federated sharing." : "Ajustar la forma en que los usuarios pueden compartir entre servidores. Esto incluye a los recursos compartidos entre usuarios en este servidor tanto como a aquellos que usan compartición federada",
"Allow people on this server to send shares to other servers (this option also allows WebDAV access to public shares)" : "Permitir a los usuarios en este servidor enviar recursos compartidos a otros servidores (esta opción también permite el acceso público vía WebDAV a los recursos compartidos públicos)",
@@ -53,11 +53,9 @@
"You can share with anyone who uses a {productName} server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "¡Puede compartir con cualquier persona que use un servidor {productName} u otros servicios compatibles con Open Cloud Mesh (OCM)!. Solo coloque el ID de Nube Federada de esta(s) persona(s) en el diálogo de compartir. Se verán así: persona@nube.ejemplo.com",
"Your Federated Cloud ID" : "Su ID de Nube Federada",
"Share it so your friends can share files with you:" : "Compártalo para que sus amigos puedan compartir archivos con Ud.:",
"Facebook" : "Facebook",
"X (formerly Twitter)" : "X (anteriormente Twitter)",
"formerly Twitter" : "anteriormente Twitter",
"Mastodon" : "Mastodon",
"Bluesky" : "Bluesky",
"Facebook" : "Facebook",
"Mastodon" : "Mastodon",
"Add to your website" : "Añadir a su sitio web",
"Share with me via {productName}" : "Compartir conmigo a través de {productName}",
"HTML Code:" : "Código HTML:",
@@ -69,6 +67,8 @@
"Incoming share could not be processed" : "Elemento compartido entrante no pudo ser procesado",
"Cloud ID copied to the clipboard" : "ID de nube copiado al portapapeles",
"Copy to clipboard" : "Copiar al portapapeles",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "¡Puede compartir con cualquier persona que use un servidor Nextcloud u otros servidores y servicios compatibles con Open Cloud Mesh (OCM)!. Solo coloque el ID de Nube Federada de esta(s) persona(s) en el diálogo de compartir. Se verán así: persona@nube.ejemplo.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "¡Puede compartir con cualquier persona que use un servidor Nextcloud u otros servidores y servicios compatibles con Open Cloud Mesh (OCM)!. Solo coloque el ID de Nube Federada de esta(s) persona(s) en el diálogo de compartir. Se verán así: persona@nube.ejemplo.com",
"X (formerly Twitter)" : "X (anteriormente Twitter)",
"formerly Twitter" : "anteriormente Twitter"
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
}
+2 -2
View File
@@ -39,7 +39,6 @@ OC.L10N.register(
"Federated Cloud" : "Nube Federada",
"Share it so your friends can share files with you:" : "Compártelo para que tus amigos puedan compartir archivos contigo:",
"Facebook" : "Facebook",
"X (formerly Twitter)" : "X (anteriormente Twitter)",
"Add to your website" : "Agregar a tu sitio web",
"HTML Code:" : "Código HTML:",
"Cancel" : "Cancelar",
@@ -49,6 +48,7 @@ OC.L10N.register(
"Remote share password" : "Contraseña del elemento compartido remoto",
"Cloud ID copied to the clipboard" : "Identificador de nube copiado al portapapeles",
"Copy to clipboard" : "Copiar al portapapeles",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "¡Puede compartir con cualquier persona que use un servidor Nextcloud u otros servidores y servicios compatibles con Open Cloud Mesh (OCM)!. Sólo ponga el identificador de nube federada en el diálogo de compartir. Tiene la forma: persona@nube.ejemplo.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "¡Puede compartir con cualquier persona que use un servidor Nextcloud u otros servidores y servicios compatibles con Open Cloud Mesh (OCM)!. Sólo ponga el identificador de nube federada en el diálogo de compartir. Tiene la forma: persona@nube.ejemplo.com",
"X (formerly Twitter)" : "X (anteriormente Twitter)"
},
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
+2 -2
View File
@@ -37,7 +37,6 @@
"Federated Cloud" : "Nube Federada",
"Share it so your friends can share files with you:" : "Compártelo para que tus amigos puedan compartir archivos contigo:",
"Facebook" : "Facebook",
"X (formerly Twitter)" : "X (anteriormente Twitter)",
"Add to your website" : "Agregar a tu sitio web",
"HTML Code:" : "Código HTML:",
"Cancel" : "Cancelar",
@@ -47,6 +46,7 @@
"Remote share password" : "Contraseña del elemento compartido remoto",
"Cloud ID copied to the clipboard" : "Identificador de nube copiado al portapapeles",
"Copy to clipboard" : "Copiar al portapapeles",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "¡Puede compartir con cualquier persona que use un servidor Nextcloud u otros servidores y servicios compatibles con Open Cloud Mesh (OCM)!. Sólo ponga el identificador de nube federada en el diálogo de compartir. Tiene la forma: persona@nube.ejemplo.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "¡Puede compartir con cualquier persona que use un servidor Nextcloud u otros servidores y servicios compatibles con Open Cloud Mesh (OCM)!. Sólo ponga el identificador de nube federada en el diálogo de compartir. Tiene la forma: persona@nube.ejemplo.com",
"X (formerly Twitter)" : "X (anteriormente Twitter)"
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
}
+7 -7
View File
@@ -25,14 +25,14 @@ OC.L10N.register(
"Provide federated file sharing across servers" : "Toeta failide jagamist liitpilves üle serverite",
"Confirm data upload to lookup server" : "Kinnita andmete üleslaadimine tuvastusserverisse",
"When enabled, all account properties (e.g. email address) with scope visibility set to \"published\", will be automatically synced and transmitted to an external system and made available in a public, global address book." : "Kui see eelistus on kasutusel, siis kõik kasutajakonto andmed, mille nähtavuseks on märgitud „avaldatud“, sünkroniseeritakse automaatselt välistesse serveritesse ning avaldatakse liitpilve üldises aadressiraamatus.",
"Disable upload" : "Keela üleslaadimine",
"Enable data upload" : "Luba andmete üleslaadimine",
"Disable upload" : "Keela üleslaadimine",
"Confirm querying lookup server" : "Kinnita andmete pärimine tuvastusserverist",
"When enabled, the search input when creating shares will be sent to an external system that provides a public and global address book." : "Kui see eelistus on kasutusel, siis jaosmeedia loomisel kasutatud otsingusisend saadetakse automaatselt välistesse serveritesse, mis tagavad liitpilve üldise ja avaliku aadressiraamatu toimimise.",
"This is used to retrieve the federated cloud ID to make federated sharing easier." : "See on kasutusel liitpilve tunnuse laadimiseks ning see teeb jagamise liitpilves lihtsamaks.",
"Moreover, email addresses of users might be sent to that system in order to verify them." : "Lisaks võidakse sellesse serverisse saata verifitseerimise jaoks kasutajate e-posti aadresse.",
"Disable querying" : "Keela päringute tegemine",
"Enable querying" : "Luba päringute tegemine",
"Disable querying" : "Keela päringute tegemine",
"Unable to update federated files sharing config" : "Failide liitpilves jagamise seadistusi ei saa uuendada",
"Adjust how people can share between servers. This includes shares between people on this server as well if they are using federated sharing." : "Reguleeri, kuidas inimesed saavad serverite vahel jagada. See hõlmab ka selles serveris olevate inimeste vahelisi jagamisi, kui nad kasutavad liitjagamist.",
"Allow people on this server to send shares to other servers (this option also allows WebDAV access to public shares)" : "Luba selles serveris olevatel inimestel saata kaustu teistele serveritele (see valik võimaldab ka WebDAV-i juurdepääsu avalikele jagamistele)",
@@ -55,11 +55,9 @@ OC.L10N.register(
"You can share with anyone who uses a {productName} server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Saad jagada kõigiga, kes kasutavad {productName}i serverit või muid Open Cloud Meshi (OCM) ühilduvaid servereid ja teenuseid! Lihtsalt sisesta jagamise vaates nende kasutajatunnus liitpilves. See näeb välja nagu kasutajanimi@pilv.toreserver.com",
"Your Federated Cloud ID" : "Sinu kasutajatunnus liitpilves",
"Share it so your friends can share files with you:" : "Jaga seda, et su sõbrad saaksid sinuga faile jagada:",
"Facebook" : "Facebook",
"X (formerly Twitter)" : "X (varasemalt Twitter)",
"formerly Twitter" : "varasemalt Twitter",
"Mastodon" : "Mastodon",
"Bluesky" : "Bluesky",
"Facebook" : "Facebook",
"Mastodon" : "Mastodon",
"Add to your website" : "Lisa oma veebisaidile",
"Share with me via {productName}" : "Jaga minuga {productName}i vahendusel",
"HTML Code:" : "HTML kood:",
@@ -71,6 +69,8 @@ OC.L10N.register(
"Incoming share could not be processed" : "Sissetulevat kausta ei saanud töödelda",
"Cloud ID copied to the clipboard" : "Kasutajatunnus liitpilves on kopeeritud lõikelauale",
"Copy to clipboard" : "Kopeeri lõikelauale",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Saad jagada kõigiga, kes kasutavad Nextcloudi serverit või muid Open Cloud Meshi (OCM) ühilduvaid servereid ja teenuseid! Lihtsalt sisesta nende kasutajatunnus liitpilves jagamise vaates. See näeb välja nagu isiksus@pilv.toreserver.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Saad jagada kõigiga, kes kasutavad Nextcloudi serverit või muid Open Cloud Meshi (OCM) ühilduvaid servereid ja teenuseid! Lihtsalt sisesta nende kasutajatunnus liitpilves jagamise vaates. See näeb välja nagu isiksus@pilv.toreserver.com",
"X (formerly Twitter)" : "X (varasemalt Twitter)",
"formerly Twitter" : "varasemalt Twitter"
},
"nplurals=2; plural=(n != 1);");
+7 -7
View File
@@ -23,14 +23,14 @@
"Provide federated file sharing across servers" : "Toeta failide jagamist liitpilves üle serverite",
"Confirm data upload to lookup server" : "Kinnita andmete üleslaadimine tuvastusserverisse",
"When enabled, all account properties (e.g. email address) with scope visibility set to \"published\", will be automatically synced and transmitted to an external system and made available in a public, global address book." : "Kui see eelistus on kasutusel, siis kõik kasutajakonto andmed, mille nähtavuseks on märgitud „avaldatud“, sünkroniseeritakse automaatselt välistesse serveritesse ning avaldatakse liitpilve üldises aadressiraamatus.",
"Disable upload" : "Keela üleslaadimine",
"Enable data upload" : "Luba andmete üleslaadimine",
"Disable upload" : "Keela üleslaadimine",
"Confirm querying lookup server" : "Kinnita andmete pärimine tuvastusserverist",
"When enabled, the search input when creating shares will be sent to an external system that provides a public and global address book." : "Kui see eelistus on kasutusel, siis jaosmeedia loomisel kasutatud otsingusisend saadetakse automaatselt välistesse serveritesse, mis tagavad liitpilve üldise ja avaliku aadressiraamatu toimimise.",
"This is used to retrieve the federated cloud ID to make federated sharing easier." : "See on kasutusel liitpilve tunnuse laadimiseks ning see teeb jagamise liitpilves lihtsamaks.",
"Moreover, email addresses of users might be sent to that system in order to verify them." : "Lisaks võidakse sellesse serverisse saata verifitseerimise jaoks kasutajate e-posti aadresse.",
"Disable querying" : "Keela päringute tegemine",
"Enable querying" : "Luba päringute tegemine",
"Disable querying" : "Keela päringute tegemine",
"Unable to update federated files sharing config" : "Failide liitpilves jagamise seadistusi ei saa uuendada",
"Adjust how people can share between servers. This includes shares between people on this server as well if they are using federated sharing." : "Reguleeri, kuidas inimesed saavad serverite vahel jagada. See hõlmab ka selles serveris olevate inimeste vahelisi jagamisi, kui nad kasutavad liitjagamist.",
"Allow people on this server to send shares to other servers (this option also allows WebDAV access to public shares)" : "Luba selles serveris olevatel inimestel saata kaustu teistele serveritele (see valik võimaldab ka WebDAV-i juurdepääsu avalikele jagamistele)",
@@ -53,11 +53,9 @@
"You can share with anyone who uses a {productName} server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Saad jagada kõigiga, kes kasutavad {productName}i serverit või muid Open Cloud Meshi (OCM) ühilduvaid servereid ja teenuseid! Lihtsalt sisesta jagamise vaates nende kasutajatunnus liitpilves. See näeb välja nagu kasutajanimi@pilv.toreserver.com",
"Your Federated Cloud ID" : "Sinu kasutajatunnus liitpilves",
"Share it so your friends can share files with you:" : "Jaga seda, et su sõbrad saaksid sinuga faile jagada:",
"Facebook" : "Facebook",
"X (formerly Twitter)" : "X (varasemalt Twitter)",
"formerly Twitter" : "varasemalt Twitter",
"Mastodon" : "Mastodon",
"Bluesky" : "Bluesky",
"Facebook" : "Facebook",
"Mastodon" : "Mastodon",
"Add to your website" : "Lisa oma veebisaidile",
"Share with me via {productName}" : "Jaga minuga {productName}i vahendusel",
"HTML Code:" : "HTML kood:",
@@ -69,6 +67,8 @@
"Incoming share could not be processed" : "Sissetulevat kausta ei saanud töödelda",
"Cloud ID copied to the clipboard" : "Kasutajatunnus liitpilves on kopeeritud lõikelauale",
"Copy to clipboard" : "Kopeeri lõikelauale",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Saad jagada kõigiga, kes kasutavad Nextcloudi serverit või muid Open Cloud Meshi (OCM) ühilduvaid servereid ja teenuseid! Lihtsalt sisesta nende kasutajatunnus liitpilves jagamise vaates. See näeb välja nagu isiksus@pilv.toreserver.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Saad jagada kõigiga, kes kasutavad Nextcloudi serverit või muid Open Cloud Meshi (OCM) ühilduvaid servereid ja teenuseid! Lihtsalt sisesta nende kasutajatunnus liitpilves jagamise vaates. See näeb välja nagu isiksus@pilv.toreserver.com",
"X (formerly Twitter)" : "X (varasemalt Twitter)",
"formerly Twitter" : "varasemalt Twitter"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}
+7 -7
View File
@@ -25,14 +25,14 @@ OC.L10N.register(
"Provide federated file sharing across servers" : "Eskaini zerbitzarien arteko federatutako partekatzea",
"Confirm data upload to lookup server" : "Berretsi datuak bilaketa-zerbitzarira kargatzea",
"When enabled, all account properties (e.g. email address) with scope visibility set to \"published\", will be automatically synced and transmitted to an external system and made available in a public, global address book." : "Gaituta dagoenean, kontuaren propietate guztiak (adib. helbide elektronikoa) ikusgarritasun eremua \"argitaratuta\" ezarrita dutenak, automatikoki sinkronizatuko dira eta kanpoko sistema batera igorriko da, eta helbide-liburu publiko eta global batean eskuragarri jarriko da.",
"Disable upload" : "Desgaitu kargatzea",
"Enable data upload" : "Aktibatu datuen kargatzea",
"Disable upload" : "Desgaitu kargatzea",
"Confirm querying lookup server" : "Berretsi bilaketa-zerbitzaria kontsultatzea",
"When enabled, the search input when creating shares will be sent to an external system that provides a public and global address book." : "Aktibatuta dagoenean, partekatzeak sortzean egiten den bilaketa-sarrera helbide-liburu publiko eta global bat ematen duen kanpoko sistema batera bidaliko da.",
"This is used to retrieve the federated cloud ID to make federated sharing easier." : "Hau federatutako hodeiaren identifikazioa berreskuratzeko erabiltzen da, federatutako partekatzea errazagoa izan dadin.",
"Moreover, email addresses of users might be sent to that system in order to verify them." : "Gainera, erabiltzaileen posta elektronikoko helbideak bidal daitezke sistema horretara, horiek egiaztatzeko.",
"Disable querying" : "Desaktibatu kontsultatzea",
"Enable querying" : "Aktibatu kontsultatzea",
"Disable querying" : "Desaktibatu kontsultatzea",
"Unable to update federated files sharing config" : "Ezin da eguneratu fitxategi partekatze federatuaren konfigurazioa",
"Adjust how people can share between servers. This includes shares between people on this server as well if they are using federated sharing." : "Doitu nola parteka dezakeen jendeak zerbitzarien artean. Horrek zerbitzari honetako pertsonen arteko partekatzeak barne hartzen ditu, partekatze federatua erabiltzen ari badira.",
"Allow people on this server to send shares to other servers (this option also allows WebDAV access to public shares)" : "Baimendu zerbitzari honetako pertsonei beste zerbitzari batzuetarako partekatzeak bidaltzea (aukera honek partekatze publikoetara WebDAV sarbidea ere baimentzen du)",
@@ -55,11 +55,9 @@ OC.L10N.register(
"You can share with anyone who uses a {productName} server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "{productName} zerbitzari bat edo Open Cloud Mesh (OCM) zerbitzari eta zerbitzu bateragarriak erabiltzen dituen edonorekin parteka dezakezu! Jarri Hodei Federatuaren identifikazioa elkarrizketa partekatuan. Horrelako itxura du: pertsona@cloud.example.com",
"Your Federated Cloud ID" : "Zure federatutako hodei IDa",
"Share it so your friends can share files with you:" : "Bidali lagunei, zurekin fitxategiak parteka ditzaten:",
"Facebook" : "Facebook",
"X (formerly Twitter)" : "X (lehen Twitter)",
"formerly Twitter" : "lehen Twitter",
"Mastodon" : "Mastodon",
"Bluesky" : "Bluesky",
"Facebook" : "Facebook",
"Mastodon" : "Mastodon",
"Add to your website" : "Gehitu zure webgunera",
"Share with me via {productName}" : "Partekatu nirekin {productName}zerbitzariaren bidez",
"HTML Code:" : "HTML kodea:",
@@ -71,6 +69,8 @@ OC.L10N.register(
"Incoming share could not be processed" : "Sarrerako partekatzea ezin izan da prozesatu",
"Cloud ID copied to the clipboard" : "Hodei IDa arbelean kopiatu da",
"Copy to clipboard" : "Kopiatu arbelera",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Nextcloud zerbitzaria darabilen edo Open Cloud Mesh (OCM) zerbitzuarekin bateragarri den zerbitzua erabiltzen duen edonorekin partekatu dezakezu! Ipini beren Federatutako Hodei IDa partekatze leihoan. Horrelako zerbait izan ohi da: erabiltzailea@nextcloud.zerbitzaria.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Nextcloud zerbitzaria darabilen edo Open Cloud Mesh (OCM) zerbitzuarekin bateragarri den zerbitzua erabiltzen duen edonorekin partekatu dezakezu! Ipini beren Federatutako Hodei IDa partekatze leihoan. Horrelako zerbait izan ohi da: erabiltzailea@nextcloud.zerbitzaria.com",
"X (formerly Twitter)" : "X (lehen Twitter)",
"formerly Twitter" : "lehen Twitter"
},
"nplurals=2; plural=(n != 1);");
+7 -7
View File
@@ -23,14 +23,14 @@
"Provide federated file sharing across servers" : "Eskaini zerbitzarien arteko federatutako partekatzea",
"Confirm data upload to lookup server" : "Berretsi datuak bilaketa-zerbitzarira kargatzea",
"When enabled, all account properties (e.g. email address) with scope visibility set to \"published\", will be automatically synced and transmitted to an external system and made available in a public, global address book." : "Gaituta dagoenean, kontuaren propietate guztiak (adib. helbide elektronikoa) ikusgarritasun eremua \"argitaratuta\" ezarrita dutenak, automatikoki sinkronizatuko dira eta kanpoko sistema batera igorriko da, eta helbide-liburu publiko eta global batean eskuragarri jarriko da.",
"Disable upload" : "Desgaitu kargatzea",
"Enable data upload" : "Aktibatu datuen kargatzea",
"Disable upload" : "Desgaitu kargatzea",
"Confirm querying lookup server" : "Berretsi bilaketa-zerbitzaria kontsultatzea",
"When enabled, the search input when creating shares will be sent to an external system that provides a public and global address book." : "Aktibatuta dagoenean, partekatzeak sortzean egiten den bilaketa-sarrera helbide-liburu publiko eta global bat ematen duen kanpoko sistema batera bidaliko da.",
"This is used to retrieve the federated cloud ID to make federated sharing easier." : "Hau federatutako hodeiaren identifikazioa berreskuratzeko erabiltzen da, federatutako partekatzea errazagoa izan dadin.",
"Moreover, email addresses of users might be sent to that system in order to verify them." : "Gainera, erabiltzaileen posta elektronikoko helbideak bidal daitezke sistema horretara, horiek egiaztatzeko.",
"Disable querying" : "Desaktibatu kontsultatzea",
"Enable querying" : "Aktibatu kontsultatzea",
"Disable querying" : "Desaktibatu kontsultatzea",
"Unable to update federated files sharing config" : "Ezin da eguneratu fitxategi partekatze federatuaren konfigurazioa",
"Adjust how people can share between servers. This includes shares between people on this server as well if they are using federated sharing." : "Doitu nola parteka dezakeen jendeak zerbitzarien artean. Horrek zerbitzari honetako pertsonen arteko partekatzeak barne hartzen ditu, partekatze federatua erabiltzen ari badira.",
"Allow people on this server to send shares to other servers (this option also allows WebDAV access to public shares)" : "Baimendu zerbitzari honetako pertsonei beste zerbitzari batzuetarako partekatzeak bidaltzea (aukera honek partekatze publikoetara WebDAV sarbidea ere baimentzen du)",
@@ -53,11 +53,9 @@
"You can share with anyone who uses a {productName} server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "{productName} zerbitzari bat edo Open Cloud Mesh (OCM) zerbitzari eta zerbitzu bateragarriak erabiltzen dituen edonorekin parteka dezakezu! Jarri Hodei Federatuaren identifikazioa elkarrizketa partekatuan. Horrelako itxura du: pertsona@cloud.example.com",
"Your Federated Cloud ID" : "Zure federatutako hodei IDa",
"Share it so your friends can share files with you:" : "Bidali lagunei, zurekin fitxategiak parteka ditzaten:",
"Facebook" : "Facebook",
"X (formerly Twitter)" : "X (lehen Twitter)",
"formerly Twitter" : "lehen Twitter",
"Mastodon" : "Mastodon",
"Bluesky" : "Bluesky",
"Facebook" : "Facebook",
"Mastodon" : "Mastodon",
"Add to your website" : "Gehitu zure webgunera",
"Share with me via {productName}" : "Partekatu nirekin {productName}zerbitzariaren bidez",
"HTML Code:" : "HTML kodea:",
@@ -69,6 +67,8 @@
"Incoming share could not be processed" : "Sarrerako partekatzea ezin izan da prozesatu",
"Cloud ID copied to the clipboard" : "Hodei IDa arbelean kopiatu da",
"Copy to clipboard" : "Kopiatu arbelera",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Nextcloud zerbitzaria darabilen edo Open Cloud Mesh (OCM) zerbitzuarekin bateragarri den zerbitzua erabiltzen duen edonorekin partekatu dezakezu! Ipini beren Federatutako Hodei IDa partekatze leihoan. Horrelako zerbait izan ohi da: erabiltzailea@nextcloud.zerbitzaria.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Nextcloud zerbitzaria darabilen edo Open Cloud Mesh (OCM) zerbitzuarekin bateragarri den zerbitzua erabiltzen duen edonorekin partekatu dezakezu! Ipini beren Federatutako Hodei IDa partekatze leihoan. Horrelako zerbait izan ohi da: erabiltzailea@nextcloud.zerbitzaria.com",
"X (formerly Twitter)" : "X (lehen Twitter)",
"formerly Twitter" : "lehen Twitter"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}
+3 -2
View File
@@ -26,8 +26,8 @@ OC.L10N.register(
"Copied!" : "Kopioitu!",
"Federated Cloud" : "Federoitu pilvi",
"Share it so your friends can share files with you:" : "Jaa se, jotta ystäväsi voivat jakaa tiedostoja kanssasi:",
"Bluesky" : "Bluesky",
"Facebook" : "Facebook",
"X (formerly Twitter)" : "X (aiemmin Twitter)",
"Mastodon" : "Mastodon",
"Add to your website" : "Lisää verkkosivuillesi",
"HTML Code:" : "HTML-koodi:",
@@ -37,6 +37,7 @@ OC.L10N.register(
"Do you want to add the remote share {name} from {owner}@{remote}?" : "Haluatko lisätä etäjaon {name} kohteesta {owner}@{remote}?",
"Remote share password" : "Etäjaon salasana",
"Copy to clipboard" : "Kopioi leikepöydälle",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Voit jakaa kenelle tahansa, joka käyttää Nextcloud-palvelinta tai muuta Open Cloud Mesh (OCM) -yhteensopivaa palvelinta tai palvelua! Kirjoita heidän federoidun pilven tunniste jaon kohteeksi. Se on muodossa henkilö@cloud.example.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Voit jakaa kenelle tahansa, joka käyttää Nextcloud-palvelinta tai muuta Open Cloud Mesh (OCM) -yhteensopivaa palvelinta tai palvelua! Kirjoita heidän federoidun pilven tunniste jaon kohteeksi. Se on muodossa henkilö@cloud.example.com",
"X (formerly Twitter)" : "X (aiemmin Twitter)"
},
"nplurals=2; plural=(n != 1);");
+3 -2
View File
@@ -24,8 +24,8 @@
"Copied!" : "Kopioitu!",
"Federated Cloud" : "Federoitu pilvi",
"Share it so your friends can share files with you:" : "Jaa se, jotta ystäväsi voivat jakaa tiedostoja kanssasi:",
"Bluesky" : "Bluesky",
"Facebook" : "Facebook",
"X (formerly Twitter)" : "X (aiemmin Twitter)",
"Mastodon" : "Mastodon",
"Add to your website" : "Lisää verkkosivuillesi",
"HTML Code:" : "HTML-koodi:",
@@ -35,6 +35,7 @@
"Do you want to add the remote share {name} from {owner}@{remote}?" : "Haluatko lisätä etäjaon {name} kohteesta {owner}@{remote}?",
"Remote share password" : "Etäjaon salasana",
"Copy to clipboard" : "Kopioi leikepöydälle",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Voit jakaa kenelle tahansa, joka käyttää Nextcloud-palvelinta tai muuta Open Cloud Mesh (OCM) -yhteensopivaa palvelinta tai palvelua! Kirjoita heidän federoidun pilven tunniste jaon kohteeksi. Se on muodossa henkilö@cloud.example.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Voit jakaa kenelle tahansa, joka käyttää Nextcloud-palvelinta tai muuta Open Cloud Mesh (OCM) -yhteensopivaa palvelinta tai palvelua! Kirjoita heidän federoidun pilven tunniste jaon kohteeksi. Se on muodossa henkilö@cloud.example.com",
"X (formerly Twitter)" : "X (aiemmin Twitter)"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}
+7 -7
View File
@@ -25,14 +25,14 @@ OC.L10N.register(
"Provide federated file sharing across servers" : "Fourni un partage de fichiers fédéré entre plusieurs serveurs",
"Confirm data upload to lookup server" : "Confirmer le téléversement des données sur le serveur de recherche",
"When enabled, all account properties (e.g. email address) with scope visibility set to \"published\", will be automatically synced and transmitted to an external system and made available in a public, global address book." : "Lorsque cette option est activée, toutes les propriétés du compte (par exemple, l'adresse e-mail) dont la visibilité est définie sur \"published\" seront automatiquement synchronisées et transmises à un système externe et mises à disposition dans un carnet d'adresses public et global.",
"Disable upload" : "Désactiver le téléchargement",
"Enable data upload" : "Activer l'envoi de données",
"Disable upload" : "Désactiver le téléchargement",
"Confirm querying lookup server" : "Confirmer l'interrogation du serveur de recherche",
"When enabled, the search input when creating shares will be sent to an external system that provides a public and global address book." : "Lorsque cette option est activée, la saisie de recherche lors de la création de partages sera envoyée à un système externe qui fournit un carnet d'adresses public et global.",
"This is used to retrieve the federated cloud ID to make federated sharing easier." : "Ceci est utilisé pour récupérer l'ID du cloud fédéré afin de faciliter le partage fédéré.",
"Moreover, email addresses of users might be sent to that system in order to verify them." : "De plus, les adresses mail des utilisateurs peuvent être envoyées à ce système pour les vérifier.",
"Disable querying" : "Désactiver le requêtage",
"Enable querying" : "Activer le requêtage",
"Disable querying" : "Désactiver le requêtage",
"Unable to update federated files sharing config" : "Impossible de mettre à jour la configuration du partage fédéré de fichiers ",
"Adjust how people can share between servers. This includes shares between people on this server as well if they are using federated sharing." : "Configurer comment les utilisateurs peuvent faire des partages entre serveurs. Cela inclut aussi les partages entre personnes de ce serveur s'ils utilisent des partages fédérés.",
"Allow people on this server to send shares to other servers (this option also allows WebDAV access to public shares)" : "Autoriser les personnes de ce serveur à envoyer des partages vers d'autres serveurs (cette option permet aussi l'accès WebDAV aux partages publics)",
@@ -55,11 +55,9 @@ OC.L10N.register(
"You can share with anyone who uses a {productName} server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Vous pouvez partager avec quiconque utilise un serveur {productName} ou un serveur ou service compatible Open Cloud Mesh (OCM). Renseignez simplement son ID de Cloud Fédéré sur une instance fédérée dans la boîte de dialogue de partage. Cela ressemble à utilisateur@cloud.exemple.com.",
"Your Federated Cloud ID" : "Votre ID de cloud fédéré",
"Share it so your friends can share files with you:" : "Partagez-le afin que vos amis puissent partager des fichiers avec vous :",
"Facebook" : "Facebook",
"X (formerly Twitter)" : "X (anciennement Twitter)",
"formerly Twitter" : "anciennement Twitter",
"Mastodon" : "Mastodon",
"Bluesky" : "Bluesky",
"Facebook" : "Facebook",
"Mastodon" : "Mastodon",
"Add to your website" : "Ajouter à votre site web",
"Share with me via {productName}" : "Partager avec moi via {productName}",
"HTML Code:" : "Code HTML :",
@@ -71,6 +69,8 @@ OC.L10N.register(
"Incoming share could not be processed" : "Le partage entrant n'a pas pu être traité",
"Cloud ID copied to the clipboard" : "ID de Cloud Fédéré copié dans le presse-papiers",
"Copy to clipboard" : "Copier dans le presse-papiers",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Vous pouvez partager avec quiconque utilise un serveur Nextcloud ou un serveur ou service compatible Open Cloud Mesh (OCM). Renseignez simplement son ID de Cloud Fédéré sur une instance fédérée dans la boîte de dialogue de partage. Cela ressemble à utilisateur@cloud.exemple.com."
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Vous pouvez partager avec quiconque utilise un serveur Nextcloud ou un serveur ou service compatible Open Cloud Mesh (OCM). Renseignez simplement son ID de Cloud Fédéré sur une instance fédérée dans la boîte de dialogue de partage. Cela ressemble à utilisateur@cloud.exemple.com.",
"X (formerly Twitter)" : "X (anciennement Twitter)",
"formerly Twitter" : "anciennement Twitter"
},
"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");
+7 -7
View File
@@ -23,14 +23,14 @@
"Provide federated file sharing across servers" : "Fourni un partage de fichiers fédéré entre plusieurs serveurs",
"Confirm data upload to lookup server" : "Confirmer le téléversement des données sur le serveur de recherche",
"When enabled, all account properties (e.g. email address) with scope visibility set to \"published\", will be automatically synced and transmitted to an external system and made available in a public, global address book." : "Lorsque cette option est activée, toutes les propriétés du compte (par exemple, l'adresse e-mail) dont la visibilité est définie sur \"published\" seront automatiquement synchronisées et transmises à un système externe et mises à disposition dans un carnet d'adresses public et global.",
"Disable upload" : "Désactiver le téléchargement",
"Enable data upload" : "Activer l'envoi de données",
"Disable upload" : "Désactiver le téléchargement",
"Confirm querying lookup server" : "Confirmer l'interrogation du serveur de recherche",
"When enabled, the search input when creating shares will be sent to an external system that provides a public and global address book." : "Lorsque cette option est activée, la saisie de recherche lors de la création de partages sera envoyée à un système externe qui fournit un carnet d'adresses public et global.",
"This is used to retrieve the federated cloud ID to make federated sharing easier." : "Ceci est utilisé pour récupérer l'ID du cloud fédéré afin de faciliter le partage fédéré.",
"Moreover, email addresses of users might be sent to that system in order to verify them." : "De plus, les adresses mail des utilisateurs peuvent être envoyées à ce système pour les vérifier.",
"Disable querying" : "Désactiver le requêtage",
"Enable querying" : "Activer le requêtage",
"Disable querying" : "Désactiver le requêtage",
"Unable to update federated files sharing config" : "Impossible de mettre à jour la configuration du partage fédéré de fichiers ",
"Adjust how people can share between servers. This includes shares between people on this server as well if they are using federated sharing." : "Configurer comment les utilisateurs peuvent faire des partages entre serveurs. Cela inclut aussi les partages entre personnes de ce serveur s'ils utilisent des partages fédérés.",
"Allow people on this server to send shares to other servers (this option also allows WebDAV access to public shares)" : "Autoriser les personnes de ce serveur à envoyer des partages vers d'autres serveurs (cette option permet aussi l'accès WebDAV aux partages publics)",
@@ -53,11 +53,9 @@
"You can share with anyone who uses a {productName} server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Vous pouvez partager avec quiconque utilise un serveur {productName} ou un serveur ou service compatible Open Cloud Mesh (OCM). Renseignez simplement son ID de Cloud Fédéré sur une instance fédérée dans la boîte de dialogue de partage. Cela ressemble à utilisateur@cloud.exemple.com.",
"Your Federated Cloud ID" : "Votre ID de cloud fédéré",
"Share it so your friends can share files with you:" : "Partagez-le afin que vos amis puissent partager des fichiers avec vous :",
"Facebook" : "Facebook",
"X (formerly Twitter)" : "X (anciennement Twitter)",
"formerly Twitter" : "anciennement Twitter",
"Mastodon" : "Mastodon",
"Bluesky" : "Bluesky",
"Facebook" : "Facebook",
"Mastodon" : "Mastodon",
"Add to your website" : "Ajouter à votre site web",
"Share with me via {productName}" : "Partager avec moi via {productName}",
"HTML Code:" : "Code HTML :",
@@ -69,6 +67,8 @@
"Incoming share could not be processed" : "Le partage entrant n'a pas pu être traité",
"Cloud ID copied to the clipboard" : "ID de Cloud Fédéré copié dans le presse-papiers",
"Copy to clipboard" : "Copier dans le presse-papiers",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Vous pouvez partager avec quiconque utilise un serveur Nextcloud ou un serveur ou service compatible Open Cloud Mesh (OCM). Renseignez simplement son ID de Cloud Fédéré sur une instance fédérée dans la boîte de dialogue de partage. Cela ressemble à utilisateur@cloud.exemple.com."
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Vous pouvez partager avec quiconque utilise un serveur Nextcloud ou un serveur ou service compatible Open Cloud Mesh (OCM). Renseignez simplement son ID de Cloud Fédéré sur une instance fédérée dans la boîte de dialogue de partage. Cela ressemble à utilisateur@cloud.exemple.com.",
"X (formerly Twitter)" : "X (anciennement Twitter)",
"formerly Twitter" : "anciennement Twitter"
},"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
}
+7 -7
View File
@@ -25,14 +25,14 @@ OC.L10N.register(
"Provide federated file sharing across servers" : "Comhroinnt comhad cónasctha a sholáthar thar freastalaithe",
"Confirm data upload to lookup server" : "Deimhnigh uaslódáil sonraí chuig an bhfreastalaí cuardaigh",
"When enabled, all account properties (e.g. email address) with scope visibility set to \"published\", will be automatically synced and transmitted to an external system and made available in a public, global address book." : "Nuair a bheidh sé cumasaithe, déanfar gach maoin chuntais (m.sh. seoladh ríomhphoist) a bhfuil scóip infheictheachta aici “foilsithe”, a shioncronú go huathoibríoch agus a tharchur chuig córas seachtrach agus cuirfear ar fáil iad i leabhar seoltaí poiblí domhanda.",
"Disable upload" : "Díchumasaigh uaslódáil",
"Enable data upload" : "Cumasaigh uaslódáil sonraí",
"Disable upload" : "Díchumasaigh uaslódáil",
"Confirm querying lookup server" : "Deimhnigh an freastalaí cuardaigh fiosraithe",
"When enabled, the search input when creating shares will be sent to an external system that provides a public and global address book." : "Nuair a bheidh sé cumasaithe, seolfar an t-ionchur cuardaigh agus scaireanna á gcruthú chuig córas seachtrach a sholáthraíonn leabhar seoltaí poiblí agus domhanda.",
"This is used to retrieve the federated cloud ID to make federated sharing easier." : "Úsáidtear é seo chun an ID scamall cónasctha a aisghabháil chun comhroinnt chónasctha a dhéanamh níos éasca.",
"Moreover, email addresses of users might be sent to that system in order to verify them." : "Ina theannta sin, dfhéadfaí seoltaí ríomhphoist úsáideoirí a sheoladh chuig an gcóras sin chun iad a fhíorú.",
"Disable querying" : "Díchumasaigh an cheistiú",
"Enable querying" : "Cumasaigh fiosrú",
"Disable querying" : "Díchumasaigh an cheistiú",
"Unable to update federated files sharing config" : "Ní féidir an chumraíocht chomhroinnte comhad a nuashonrú",
"Adjust how people can share between servers. This includes shares between people on this server as well if they are using federated sharing." : "Coigeartaigh conas is féidir le daoine roinnt idir freastalaithe. Áirítear leis seo scaireanna idir daoine ar an bhfreastalaí seo freisin má tá comhroinnt chónaidhmeach á úsáid acu.",
"Allow people on this server to send shares to other servers (this option also allows WebDAV access to public shares)" : "Lig do dhaoine ar an bhfreastalaí seo scaireanna a sheoladh chuig freastalaithe eile ( ceadaíonn an rogha seo rochtain WebDAV ar scaireanna poiblí freisin)",
@@ -55,11 +55,9 @@ OC.L10N.register(
"You can share with anyone who uses a {productName} server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Is féidir leat comhroinnt le duine ar bith a úsáideann freastalaí {productName} nó freastalaithe agus seirbhísí eile atá comhoiriúnach le Open Cloud Mesh (OCM)! Cuir a n-ID Cónaidhme Cloud sa dialóg comhroinnte. Tá cuma person@cloud.example.com air.",
"Your Federated Cloud ID" : "D'Aitheantas Néal Cónaidhmeach",
"Share it so your friends can share files with you:" : "Roinn é ionas gur féidir le do chairde comhaid a roinnt leat:",
"Facebook" : "Facebook",
"X (formerly Twitter)" : "X (Twitter roimhe seo)",
"formerly Twitter" : "Twitter roimhe seo",
"Mastodon" : "Mastodon",
"Bluesky" : "Bluesky",
"Facebook" : "Facebook",
"Mastodon" : "Mastodon",
"Add to your website" : "Cuir le do láithreán gréasáin",
"Share with me via {productName}" : "Roinn liom trí {productName}",
"HTML Code:" : "Cód HTML:",
@@ -71,6 +69,8 @@ OC.L10N.register(
"Incoming share could not be processed" : "Níorbh fhéidir an sciar isteach a phróiseáil",
"Cloud ID copied to the clipboard" : "Cóipeáladh Cloud ID chuig an ngearrthaisce",
"Copy to clipboard" : "Cóipeáil chuig an ngearrthaisce",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Is féidir leat a roinnt le duine ar bith a úsáideann freastalaí Nextcloud nó freastalaithe agus seirbhísí comhoiriúnacha Open Cloud Mesh (OCM) eile! Níl le déanamh ach a n-ID Cloud Cónaidhme a chur sa dialóg scaireanna. Breathnaíonn sé cosúil le person@cloud.example.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Is féidir leat a roinnt le duine ar bith a úsáideann freastalaí Nextcloud nó freastalaithe agus seirbhísí comhoiriúnacha Open Cloud Mesh (OCM) eile! Níl le déanamh ach a n-ID Cloud Cónaidhme a chur sa dialóg scaireanna. Breathnaíonn sé cosúil le person@cloud.example.com",
"X (formerly Twitter)" : "X (Twitter roimhe seo)",
"formerly Twitter" : "Twitter roimhe seo"
},
"nplurals=5; plural=(n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n<11 ? 3 : 4);");
+7 -7
View File
@@ -23,14 +23,14 @@
"Provide federated file sharing across servers" : "Comhroinnt comhad cónasctha a sholáthar thar freastalaithe",
"Confirm data upload to lookup server" : "Deimhnigh uaslódáil sonraí chuig an bhfreastalaí cuardaigh",
"When enabled, all account properties (e.g. email address) with scope visibility set to \"published\", will be automatically synced and transmitted to an external system and made available in a public, global address book." : "Nuair a bheidh sé cumasaithe, déanfar gach maoin chuntais (m.sh. seoladh ríomhphoist) a bhfuil scóip infheictheachta aici “foilsithe”, a shioncronú go huathoibríoch agus a tharchur chuig córas seachtrach agus cuirfear ar fáil iad i leabhar seoltaí poiblí domhanda.",
"Disable upload" : "Díchumasaigh uaslódáil",
"Enable data upload" : "Cumasaigh uaslódáil sonraí",
"Disable upload" : "Díchumasaigh uaslódáil",
"Confirm querying lookup server" : "Deimhnigh an freastalaí cuardaigh fiosraithe",
"When enabled, the search input when creating shares will be sent to an external system that provides a public and global address book." : "Nuair a bheidh sé cumasaithe, seolfar an t-ionchur cuardaigh agus scaireanna á gcruthú chuig córas seachtrach a sholáthraíonn leabhar seoltaí poiblí agus domhanda.",
"This is used to retrieve the federated cloud ID to make federated sharing easier." : "Úsáidtear é seo chun an ID scamall cónasctha a aisghabháil chun comhroinnt chónasctha a dhéanamh níos éasca.",
"Moreover, email addresses of users might be sent to that system in order to verify them." : "Ina theannta sin, dfhéadfaí seoltaí ríomhphoist úsáideoirí a sheoladh chuig an gcóras sin chun iad a fhíorú.",
"Disable querying" : "Díchumasaigh an cheistiú",
"Enable querying" : "Cumasaigh fiosrú",
"Disable querying" : "Díchumasaigh an cheistiú",
"Unable to update federated files sharing config" : "Ní féidir an chumraíocht chomhroinnte comhad a nuashonrú",
"Adjust how people can share between servers. This includes shares between people on this server as well if they are using federated sharing." : "Coigeartaigh conas is féidir le daoine roinnt idir freastalaithe. Áirítear leis seo scaireanna idir daoine ar an bhfreastalaí seo freisin má tá comhroinnt chónaidhmeach á úsáid acu.",
"Allow people on this server to send shares to other servers (this option also allows WebDAV access to public shares)" : "Lig do dhaoine ar an bhfreastalaí seo scaireanna a sheoladh chuig freastalaithe eile ( ceadaíonn an rogha seo rochtain WebDAV ar scaireanna poiblí freisin)",
@@ -53,11 +53,9 @@
"You can share with anyone who uses a {productName} server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Is féidir leat comhroinnt le duine ar bith a úsáideann freastalaí {productName} nó freastalaithe agus seirbhísí eile atá comhoiriúnach le Open Cloud Mesh (OCM)! Cuir a n-ID Cónaidhme Cloud sa dialóg comhroinnte. Tá cuma person@cloud.example.com air.",
"Your Federated Cloud ID" : "D'Aitheantas Néal Cónaidhmeach",
"Share it so your friends can share files with you:" : "Roinn é ionas gur féidir le do chairde comhaid a roinnt leat:",
"Facebook" : "Facebook",
"X (formerly Twitter)" : "X (Twitter roimhe seo)",
"formerly Twitter" : "Twitter roimhe seo",
"Mastodon" : "Mastodon",
"Bluesky" : "Bluesky",
"Facebook" : "Facebook",
"Mastodon" : "Mastodon",
"Add to your website" : "Cuir le do láithreán gréasáin",
"Share with me via {productName}" : "Roinn liom trí {productName}",
"HTML Code:" : "Cód HTML:",
@@ -69,6 +67,8 @@
"Incoming share could not be processed" : "Níorbh fhéidir an sciar isteach a phróiseáil",
"Cloud ID copied to the clipboard" : "Cóipeáladh Cloud ID chuig an ngearrthaisce",
"Copy to clipboard" : "Cóipeáil chuig an ngearrthaisce",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Is féidir leat a roinnt le duine ar bith a úsáideann freastalaí Nextcloud nó freastalaithe agus seirbhísí comhoiriúnacha Open Cloud Mesh (OCM) eile! Níl le déanamh ach a n-ID Cloud Cónaidhme a chur sa dialóg scaireanna. Breathnaíonn sé cosúil le person@cloud.example.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Is féidir leat a roinnt le duine ar bith a úsáideann freastalaí Nextcloud nó freastalaithe agus seirbhísí comhoiriúnacha Open Cloud Mesh (OCM) eile! Níl le déanamh ach a n-ID Cloud Cónaidhme a chur sa dialóg scaireanna. Breathnaíonn sé cosúil le person@cloud.example.com",
"X (formerly Twitter)" : "X (Twitter roimhe seo)",
"formerly Twitter" : "Twitter roimhe seo"
},"pluralForm" :"nplurals=5; plural=(n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n<11 ? 3 : 4);"
}
+7 -7
View File
@@ -25,14 +25,14 @@ OC.L10N.register(
"Provide federated file sharing across servers" : "Fornece a compartición federada de ficheiros entre servidores",
"Confirm data upload to lookup server" : "Confirmar o envío de datos ao servidor de busca",
"When enabled, all account properties (e.g. email address) with scope visibility set to \"published\", will be automatically synced and transmitted to an external system and made available in a public, global address book." : "Cando está activado, todas as propiedades da conta (p. ex., o enderezo de correo-e) co ámbito de visibilidade definido en «publicado», sincronizaranse automaticamente e transmitiranse a un sistema externo e estarán dispoñíbeis nun caderno de enderezos público e global.",
"Disable upload" : "Desactivar o envío",
"Enable data upload" : "Activar o envío de datos",
"Disable upload" : "Desactivar o envío",
"Confirm querying lookup server" : "Confirmar a consulta ao servidor de buscas",
"When enabled, the search input when creating shares will be sent to an external system that provides a public and global address book." : "Cando está activada, a entrada de busca ao crear comparticións enviarase a un sistema externo que fornece un caderno de enderezos público e global.",
"This is used to retrieve the federated cloud ID to make federated sharing easier." : "Isto utilízase para recuperar o ID de nube federado para facilitar a compartición federada.",
"Moreover, email addresses of users might be sent to that system in order to verify them." : "Ademais, poderánse enviar os enderezos de correo-e dos usuarios a ese sistema para verificalos.",
"Disable querying" : "Desactivar a consulta",
"Enable querying" : "Activar a consulta",
"Disable querying" : "Desactivar a consulta",
"Unable to update federated files sharing config" : "Non é posíbel actualizar a configuración de uso compartido de ficheiros federados",
"Adjust how people can share between servers. This includes shares between people on this server as well if they are using federated sharing." : "Axuste a forma como a xente pode compartir entre servidores. Isto inclúe tamén as comparticións entre persoas deste servidor se están a usaren a compartición federada.",
"Allow people on this server to send shares to other servers (this option also allows WebDAV access to public shares)" : "Permitirlle á xente deste servidor enviar comparticións a outros servidores (esta opción tamén permite o acceso de WebDAV a comparticións públicas)",
@@ -55,11 +55,9 @@ OC.L10N.register(
"You can share with anyone who uses a {productName} server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Pode compartir con calquera persoa que empregue servidores {productName}, ou outro servidor ou servizo compatíbel co Open Cloud Mesh (OCM)! Simplemente, introduza o seu ID de nube federada no diálogo de compartir. É algo como persona@cloud.example.com",
"Your Federated Cloud ID" : "ID da súa nube federada",
"Share it so your friends can share files with you:" : "Compártao para que as súas amizades poidan compartir ficheiros con Vde.:",
"Facebook" : "Facebook",
"X (formerly Twitter)" : "X (anteriormente Twitter).",
"formerly Twitter" : "anteriormente Twitter",
"Mastodon" : "Mastodon",
"Bluesky" : "Bluesky",
"Facebook" : "Facebook",
"Mastodon" : "Mastodon",
"Add to your website" : "Engadir ao seu sitio web",
"Share with me via {productName}" : "Comparta comigo a través de {productName}",
"HTML Code:" : "Código HTML:",
@@ -71,6 +69,8 @@ OC.L10N.register(
"Incoming share could not be processed" : "Non foi posíbel procesar a compartición entrante",
"Cloud ID copied to the clipboard" : "O identificador de nube (Cloud ID) (foi copiado no portapapeis",
"Copy to clipboard" : "Copiar no portapapeis.",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Pode compartir con calquera persoa que empregue servidores Nextcloud, ou outro servidor ou servizo compatíbel co Open Cloud Mesh (OCM)! Simplemente, introduza o seu ID de nube federada no diálogo de compartir. É algo como persona@cloud.example.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Pode compartir con calquera persoa que empregue servidores Nextcloud, ou outro servidor ou servizo compatíbel co Open Cloud Mesh (OCM)! Simplemente, introduza o seu ID de nube federada no diálogo de compartir. É algo como persona@cloud.example.com",
"X (formerly Twitter)" : "X (anteriormente Twitter).",
"formerly Twitter" : "anteriormente Twitter"
},
"nplurals=2; plural=(n != 1);");
+7 -7
View File
@@ -23,14 +23,14 @@
"Provide federated file sharing across servers" : "Fornece a compartición federada de ficheiros entre servidores",
"Confirm data upload to lookup server" : "Confirmar o envío de datos ao servidor de busca",
"When enabled, all account properties (e.g. email address) with scope visibility set to \"published\", will be automatically synced and transmitted to an external system and made available in a public, global address book." : "Cando está activado, todas as propiedades da conta (p. ex., o enderezo de correo-e) co ámbito de visibilidade definido en «publicado», sincronizaranse automaticamente e transmitiranse a un sistema externo e estarán dispoñíbeis nun caderno de enderezos público e global.",
"Disable upload" : "Desactivar o envío",
"Enable data upload" : "Activar o envío de datos",
"Disable upload" : "Desactivar o envío",
"Confirm querying lookup server" : "Confirmar a consulta ao servidor de buscas",
"When enabled, the search input when creating shares will be sent to an external system that provides a public and global address book." : "Cando está activada, a entrada de busca ao crear comparticións enviarase a un sistema externo que fornece un caderno de enderezos público e global.",
"This is used to retrieve the federated cloud ID to make federated sharing easier." : "Isto utilízase para recuperar o ID de nube federado para facilitar a compartición federada.",
"Moreover, email addresses of users might be sent to that system in order to verify them." : "Ademais, poderánse enviar os enderezos de correo-e dos usuarios a ese sistema para verificalos.",
"Disable querying" : "Desactivar a consulta",
"Enable querying" : "Activar a consulta",
"Disable querying" : "Desactivar a consulta",
"Unable to update federated files sharing config" : "Non é posíbel actualizar a configuración de uso compartido de ficheiros federados",
"Adjust how people can share between servers. This includes shares between people on this server as well if they are using federated sharing." : "Axuste a forma como a xente pode compartir entre servidores. Isto inclúe tamén as comparticións entre persoas deste servidor se están a usaren a compartición federada.",
"Allow people on this server to send shares to other servers (this option also allows WebDAV access to public shares)" : "Permitirlle á xente deste servidor enviar comparticións a outros servidores (esta opción tamén permite o acceso de WebDAV a comparticións públicas)",
@@ -53,11 +53,9 @@
"You can share with anyone who uses a {productName} server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Pode compartir con calquera persoa que empregue servidores {productName}, ou outro servidor ou servizo compatíbel co Open Cloud Mesh (OCM)! Simplemente, introduza o seu ID de nube federada no diálogo de compartir. É algo como persona@cloud.example.com",
"Your Federated Cloud ID" : "ID da súa nube federada",
"Share it so your friends can share files with you:" : "Compártao para que as súas amizades poidan compartir ficheiros con Vde.:",
"Facebook" : "Facebook",
"X (formerly Twitter)" : "X (anteriormente Twitter).",
"formerly Twitter" : "anteriormente Twitter",
"Mastodon" : "Mastodon",
"Bluesky" : "Bluesky",
"Facebook" : "Facebook",
"Mastodon" : "Mastodon",
"Add to your website" : "Engadir ao seu sitio web",
"Share with me via {productName}" : "Comparta comigo a través de {productName}",
"HTML Code:" : "Código HTML:",
@@ -69,6 +67,8 @@
"Incoming share could not be processed" : "Non foi posíbel procesar a compartición entrante",
"Cloud ID copied to the clipboard" : "O identificador de nube (Cloud ID) (foi copiado no portapapeis",
"Copy to clipboard" : "Copiar no portapapeis.",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Pode compartir con calquera persoa que empregue servidores Nextcloud, ou outro servidor ou servizo compatíbel co Open Cloud Mesh (OCM)! Simplemente, introduza o seu ID de nube federada no diálogo de compartir. É algo como persona@cloud.example.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Pode compartir con calquera persoa que empregue servidores Nextcloud, ou outro servidor ou servizo compatíbel co Open Cloud Mesh (OCM)! Simplemente, introduza o seu ID de nube federada no diálogo de compartir. É algo como persona@cloud.example.com",
"X (formerly Twitter)" : "X (anteriormente Twitter).",
"formerly Twitter" : "anteriormente Twitter"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}
+7 -7
View File
@@ -25,14 +25,14 @@ OC.L10N.register(
"Provide federated file sharing across servers" : "Föderált fájlmegosztás biztosítása a kiszolgálók között",
"Confirm data upload to lookup server" : "Keresési kiszolgálóra történő adatfeltöltés megerősítése",
"When enabled, all account properties (e.g. email address) with scope visibility set to \"published\", will be automatically synced and transmitted to an external system and made available in a public, global address book." : "Ha engedélyezve van, az összes „közzétett” láthatóságú fióktulajdonság (például e-mail-cím) automatikusan szinkronizálva lesz és átküldésre kerül egy nyilvános, globális címjegyzékbe.",
"Disable upload" : "Feltöltés letiltása",
"Enable data upload" : "Adatfeltöltés engedélyezése",
"Disable upload" : "Feltöltés letiltása",
"Confirm querying lookup server" : "Keresési kiszolgálóról való lekérés megerősítése",
"When enabled, the search input when creating shares will be sent to an external system that provides a public and global address book." : "Ha engedélyezve van, a keresési bemenet el lesz küldve egy külső rendszernek, amely egy nyilvános és globális címjegyzéket biztosít.",
"This is used to retrieve the federated cloud ID to make federated sharing easier." : "Ez arra használatos, hogy lekérje a föderált felhőazonosítót, hogy megkönnyítse a föderált megosztást.",
"Moreover, email addresses of users might be sent to that system in order to verify them." : "Továbbá a felhasználók e-mail-címe is elküldésre kerülhet ellenőrzés céljából.",
"Disable querying" : "Lekérdezés letiltása",
"Enable querying" : "Lekérdezés engedélyezése",
"Disable querying" : "Lekérdezés letiltása",
"Unable to update federated files sharing config" : "A föderált fájlmegosztási konfiguráció nem frissíthető",
"Adjust how people can share between servers. This includes shares between people on this server as well if they are using federated sharing." : "Beállítás, hogy az emberek hogyan oszthatnak meg kiszolgálók között. Ebbe beleértendők a kiszolgálón lévő emberek közti megosztások és a megosztások is.",
"Allow people on this server to send shares to other servers (this option also allows WebDAV access to public shares)" : "Engedélyezés a kiszolgálón lévő embereknek, hogy megosztásokat küldjenek más kiszolgálóknak (ez a lehetőség lehetővé teszi a nyilvános megosztások WebDAV hozzáférését is)",
@@ -55,11 +55,9 @@ OC.L10N.register(
"You can share with anyone who uses a {productName} server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Bármelyik {productName}-kiszolgálót vagy egyéb Open Cloud Mesh-kompatibilis (OCM) kiszolgálót és szolgáltatást használó felhasználóval megoszthatja adatait. Csak írja a föderált felhőazonosítóját a megosztási párbeszédablakba. Hasonlóan néz ki: person@cloud.example.com",
"Your Federated Cloud ID" : "Az Ön föderált felhőazonosítója",
"Share it so your friends can share files with you:" : "Ossza meg, hogy a barátai is oszthassanak meg Önnel fájlokat:",
"Facebook" : "Facebook",
"X (formerly Twitter)" : "X (korábban Twitter)",
"formerly Twitter" : "korábban Twitter",
"Mastodon" : "Mastodon",
"Bluesky" : "Bluesky",
"Facebook" : "Facebook",
"Mastodon" : "Mastodon",
"Add to your website" : "Adja hozzá saját weboldalához",
"Share with me via {productName}" : "Megnyitás {productName} használatával",
"HTML Code:" : "HTML-kód:",
@@ -71,6 +69,8 @@ OC.L10N.register(
"Incoming share could not be processed" : "A bejövő megosztás nem dolgozható fel",
"Cloud ID copied to the clipboard" : "Felhőazonosító a vágólapra másolva",
"Copy to clipboard" : "Másolás a vágólapra",
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Bármelyik Nextcloud-kiszolgálót vagy egyéb Open Cloud Mesh-kompatibilis (OCM) kiszolgálót és szolgáltatást használó felhasználóval megoszthatja adatait. Csak tegye a föderált felhőazonosítóját a megosztási párbeszédablakba. Hasonlóan néz ki: person@cloud.example.com"
"You can share with anyone who uses a Nextcloud server or other Open Cloud Mesh (OCM) compatible servers and services! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Bármelyik Nextcloud-kiszolgálót vagy egyéb Open Cloud Mesh-kompatibilis (OCM) kiszolgálót és szolgáltatást használó felhasználóval megoszthatja adatait. Csak tegye a föderált felhőazonosítóját a megosztási párbeszédablakba. Hasonlóan néz ki: person@cloud.example.com",
"X (formerly Twitter)" : "X (korábban Twitter)",
"formerly Twitter" : "korábban Twitter"
},
"nplurals=2; plural=(n != 1);");

Some files were not shown because too many files have changed in this diff Show More