Merge branch 'master' into bugfix/incorrect-filename-when-sync-s3

pull/43660/head
hopleus 2 weeks ago committed by GitHub
commit 937718afab
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -1,4 +1,4 @@
FROM ubuntu:jammy
FROM ubuntu:noble
ARG DEBIAN_FRONTEND=noninteractive
@ -7,29 +7,29 @@ RUN apt-get update -y && \
apt install -y apache2 vim software-properties-common sudo nano gnupg2
RUN apt-get install --no-install-recommends -y \
php8.1 \
php8.1-common \
php8.1-gd \
php8.1-zip \
php8.1-curl \
php8.1-xml \
php8.1-xmlrpc \
php8.1-mbstring \
php8.1-sqlite \
php8.1-xdebug \
php8.1-pgsql \
php8.1-intl \
php8.1-imagick \
php8.1-gmp \
php8.1-apcu \
php8.1-bcmath \
php8.1-redis \
php8.1-soap \
php8.1-imap \
php8.1-opcache \
php8.1-cli \
php8.1-dev \
libmagickcore-6.q16-3-extra \
php8.3 \
php8.3-common \
php8.3-gd \
php8.3-zip \
php8.3-curl \
php8.3-xml \
php8.3-xmlrpc \
php8.3-mbstring \
php8.3-sqlite \
php8.3-xdebug \
php8.3-pgsql \
php8.3-intl \
php8.3-imagick \
php8.3-gmp \
php8.3-apcu \
php8.3-bcmath \
php8.3-redis \
php8.3-soap \
php8.3-imap \
php8.3-opcache \
php8.3-cli \
php8.3-dev \
libmagickcore-6.q16-7-extra \
curl \
lsof \
make \
@ -42,15 +42,15 @@ RUN curl -sS https://getcomposer.org/installer -o /tmp/composer-setup.php && \
php /tmp/composer-setup.php --install-dir=/usr/local/bin --filename=composer && \
rm /tmp/composer-setup.php /tmp/composer-setup.sig
RUN echo "xdebug.remote_enable = 1" >> /etc/php/8.1/cli/conf.d/20-xdebug.ini && \
echo "xdebug.remote_autostart = 1" >> /etc/php/8.1/cli/conf.d/20-xdebug.ini && \
echo "apc.enable_cli=1" >> /etc/php/8.1/cli/conf.d/20-apcu.ini
RUN echo "xdebug.remote_enable = 1" >> /etc/php/8.3/cli/conf.d/20-xdebug.ini && \
echo "xdebug.remote_autostart = 1" >> /etc/php/8.3/cli/conf.d/20-xdebug.ini && \
echo "apc.enable_cli=1" >> /etc/php/8.3/cli/conf.d/20-apcu.ini
# Autostart XDebug for apache
RUN { \
echo "xdebug.mode=debug"; \
echo "xdebug.start_with_request=yes"; \
} >> /etc/php/8.1/apache2/conf.d/20-xdebug.ini
} >> /etc/php/8.3/apache2/conf.d/20-xdebug.ini
# Docker
RUN apt-get -y install \

@ -1,3 +1,8 @@
<!--
- 🚨 SECURITY INFO
-
- Before sending a pull request that fixes a security issue please report it via our HackerOne page (https://hackerone.com/nextcloud) following our security policy (https://nextcloud.com/security/). This allows us to coordinate the fix and release without potentially exposing all Nextcloud servers and users in the meantime.
-->
* Resolves: # <!-- related github issue -->

@ -2,6 +2,9 @@
#
# https://github.com/nextcloud/.github
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
#
# SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors
# SPDX-License-Identifier: MIT
name: Dependabot
@ -21,7 +24,7 @@ concurrency:
jobs:
auto-approve-merge:
if: github.actor == 'dependabot[bot]'
if: github.actor == 'dependabot[bot]' || github.actor == 'renovate[bot]'
runs-on: ubuntu-latest-low
permissions:
# for hmarr/auto-approve-action to approve PRs

@ -1,3 +1,11 @@
# This workflow is provided via the organization template repository
#
# https://github.com/nextcloud/.github
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
#
# SPDX-FileCopyrightText: 2023-2024 Nextcloud GmbH and Nextcloud contributors
# SPDX-License-Identifier: MIT
name: Node tests
on:
@ -5,6 +13,9 @@ on:
schedule:
- cron: "5 2 * * *"
permissions:
contents: read
concurrency:
group: node-tests-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
@ -26,18 +37,18 @@ jobs:
- '.github/workflows/**'
- '**/__tests__/**'
- '**/__mocks__/**'
- '**/src/**'
- '**/appinfo/info.xml'
- 'apps/*/src/**'
- 'apps/*/appinfo/info.xml'
- 'core/src/**'
- 'package.json'
- 'package-lock.json'
- 'tsconfig.json'
- '**.js'
- '**.ts'
- '**.vue'
- '**.handlebars'
versions:
runs-on: ubuntu-latest
runs-on: ubuntu-latest-low
needs: changes
if: ${{ github.repository_owner != 'nextcloud-gmbh' && needs.changes.outputs.src != 'false' }}
@ -48,14 +59,14 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
- name: Read package.json node and npm engines version
uses: skjnldsv/read-package-engines-version-actions@8205673bab74a63eb9b8093402fd9e0e018663a1
uses: skjnldsv/read-package-engines-version-actions@06d6baf7d8f41934ab630e97d9e6c0bc9c9ac5e4 # v3
id: versions
with:
fallbackNode: '^20'
fallbackNpm: '^9'
fallbackNpm: '^10'
test:
runs-on: ubuntu-latest
@ -69,27 +80,26 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
- name: Set up node ${{ needs.versions.outputs.nodeVersion }}
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: ${{ needs.versions.outputs.nodeVersion }}
- name: Set up npm ${{ needs.versions.outputs.npmVersion }}
run: npm i -g npm@"${{ needs.versions.outputs.npmVersion }}"
- name: Install dependencies
run: npm ci
- name: Show cypress version
run: npm run cypress:version
- name: Install dependencies & build
run: |
npm ci
npm run build --if-present
- name: Test and process coverage
run: npm run test:coverage
run: npm run test:coverage --if-present
- name: Collect coverage
uses: codecov/codecov-action@c16abc29c95fcf9174b58eb7e1abf4c866893bc8 # v4.1.1
uses: codecov/codecov-action@5ecb98a3c6b747ed38dc09f787459979aebb39be # v4.3.1
with:
files: ./coverage/lcov.info
@ -104,10 +114,10 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
- name: Set up node ${{ needs.versions.outputs.nodeVersion }}
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: ${{ needs.versions.outputs.nodeVersion }}
@ -117,9 +127,6 @@ jobs:
- name: Install dependencies
run: npm ci
- name: Show cypress version
run: npm run cypress:version
- name: Test
run: npm run test:jsunit
@ -135,10 +142,10 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
- name: Set up node ${{ needs.versions.outputs.nodeVersion }}
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: ${{ needs.versions.outputs.nodeVersion }}
@ -148,9 +155,6 @@ jobs:
- name: Install dependencies
run: npm ci
- name: Show cypress version
run: npm run cypress:version
- name: Run compile
run: ./build/compile-handlebars-templates.sh

@ -1,3 +1,15 @@
# This workflow is provided via the organization template repository
#
# https://github.com/nextcloud/.github
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
# SPDX-FileCopyrightText: 2023-2024 Nextcloud GmbH and Nextcloud contributors
# SPDX-FileCopyrightText: 2023 Marcel Klehr <mklehr@gmx.net>
# SPDX-FileCopyrightText: 2023 Joas Schilling <213943+nickvergessen@users.noreply.github.com>
# SPDX-FileCopyrightText: 2023 Daniel Kesselberg <mail@danielkesselberg.de>
# SPDX-FileCopyrightText: 2023 Florian Steffens <florian.steffens@nextcloud.com>
# SPDX-License-Identifier: MIT
name: 'Ask for feedback on PRs'
on:
schedule:
@ -5,25 +17,25 @@ on:
jobs:
pr-feedback:
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
steps:
- name: The get-github-handles-from-website action
uses: marcelklehr/get-github-handles-from-website-action@a739600f6b91da4957f51db0792697afbb2f143c # v1.0.0
id: scrape
with:
website: 'https://nextcloud.com/team/'
- uses: marcelklehr/pr-feedback-action@601109aa729eb4c8d6d0ece7567b9d4901db4aef
- uses: marcelklehr/pr-feedback-action@1883b38a033fb16f576875e0cf45f98b857655c4
with:
feedback-message: |
Hello there,
Thank you so much for taking the time and effort to create a pull request to our Nextcloud project.
We hope that the reviewing process is going smooth and is helpful for you. We want to ensure your pull request is reviewed to your satisfaction. If you have a moment, our community management team would very much appreciate your feedback on your experience with this PR reviewing process.
We hope that the review process is going smooth and is helpful for you. We want to ensure your pull request is reviewed to your satisfaction. If you have a moment, our community management team would very much appreciate your feedback on your experience with this PR review process.
Your feedback is valuable to us as we continuously strive to improve our community developer experience. Please take a moment to complete our short survey by clicking on the following link: https://cloud.nextcloud.com/apps/forms/s/i9Ago4EQRZ7TWxjfmeEpPkf6
Thank you for contributing to Nextcloud and we hope to hear from you soon!
days-before-feedback: 14
start-date: "2023-07-10"
exempt-authors: "${{ steps.scrape.outputs.users }}"
start-date: "2024-04-30"
exempt-authors: "${{ steps.scrape.outputs.users }},nextcloud-command,nextcloud-android-bot,skjnldsv,datenangebot"
exempt-bots: true

@ -102,10 +102,8 @@
# Here are more information about the issue:
# - https://docs.cyberduck.io/mountainduck/issues/fastcgi/
# - https://docs.nextcloud.com/server/latest/admin_manual/issues/general_troubleshooting.html#troubleshooting-webdav
<IfModule setenvif.c>
<Location "/remote.php">
SetEnvIf Transfer-Encoding "chunked" proxy-sendcl=1
</Location>
<IfModule mod_setenvif.c>
SetEnvIf Transfer-Encoding "chunked" proxy-sendcl=1
</IfModule>
AddDefaultCharset utf-8

@ -1 +1 @@
Subproject commit fa5a4a4b221f7176610f523f5fd9145e81885629
Subproject commit cbcfacd52639b3201dd2cf507da3d440ea3344fe

@ -0,0 +1,7 @@
OC.L10N.register(
"admin_audit",
{
"Auditing / Logging" : "Iniúchóireacht / Logáil",
"Provides logging abilities for Nextcloud such as logging file accesses or otherwise sensitive actions." : "Soláthraíonn sé cumais logála do Nextcloud cosúil le logáil isteach rochtain comhaid nó gníomhartha íogaire eile."
},
"nplurals=5; plural=(n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n<11 ? 3 : 4);");

@ -0,0 +1,5 @@
{ "translations": {
"Auditing / Logging" : "Iniúchóireacht / Logáil",
"Provides logging abilities for Nextcloud such as logging file accesses or otherwise sensitive actions." : "Soláthraíonn sé cumais logála do Nextcloud cosúil le logáil isteach rochtain comhaid nó gníomhartha íogaire eile."
},"pluralForm" :"nplurals=5; plural=(n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n<11 ? 3 : 4);"
}

@ -27,6 +27,18 @@ declare(strict_types=1);
*/
namespace OCA\AdminAudit\Actions;
use OCP\Files\Events\Node\BeforeNodeReadEvent;
use OCP\Files\Events\Node\BeforeNodeWrittenEvent;
use OCP\Files\Events\Node\NodeCopiedEvent;
use OCP\Files\Events\Node\NodeCreatedEvent;
use OCP\Files\Events\Node\NodeDeletedEvent;
use OCP\Files\Events\Node\NodeRenamedEvent;
use OCP\Files\Events\Node\NodeWrittenEvent;
use OCP\Files\InvalidPathException;
use OCP\Files\NotFoundException;
use OCP\Preview\BeforePreviewFetchedEvent;
use Psr\Log\LoggerInterface;
/**
* Class Files logs the actions to files
*
@ -36,134 +48,210 @@ class Files extends Action {
/**
* Logs file read actions
*
* @param array $params
* @param BeforeNodeReadEvent $event
*/
public function read(array $params): void {
public function read(BeforeNodeReadEvent $event): void {
try {
$params = [
'id' => $event->getNode()->getId(),
'path' => mb_substr($event->getNode()->getInternalPath(), 5),
];
} catch (InvalidPathException|NotFoundException $e) {
\OCP\Server::get(LoggerInterface::class)->error(
"Exception thrown in file read: ".$e->getMessage(), ['app' => 'admin_audit', 'exception' => $e]
);
return;
}
$this->log(
'File accessed: "%s"',
'File with id "%s" accessed: "%s"',
$params,
[
'path',
]
array_keys($params)
);
}
/**
* Logs rename actions of files
*
* @param array $params
* @param NodeRenamedEvent $event
*/
public function rename(array $params): void {
public function rename(NodeRenamedEvent $event): void {
try {
$source = $event->getSource();
$target = $event->getTarget();
$params = [
'newid' => $target->getId(),
'oldpath' => mb_substr($source->getPath(), 5),
'newpath' => mb_substr($target->getPath(), 5),
];
} catch (InvalidPathException|NotFoundException $e) {
\OCP\Server::get(LoggerInterface::class)->error(
"Exception thrown in file rename: ".$e->getMessage(), ['app' => 'admin_audit', 'exception' => $e]
);
return;
}
$this->log(
'File renamed: "%s" to "%s"',
'File renamed with id "%s" from "%s" to "%s"',
$params,
[
'oldpath',
'newpath',
]
array_keys($params)
);
}
/**
* Logs creation of files
*
* @param array $params
* @param NodeCreatedEvent $event
*/
public function create(array $params): void {
if ($params['path'] === '/' || $params['path'] === '' || $params['path'] === null) {
public function create(NodeCreatedEvent $event): void {
try {
$params = [
'id' => $event->getNode()->getId(),
'path' => mb_substr($event->getNode()->getInternalPath(), 5),
];
} catch (InvalidPathException|NotFoundException $e) {
\OCP\Server::get(LoggerInterface::class)->error(
"Exception thrown in file create: ".$e->getMessage(), ['app' => 'admin_audit', 'exception' => $e]
);
return;
}
if ($params['path'] === '/' || $params['path'] === '') {
return;
}
$this->log(
'File created: "%s"',
'File with id "%s" created: "%s"',
$params,
[
'path',
]
array_keys($params)
);
}
/**
* Logs copying of files
*
* @param array $params
* @param NodeCopiedEvent $event
*/
public function copy(array $params): void {
public function copy(NodeCopiedEvent $event): void {
try {
$params = [
'oldid' => $event->getSource()->getId(),
'newid' => $event->getTarget()->getId(),
'oldpath' => mb_substr($event->getSource()->getInternalPath(), 5),
'newpath' => mb_substr($event->getTarget()->getInternalPath(), 5),
];
} catch (InvalidPathException|NotFoundException $e) {
\OCP\Server::get(LoggerInterface::class)->error(
"Exception thrown in file copy: ".$e->getMessage(), ['app' => 'admin_audit', 'exception' => $e]
);
return;
}
$this->log(
'File copied: "%s" to "%s"',
'File id copied from: "%s" to "%s", path from "%s" to "%s"',
$params,
[
'oldpath',
'newpath',
]
array_keys($params)
);
}
/**
* Logs writing of files
*
* @param array $params
* @param BeforeNodeWrittenEvent $event
*/
public function write(array $params): void {
if ($params['path'] === '/' || $params['path'] === '' || $params['path'] === null) {
public function write(BeforeNodeWrittenEvent $event): void {
try {
$params = [
'id' => $event->getNode()->getId(),
'path' => mb_substr($event->getNode()->getInternalPath(), 5),
];
} catch (InvalidPathException|NotFoundException $e) {
\OCP\Server::get(LoggerInterface::class)->error(
"Exception thrown in file write: ".$e->getMessage(), ['app' => 'admin_audit', 'exception' => $e]
);
return;
}
if ($params['path'] === '/' || $params['path'] === '') {
return;
}
$this->log(
'File written to: "%s"',
'File with id "%s" written to: "%s"',
$params,
[
'path',
]
array_keys($params)
);
}
/**
* Logs update of files
*
* @param array $params
* @param NodeWrittenEvent $event
*/
public function update(array $params): void {
public function update(NodeWrittenEvent $event): void {
try {
$params = [
'id' => $event->getNode()->getId(),
'path' => mb_substr($event->getNode()->getInternalPath(), 5),
];
} catch (InvalidPathException|NotFoundException $e) {
\OCP\Server::get(LoggerInterface::class)->error(
"Exception thrown in file update: ".$e->getMessage(), ['app' => 'admin_audit', 'exception' => $e]
);
return;
}
$this->log(
'File updated: "%s"',
'File with id "%s" updated: "%s"',
$params,
[
'path',
]
array_keys($params)
);
}
/**
* Logs deletions of files
*
* @param array $params
* @param NodeDeletedEvent $event
*/
public function delete(array $params): void {
public function delete(NodeDeletedEvent $event): void {
try {
$params = [
'id' => $event->getNode()->getId(),
'path' => mb_substr($event->getNode()->getInternalPath(), 5),
];
} catch (InvalidPathException|NotFoundException $e) {
\OCP\Server::get(LoggerInterface::class)->error(
"Exception thrown in file delete: ".$e->getMessage(), ['app' => 'admin_audit', 'exception' => $e]
);
return;
}
$this->log(
'File deleted: "%s"',
'File with id "%s" deleted: "%s"',
$params,
[
'path',
]
array_keys($params)
);
}
/**
* Logs preview access to a file
*
* @param array $params
* @param BeforePreviewFetchedEvent $event
*/
public function preview(array $params): void {
public function preview(BeforePreviewFetchedEvent $event): void {
try {
$file = $event->getNode();
$params = [
'id' => $file->getId(),
'width' => $event->getWidth(),
'height' => $event->getHeight(),
'crop' => $event->isCrop(),
'mode' => $event->getMode(),
'path' => mb_substr($file->getInternalPath(), 5)
];
} catch (InvalidPathException|NotFoundException $e) {
\OCP\Server::get(LoggerInterface::class)->error(
"Exception thrown in file preview: ".$e->getMessage(), ['app' => 'admin_audit', 'exception' => $e]
);
return;
}
$this->log(
'Preview accessed: "%s" (width: "%s", height: "%s" crop: "%s", mode: "%s")',
'Preview accessed: (id: "%s", width: "%s", height: "%s" crop: "%s", mode: "%s", path: "%s")',
$params,
[
'path',
'width',
'height',
'crop',
'mode'
]
array_keys($params)
);
}
}

@ -33,7 +33,6 @@ declare(strict_types=1);
*/
namespace OCA\AdminAudit\AppInfo;
use OC\Files\Filesystem;
use OC\Group\Manager as GroupManager;
use OC\User\Session as UserSession;
use OCA\AdminAudit\Actions\AppManagement;
@ -58,6 +57,13 @@ use OCP\Authentication\TwoFactorAuth\TwoFactorProviderChallengeFailed;
use OCP\Authentication\TwoFactorAuth\TwoFactorProviderChallengePassed;
use OCP\Console\ConsoleEvent;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\Events\Node\BeforeNodeReadEvent;
use OCP\Files\Events\Node\BeforeNodeWrittenEvent;
use OCP\Files\Events\Node\NodeCopiedEvent;
use OCP\Files\Events\Node\NodeCreatedEvent;
use OCP\Files\Events\Node\NodeDeletedEvent;
use OCP\Files\Events\Node\NodeRenamedEvent;
use OCP\Files\Events\Node\NodeWrittenEvent;
use OCP\IConfig;
use OCP\IGroupManager;
use OCP\IUserSession;
@ -195,58 +201,57 @@ class Application extends App implements IBootstrap {
$eventDispatcher->addListener(
BeforePreviewFetchedEvent::class,
function (BeforePreviewFetchedEvent $event) use ($fileActions) {
$file = $event->getNode();
$fileActions->preview([
'path' => mb_substr($file->getInternalPath(), 5),
'width' => $event->getWidth(),
'height' => $event->getHeight(),
'crop' => $event->isCrop(),
'mode' => $event->getMode()
]);
$fileActions->preview($event);
}
);
Util::connectHook(
Filesystem::CLASSNAME,
Filesystem::signal_post_rename,
$fileActions,
'rename'
$eventDispatcher->addListener(
NodeRenamedEvent::class,
function (NodeRenamedEvent $event) use ($fileActions) {
$fileActions->rename($event);
}
);
Util::connectHook(
Filesystem::CLASSNAME,
Filesystem::signal_post_create,
$fileActions,
'create'
$eventDispatcher->addListener(
NodeCreatedEvent::class,
function (NodeCreatedEvent $event) use ($fileActions) {
$fileActions->create($event);
}
);
Util::connectHook(
Filesystem::CLASSNAME,
Filesystem::signal_post_copy,
$fileActions,
'copy'
$eventDispatcher->addListener(
NodeCopiedEvent::class,
function (NodeCopiedEvent $event) use ($fileActions) {
$fileActions->copy($event);
}
);
Util::connectHook(
Filesystem::CLASSNAME,
Filesystem::signal_post_write,
$fileActions,
'write'
$eventDispatcher->addListener(
BeforeNodeWrittenEvent::class,
function (BeforeNodeWrittenEvent $event) use ($fileActions) {
$fileActions->write($event);
}
);
Util::connectHook(
Filesystem::CLASSNAME,
Filesystem::signal_post_update,
$fileActions,
'update'
$eventDispatcher->addListener(
NodeWrittenEvent::class,
function (NodeWrittenEvent $event) use ($fileActions) {
$fileActions->update($event);
}
);
Util::connectHook(
Filesystem::CLASSNAME,
Filesystem::signal_read,
$fileActions,
'read'
$eventDispatcher->addListener(
BeforeNodeReadEvent::class,
function (BeforeNodeReadEvent $event) use ($fileActions) {
$fileActions->read($event);
}
);
Util::connectHook(
Filesystem::CLASSNAME,
Filesystem::signal_delete,
$fileActions,
'delete'
$eventDispatcher->addListener(
NodeDeletedEvent::class,
function (NodeDeletedEvent $event) use ($fileActions) {
$fileActions->delete($event);
}
);
}

@ -0,0 +1,39 @@
OC.L10N.register(
"comments",
{
"Comments" : "Tuairimí",
"You commented" : "Rinne tú trácht",
"{author} commented" : "Rinne {author} nóta tráchta",
"You commented on %1$s" : "Rinne tú trácht ar%1$s",
"You commented on {file}" : "Rinne tú trácht ar {file}",
"%1$s commented on %2$s" : "%1$s trácht ar %2$s",
"{author} commented on {file}" : "{author} trácht ar {file}",
"<strong>Comments</strong> for files" : "<strong>Tuairimí</strong> le haghaidh comhaid",
"You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Luadh thú ar \"{file}\", i nóta tráchta ó chuntas a scriosadh ó shin",
"{user} mentioned you in a comment on \"{file}\"" : "Luaigh {úsáideoir} tú i nóta tráchta ar \"{file}\"",
"Files app plugin to add comments to files" : "Breiseán aip Comhaid chun tuairimí a chur le comhaid",
"Edit comment" : "Cuir trácht in eagar",
"Delete comment" : "Scrios nóta tráchta",
"Cancel edit" : "Cealaigh eagarthóireacht",
"New comment" : "Trácht nua",
"Write a comment …" : "Scríobh trácht…",
"Post comment" : "Post trácht",
"@ for mentions, : for emoji, / for smart picker" : "@ le haghaidh tagairtí, : le haghaidh emoji, / le haghaidh roghnóir cliste",
"Could not reload comments" : "Níorbh fhéidir na nótaí tráchta a athlódáil",
"No comments yet, start the conversation!" : "Gan trácht ar bith go fóill, cuir tús leis an gcomhrá!",
"No more messages" : "Níl a thuilleadh teachtaireachtaí",
"Retry" : "Bain triail eile as",
"Failed to mark comments as read" : "Theip ar nótaí tráchta a mharcáil mar léite",
"Unable to load the comments list" : "Ní féidir an liosta tuairimí a lódáil",
"_1 new comment_::_{unread} new comments_" : ["1 trácht nua","{unread} nóta tráchta nua","{unread} nóta tráchta nua","{unread} nóta tráchta nua","{unread} nóta tráchta nua"],
"Comment" : "Trácht",
"An error occurred while trying to edit the comment" : "Tharla earráid agus an nóta tráchta á chur in eagar",
"Comment deleted" : "Trácht scriosta",
"An error occurred while trying to delete the comment" : "Tharla earráid agus an nóta tráchta á scriosadh",
"An error occurred while trying to create the comment" : "Tharla earráid agus an nóta tráchta á chruthú",
"You were mentioned on \"{file}\", in a comment by a user that has since been deleted" : "Luadh thú ar \"{file}\", i nóta tráchta ó úsáideoir atá scriosta ó shin",
"Write a message …" : "Scríobh teachtaireacht…",
"\"@\" for mentions, \":\" for emoji, \"/\" for smart picker" : "\"@\" le haghaidh tagairtí, \":\" le haghaidh emoji, \"/\" don roghnóir cliste",
"_%n unread comment_::_%n unread comments_" : ["%n trácht gan léamh","%n tuairimí neamhléite","%n tuairimí neamhléite","%n tuairimí neamhléite","%n tuairimí neamhléite"]
},
"nplurals=5; plural=(n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n<11 ? 3 : 4);");

@ -0,0 +1,37 @@
{ "translations": {
"Comments" : "Tuairimí",
"You commented" : "Rinne tú trácht",
"{author} commented" : "Rinne {author} nóta tráchta",
"You commented on %1$s" : "Rinne tú trácht ar%1$s",
"You commented on {file}" : "Rinne tú trácht ar {file}",
"%1$s commented on %2$s" : "%1$s trácht ar %2$s",
"{author} commented on {file}" : "{author} trácht ar {file}",
"<strong>Comments</strong> for files" : "<strong>Tuairimí</strong> le haghaidh comhaid",
"You were mentioned on \"{file}\", in a comment by an account that has since been deleted" : "Luadh thú ar \"{file}\", i nóta tráchta ó chuntas a scriosadh ó shin",
"{user} mentioned you in a comment on \"{file}\"" : "Luaigh {úsáideoir} tú i nóta tráchta ar \"{file}\"",
"Files app plugin to add comments to files" : "Breiseán aip Comhaid chun tuairimí a chur le comhaid",
"Edit comment" : "Cuir trácht in eagar",
"Delete comment" : "Scrios nóta tráchta",
"Cancel edit" : "Cealaigh eagarthóireacht",
"New comment" : "Trácht nua",
"Write a comment …" : "Scríobh trácht…",
"Post comment" : "Post trácht",
"@ for mentions, : for emoji, / for smart picker" : "@ le haghaidh tagairtí, : le haghaidh emoji, / le haghaidh roghnóir cliste",
"Could not reload comments" : "Níorbh fhéidir na nótaí tráchta a athlódáil",
"No comments yet, start the conversation!" : "Gan trácht ar bith go fóill, cuir tús leis an gcomhrá!",
"No more messages" : "Níl a thuilleadh teachtaireachtaí",
"Retry" : "Bain triail eile as",
"Failed to mark comments as read" : "Theip ar nótaí tráchta a mharcáil mar léite",
"Unable to load the comments list" : "Ní féidir an liosta tuairimí a lódáil",
"_1 new comment_::_{unread} new comments_" : ["1 trácht nua","{unread} nóta tráchta nua","{unread} nóta tráchta nua","{unread} nóta tráchta nua","{unread} nóta tráchta nua"],
"Comment" : "Trácht",
"An error occurred while trying to edit the comment" : "Tharla earráid agus an nóta tráchta á chur in eagar",
"Comment deleted" : "Trácht scriosta",
"An error occurred while trying to delete the comment" : "Tharla earráid agus an nóta tráchta á scriosadh",
"An error occurred while trying to create the comment" : "Tharla earráid agus an nóta tráchta á chruthú",
"You were mentioned on \"{file}\", in a comment by a user that has since been deleted" : "Luadh thú ar \"{file}\", i nóta tráchta ó úsáideoir atá scriosta ó shin",
"Write a message …" : "Scríobh teachtaireacht…",
"\"@\" for mentions, \":\" for emoji, \"/\" for smart picker" : "\"@\" le haghaidh tagairtí, \":\" le haghaidh emoji, \"/\" don roghnóir cliste",
"_%n unread comment_::_%n unread comments_" : ["%n trácht gan léamh","%n tuairimí neamhléite","%n tuairimí neamhléite","%n tuairimí neamhléite","%n tuairimí neamhléite"]
},"pluralForm" :"nplurals=5; plural=(n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n<11 ? 3 : 4);"
}

@ -16,7 +16,7 @@ OC.L10N.register(
"Delete comment" : "Eliminar comentario",
"Cancel edit" : "Cancelar a edición",
"New comment" : "Comentario novo",
"Write a comment …" : "Escribe un comentario …",
"Write a comment …" : "Escriba un comentario…",
"Post comment" : "Publicar comentario",
"@ for mentions, : for emoji, / for smart picker" : "@ para mencións, : para «emoji», / para selector intelixente",
"Could not reload comments" : "Non foi posíbel volver cargar os comentarios",
@ -32,7 +32,7 @@ OC.L10N.register(
"An error occurred while trying to delete the comment" : "Produciuse un erro cando tentaba eliminar o comentario",
"An error occurred while trying to create the comment" : "Produciuse un erro cando tentaba crear o comentario",
"You were mentioned on \"{file}\", in a comment by a user that has since been deleted" : "Mencionárono en «{file}», nun comentario dun usuario que xa foi eliminado",
"Write a message …" : "Escribe unha mensaxe ...",
"Write a message …" : "Escriba unha mensaxe…",
"\"@\" for mentions, \":\" for emoji, \"/\" for smart picker" : "«@» para mencións, «:» para «emoji», «/» para selector intelixente",
"_%n unread comment_::_%n unread comments_" : ["%n comentario sen ler","%n comentarios sen ler"]
},

@ -14,7 +14,7 @@
"Delete comment" : "Eliminar comentario",
"Cancel edit" : "Cancelar a edición",
"New comment" : "Comentario novo",
"Write a comment …" : "Escribe un comentario …",
"Write a comment …" : "Escriba un comentario…",
"Post comment" : "Publicar comentario",
"@ for mentions, : for emoji, / for smart picker" : "@ para mencións, : para «emoji», / para selector intelixente",
"Could not reload comments" : "Non foi posíbel volver cargar os comentarios",
@ -30,7 +30,7 @@
"An error occurred while trying to delete the comment" : "Produciuse un erro cando tentaba eliminar o comentario",
"An error occurred while trying to create the comment" : "Produciuse un erro cando tentaba crear o comentario",
"You were mentioned on \"{file}\", in a comment by a user that has since been deleted" : "Mencionárono en «{file}», nun comentario dun usuario que xa foi eliminado",
"Write a message …" : "Escribe unha mensaxe ...",
"Write a message …" : "Escriba unha mensaxe…",
"\"@\" for mentions, \":\" for emoji, \"/\" for smart picker" : "«@» para mencións, «:» para «emoji», «/» para selector intelixente",
"_%n unread comment_::_%n unread comments_" : ["%n comentario sen ler","%n comentarios sen ler"]
},"pluralForm" :"nplurals=2; plural=(n != 1);"

@ -18,7 +18,7 @@ OC.L10N.register(
"New comment" : "Новий коментар",
"Write a comment …" : "Додати коментар ...",
"Post comment" : "Опублікувати коментар",
"@ for mentions, : for emoji, / for smart picker" : "@ for згадування, : для емоційок, / для асистента з вибору",
"@ for mentions, : for emoji, / for smart picker" : "@ згадати, : емоційки, / асистент вибору",
"Could not reload comments" : "Не вдалося перезавантажити коментарі",
"No comments yet, start the conversation!" : "Тут можна додати коментарі",
"No more messages" : "Більше жодних повідомлень",
@ -33,7 +33,7 @@ OC.L10N.register(
"An error occurred while trying to create the comment" : "Під час створення коментаря сталася помилка",
"You were mentioned on \"{file}\", in a comment by a user that has since been deleted" : "Вас згадали в \"{file}\" у коментарі користувача, який згодом було вилучено",
"Write a message …" : "Написати повідомлення ...",
"\"@\" for mentions, \":\" for emoji, \"/\" for smart picker" : "\"@\" для згадок, \":\" для емоційок, \"/\" для асистента",
"\"@\" for mentions, \":\" for emoji, \"/\" for smart picker" : "\"@\" згадати, \":\" емоційки, \"/\" асистент вибору",
"_%n unread comment_::_%n unread comments_" : ["%n непрочитаний коментар","%n непрочитаних коментарів","%n непрочитаних коментарів","%n непрочитаних коментарів"]
},
"nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != 11 ? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || (n % 100 >=11 && n % 100 <=14 )) ? 2: 3);");

@ -16,7 +16,7 @@
"New comment" : "Новий коментар",
"Write a comment …" : "Додати коментар ...",
"Post comment" : "Опублікувати коментар",
"@ for mentions, : for emoji, / for smart picker" : "@ for згадування, : для емоційок, / для асистента з вибору",
"@ for mentions, : for emoji, / for smart picker" : "@ згадати, : емоційки, / асистент вибору",
"Could not reload comments" : "Не вдалося перезавантажити коментарі",
"No comments yet, start the conversation!" : "Тут можна додати коментарі",
"No more messages" : "Більше жодних повідомлень",
@ -31,7 +31,7 @@
"An error occurred while trying to create the comment" : "Під час створення коментаря сталася помилка",
"You were mentioned on \"{file}\", in a comment by a user that has since been deleted" : "Вас згадали в \"{file}\" у коментарі користувача, який згодом було вилучено",
"Write a message …" : "Написати повідомлення ...",
"\"@\" for mentions, \":\" for emoji, \"/\" for smart picker" : "\"@\" для згадок, \":\" для емоційок, \"/\" для асистента",
"\"@\" for mentions, \":\" for emoji, \"/\" for smart picker" : "\"@\" згадати, \":\" емоційки, \"/\" асистент вибору",
"_%n unread comment_::_%n unread comments_" : ["%n непрочитаний коментар","%n непрочитаних коментарів","%n непрочитаних коментарів","%n непрочитаних коментарів"]
},"pluralForm" :"nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != 11 ? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || (n % 100 >=11 && n % 100 <=14 )) ? 2: 3);"
}

@ -3,6 +3,8 @@ OC.L10N.register(
{
"Recently contacted" : "Ostatnio skontaktowano się",
"Contacts Interaction" : "Interakcja kontaktów",
"Manages interaction between accounts and contacts" : "Zarządza interakcją pomiędzy kontami i kontaktami",
"Collect data about accounts and contacts interactions and provide an address book for the data" : "Zbieraj dane o kontach i interakcjach kontaktów oraz udostępniaj książkę adresową dla danych",
"Manages interaction between users and contacts" : "Zarządza interakcją między użytkownikami i kontaktami",
"Collect data about user and contacts interactions and provide an address book for the data" : "Zbieraj dane o interakcjach użytkowników i kontaktów oraz udostępniaj książkę adresową dla tych danych."
},

@ -1,6 +1,8 @@
{ "translations": {
"Recently contacted" : "Ostatnio skontaktowano się",
"Contacts Interaction" : "Interakcja kontaktów",
"Manages interaction between accounts and contacts" : "Zarządza interakcją pomiędzy kontami i kontaktami",
"Collect data about accounts and contacts interactions and provide an address book for the data" : "Zbieraj dane o kontach i interakcjach kontaktów oraz udostępniaj książkę adresową dla danych",
"Manages interaction between users and contacts" : "Zarządza interakcją między użytkownikami i kontaktami",
"Collect data about user and contacts interactions and provide an address book for the data" : "Zbieraj dane o interakcjach użytkowników i kontaktów oraz udostępniaj książkę adresową dla tych danych."
},"pluralForm" :"nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);"

@ -3,7 +3,7 @@ OC.L10N.register(
{
"Dashboard" : "Tableau de bord",
"Dashboard app" : "App Tableau de bord",
"Start your day informed\n\nThe Nextcloud Dashboard is your starting point of the day, giving you an overview of your upcoming appointments, urgent emails, chat messages, incoming tickets, latest tweets and much more! People can add the widgets they like and change the background to their liking." : "Commencez votre journée en étant informé\n\nLe tableau de bord Nextcloud est votre point de départ de la journée, vous donnant un aperçu de vos rendez-vous à venir, des courriels urgents, des messages de discussion, des tickets entrants, des derniers tweets et bien plus encore ! Les personnes peuvent ajouter les widgets quils souhaitent et changer larrière-plan à leur guise.",
"Start your day informed\n\nThe Nextcloud Dashboard is your starting point of the day, giving you an overview of your upcoming appointments, urgent emails, chat messages, incoming tickets, latest tweets and much more! People can add the widgets they like and change the background to their liking." : "Commencez votre journée en étant informé\n\nLe tableau de bord Nextcloud est votre point de départ de la journée, vous donnant un aperçu de vos rendez-vous à venir, des e-mails urgents, des messages de discussion, des tickets entrants, des derniers tweets et bien plus encore ! Les personnes peuvent ajouter les widgets quils souhaitent et changer larrière-plan à leur guise.",
"\"{title} icon\"" :  Icône {title} »",
"Customize" : "Personnaliser",
"Edit widgets" : "Modifier les widgets",
@ -23,6 +23,6 @@ OC.L10N.register(
"Good evening, {name}" : "Bonsoir {name}",
"Hello" : "Bonjour",
"Hello, {name}" : "Bonjour {name}",
"Start your day informed\n\nThe Nextcloud Dashboard is your starting point of the day, giving you an overview of your upcoming appointments, urgent emails, chat messages, incoming tickets, latest tweets and much more! Users can add the widgets they like and change the background to their liking." : "Commencez votre journée en étant informé\n\nLe tableau de bord Nextcloud est votre point de départ de la journée, vous donnant un aperçu de vos rendez-vous à venir, des courriels urgents, des messages de discussion, des tickets entrants, des derniers tweets et bien plus encore ! Les utilisateurs peuvent ajouter les widgets quils souhaitent et changer larrière-plan à leur guise."
"Start your day informed\n\nThe Nextcloud Dashboard is your starting point of the day, giving you an overview of your upcoming appointments, urgent emails, chat messages, incoming tickets, latest tweets and much more! Users can add the widgets they like and change the background to their liking." : "Commencez votre journée en étant informé\n\nLe tableau de bord Nextcloud est votre point de départ de la journée, vous donnant un aperçu de vos rendez-vous à venir, des e-mails urgents, des messages de discussion, des tickets entrants, des derniers tweets et bien plus encore ! Les utilisateurs peuvent ajouter les widgets quils souhaitent et changer larrière-plan à leur guise."
},
"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");

@ -1,7 +1,7 @@
{ "translations": {
"Dashboard" : "Tableau de bord",
"Dashboard app" : "App Tableau de bord",
"Start your day informed\n\nThe Nextcloud Dashboard is your starting point of the day, giving you an overview of your upcoming appointments, urgent emails, chat messages, incoming tickets, latest tweets and much more! People can add the widgets they like and change the background to their liking." : "Commencez votre journée en étant informé\n\nLe tableau de bord Nextcloud est votre point de départ de la journée, vous donnant un aperçu de vos rendez-vous à venir, des courriels urgents, des messages de discussion, des tickets entrants, des derniers tweets et bien plus encore ! Les personnes peuvent ajouter les widgets quils souhaitent et changer larrière-plan à leur guise.",
"Start your day informed\n\nThe Nextcloud Dashboard is your starting point of the day, giving you an overview of your upcoming appointments, urgent emails, chat messages, incoming tickets, latest tweets and much more! People can add the widgets they like and change the background to their liking." : "Commencez votre journée en étant informé\n\nLe tableau de bord Nextcloud est votre point de départ de la journée, vous donnant un aperçu de vos rendez-vous à venir, des e-mails urgents, des messages de discussion, des tickets entrants, des derniers tweets et bien plus encore ! Les personnes peuvent ajouter les widgets quils souhaitent et changer larrière-plan à leur guise.",
"\"{title} icon\"" :  Icône {title} »",
"Customize" : "Personnaliser",
"Edit widgets" : "Modifier les widgets",
@ -21,6 +21,6 @@
"Good evening, {name}" : "Bonsoir {name}",
"Hello" : "Bonjour",
"Hello, {name}" : "Bonjour {name}",
"Start your day informed\n\nThe Nextcloud Dashboard is your starting point of the day, giving you an overview of your upcoming appointments, urgent emails, chat messages, incoming tickets, latest tweets and much more! Users can add the widgets they like and change the background to their liking." : "Commencez votre journée en étant informé\n\nLe tableau de bord Nextcloud est votre point de départ de la journée, vous donnant un aperçu de vos rendez-vous à venir, des courriels urgents, des messages de discussion, des tickets entrants, des derniers tweets et bien plus encore ! Les utilisateurs peuvent ajouter les widgets quils souhaitent et changer larrière-plan à leur guise."
"Start your day informed\n\nThe Nextcloud Dashboard is your starting point of the day, giving you an overview of your upcoming appointments, urgent emails, chat messages, incoming tickets, latest tweets and much more! Users can add the widgets they like and change the background to their liking." : "Commencez votre journée en étant informé\n\nLe tableau de bord Nextcloud est votre point de départ de la journée, vous donnant un aperçu de vos rendez-vous à venir, des e-mails urgents, des messages de discussion, des tickets entrants, des derniers tweets et bien plus encore ! Les utilisateurs peuvent ajouter les widgets quils souhaitent et changer larrière-plan à leur guise."
},"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
}

@ -46,7 +46,9 @@ return array(
'OCA\\DAV\\CalDAV\\BirthdayCalendar\\EnablePlugin' => $baseDir . '/../lib/CalDAV/BirthdayCalendar/EnablePlugin.php',
'OCA\\DAV\\CalDAV\\BirthdayService' => $baseDir . '/../lib/CalDAV/BirthdayService.php',
'OCA\\DAV\\CalDAV\\CachedSubscription' => $baseDir . '/../lib/CalDAV/CachedSubscription.php',
'OCA\\DAV\\CalDAV\\CachedSubscriptionImpl' => $baseDir . '/../lib/CalDAV/CachedSubscriptionImpl.php',
'OCA\\DAV\\CalDAV\\CachedSubscriptionObject' => $baseDir . '/../lib/CalDAV/CachedSubscriptionObject.php',
'OCA\\DAV\\CalDAV\\CachedSubscriptionProvider' => $baseDir . '/../lib/CalDAV/CachedSubscriptionProvider.php',
'OCA\\DAV\\CalDAV\\CalDavBackend' => $baseDir . '/../lib/CalDAV/CalDavBackend.php',
'OCA\\DAV\\CalDAV\\Calendar' => $baseDir . '/../lib/CalDAV/Calendar.php',
'OCA\\DAV\\CalDAV\\CalendarHome' => $baseDir . '/../lib/CalDAV/CalendarHome.php',

@ -61,7 +61,9 @@ class ComposerStaticInitDAV
'OCA\\DAV\\CalDAV\\BirthdayCalendar\\EnablePlugin' => __DIR__ . '/..' . '/../lib/CalDAV/BirthdayCalendar/EnablePlugin.php',
'OCA\\DAV\\CalDAV\\BirthdayService' => __DIR__ . '/..' . '/../lib/CalDAV/BirthdayService.php',
'OCA\\DAV\\CalDAV\\CachedSubscription' => __DIR__ . '/..' . '/../lib/CalDAV/CachedSubscription.php',
'OCA\\DAV\\CalDAV\\CachedSubscriptionImpl' => __DIR__ . '/..' . '/../lib/CalDAV/CachedSubscriptionImpl.php',
'OCA\\DAV\\CalDAV\\CachedSubscriptionObject' => __DIR__ . '/..' . '/../lib/CalDAV/CachedSubscriptionObject.php',
'OCA\\DAV\\CalDAV\\CachedSubscriptionProvider' => __DIR__ . '/..' . '/../lib/CalDAV/CachedSubscriptionProvider.php',
'OCA\\DAV\\CalDAV\\CalDavBackend' => __DIR__ . '/..' . '/../lib/CalDAV/CalDavBackend.php',
'OCA\\DAV\\CalDAV\\Calendar' => __DIR__ . '/..' . '/../lib/CalDAV/Calendar.php',
'OCA\\DAV\\CalDAV\\CalendarHome' => __DIR__ . '/..' . '/../lib/CalDAV/CalendarHome.php',

@ -87,10 +87,10 @@ OC.L10N.register(
"Attendees:" : "Participants :",
"Title:" : "Titre :",
"Time:" : "Heure :",
"Location:" : "Localisation :",
"Location:" : "Lieu :",
"Link:" : "Lien :",
"Accept" : "Accepter",
"Decline" : "Refuser",
"Decline" : "Décliner",
"More options …" : "Plus d'options…",
"More options at %s" : "Plus d'options à %s",
"Contacts" : "Contacts",

@ -85,10 +85,10 @@
"Attendees:" : "Participants :",
"Title:" : "Titre :",
"Time:" : "Heure :",
"Location:" : "Localisation :",
"Location:" : "Lieu :",
"Link:" : "Lien :",
"Accept" : "Accepter",
"Decline" : "Refuser",
"Decline" : "Décliner",
"More options …" : "Plus d'options…",
"More options at %s" : "Plus d'options à %s",
"Contacts" : "Contacts",

@ -173,7 +173,7 @@ OC.L10N.register(
"Delete slot" : "Eliminar franxa horaria",
"No working hours set" : "Sen horario de traballo estabelecido",
"Add slot" : "Engadir franxa horaria",
"Weekdays" : "Días laborables",
"Weekdays" : "Días laborábeis",
"Monday" : "luns",
"Tuesday" : "martes",
"Wednesday" : "mércores",

@ -171,7 +171,7 @@
"Delete slot" : "Eliminar franxa horaria",
"No working hours set" : "Sen horario de traballo estabelecido",
"Add slot" : "Engadir franxa horaria",
"Weekdays" : "Días laborables",
"Weekdays" : "Días laborábeis",
"Monday" : "luns",
"Tuesday" : "martes",
"Wednesday" : "mércores",

@ -171,6 +171,7 @@ OC.L10N.register(
"Delete slot" : "Elimina slot",
"No working hours set" : "Orari lavorativi non impostati",
"Add slot" : "Aggiungi slot",
"Weekdays" : "Giorni feriali",
"Monday" : "Lunedì",
"Tuesday" : "Martedì",
"Wednesday" : "Mercoledì",

@ -169,6 +169,7 @@
"Delete slot" : "Elimina slot",
"No working hours set" : "Orari lavorativi non impostati",
"Add slot" : "Aggiungi slot",
"Weekdays" : "Giorni feriali",
"Monday" : "Lunedì",
"Tuesday" : "Martedì",
"Wednesday" : "Mercoledì",

@ -34,6 +34,7 @@ namespace OCA\DAV\AppInfo;
use OCA\DAV\CalDAV\Activity\Backend;
use OCA\DAV\CalDAV\AppCalendar\AppCalendarPlugin;
use OCA\DAV\CalDAV\CachedSubscriptionProvider;
use OCA\DAV\CalDAV\CalendarManager;
use OCA\DAV\CalDAV\CalendarProvider;
use OCA\DAV\CalDAV\Reminder\NotificationProvider\AudioProvider;
@ -207,6 +208,7 @@ class Application extends App implements IBootstrap {
$context->registerNotifierService(Notifier::class);
$context->registerCalendarProvider(CalendarProvider::class);
$context->registerCalendarProvider(CachedSubscriptionProvider::class);
$context->registerUserMigrator(CalendarMigrator::class);
$context->registerUserMigrator(ContactsMigrator::class);

@ -68,7 +68,7 @@ class AppCalendarPlugin implements ICalendarProvider {
return array_values(
array_filter($this->manager->getCalendarsForPrincipal($principalUri, $calendarUris), function ($c) {
// We must not provide a wrapper for DAV calendars
return ! ($c instanceof \OCA\DAV\CalDAV\CalendarImpl);
return ! (($c instanceof \OCA\DAV\CalDAV\CalendarImpl) || ($c instanceof \OCA\DAV\CalDAV\CachedSubscriptionImpl));
})
);
}

@ -73,6 +73,11 @@ class CachedSubscription extends \Sabre\CalDAV\Calendar {
'principal' => '{DAV:}authenticated',
'protected' => true,
],
[
'privilege' => '{DAV:}write-properties',
'principal' => $this->getOwner(),
'protected' => true,
]
];
}
@ -97,7 +102,6 @@ class CachedSubscription extends \Sabre\CalDAV\Calendar {
'principal' => $this->getOwner() . '/calendar-proxy-read',
'protected' => true,
],
];
}

@ -0,0 +1,117 @@
<?php
declare(strict_types=1);
/**
* @copyright 2024 Daniel Kesselberg <mail@danielkesselberg.de>
*
* @author Daniel Kesselberg <mail@danielkesselberg.de>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\DAV\CalDAV;
use OCP\Calendar\ICalendar;
use OCP\Constants;
class CachedSubscriptionImpl implements ICalendar {
private CalDavBackend $backend;
private CachedSubscription $calendar;
/** @var array<string, mixed> */
private array $calendarInfo;
public function __construct(
CachedSubscription $calendar,
array $calendarInfo,
CalDavBackend $backend
) {
$this->calendar = $calendar;
$this->calendarInfo = $calendarInfo;
$this->backend = $backend;
}
/**
* @return string defining the technical unique key
* @since 13.0.0
*/
public function getKey(): string {
return (string) $this->calendarInfo['id'];
}
/**
* {@inheritDoc}
*/
public function getUri(): string {
return $this->calendarInfo['uri'];
}
/**
* In comparison to getKey() this function returns a human readable (maybe translated) name
* @since 13.0.0
*/
public function getDisplayName(): ?string {
return $this->calendarInfo['{DAV:}displayname'];
}
/**
* Calendar color
* @since 13.0.0
*/
public function getDisplayColor(): ?string {
return $this->calendarInfo['{http://apple.com/ns/ical/}calendar-color'];
}
/**
* @param string $pattern which should match within the $searchProperties
* @param array $searchProperties defines the properties within the query pattern should match
* @param array $options - optional parameters:
* ['timerange' => ['start' => new DateTime(...), 'end' => new DateTime(...)]]
* @param int|null $limit - limit number of search results
* @param int|null $offset - offset for paging of search results
* @return array an array of events/journals/todos which are arrays of key-value-pairs
* @since 13.0.0
*/
public function search(string $pattern, array $searchProperties = [], array $options = [], $limit = null, $offset = null): array {
return $this->backend->search($this->calendarInfo, $pattern, $searchProperties, $options, $limit, $offset);
}
/**
* @return int build up using \OCP\Constants
* @since 13.0.0
*/
public function getPermissions(): int {
$permissions = $this->calendar->getACL();
$result = 0;
foreach ($permissions as $permission) {
switch ($permission['privilege']) {
case '{DAV:}read':
$result |= Constants::PERMISSION_READ;
break;
}
}
return $result;
}
public function isDeleted(): bool {
return false;
}
public function getSource(): string {
return $this->calendarInfo['source'];
}
}

@ -0,0 +1,57 @@
<?php
declare(strict_types=1);
/**
* @copyright 2024 Daniel Kesselberg <mail@danielkesselberg.de>
*
* @author Daniel Kesselberg <mail@danielkesselberg.de>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\DAV\CalDAV;
use OCP\Calendar\ICalendarProvider;
class CachedSubscriptionProvider implements ICalendarProvider {
public function __construct(
private CalDavBackend $calDavBackend
) {
}
public function getCalendars(string $principalUri, array $calendarUris = []): array {
$calendarInfos = $this->calDavBackend->getSubscriptionsForUser($principalUri);
if (count($calendarUris) > 0) {
$calendarInfos = array_filter($calendarInfos, fn (array $subscription) => in_array($subscription['uri'], $calendarUris));
}
$calendarInfos = array_values(array_filter($calendarInfos));
$iCalendars = [];
foreach ($calendarInfos as $calendarInfo) {
$calendar = new CachedSubscription($this->calDavBackend, $calendarInfo);
$iCalendars[] = new CachedSubscriptionImpl(
$calendar,
$calendarInfo,
$this->calDavBackend,
);
}
return $iCalendars;
}
}

@ -1882,12 +1882,18 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
$outerQuery = $this->db->getQueryBuilder();
$innerQuery = $this->db->getQueryBuilder();
if (isset($calendarInfo['source'])) {
$calendarType = self::CALENDAR_TYPE_SUBSCRIPTION;
} else {
$calendarType = self::CALENDAR_TYPE_CALENDAR;
}
$innerQuery->selectDistinct('op.objectid')
->from($this->dbObjectPropertiesTable, 'op')
->andWhere($innerQuery->expr()->eq('op.calendarid',
$outerQuery->createNamedParameter($calendarInfo['id'])))
->andWhere($innerQuery->expr()->eq('op.calendartype',
$outerQuery->createNamedParameter(self::CALENDAR_TYPE_CALENDAR)));
$outerQuery->createNamedParameter($calendarType)));
$outerQuery->select('c.id', 'c.calendardata', 'c.componenttype', 'c.uid', 'c.uri')
->from('calendarobjects', 'c')

@ -53,14 +53,16 @@ class CalendarHome extends \Sabre\CalDAV\CalendarHome {
/** @var PluginManager */
private $pluginManager;
/** @var bool */
private $returnCachedSubscriptions = false;
/** @var LoggerInterface */
private $logger;
private ?array $cachedChildren = null;
public function __construct(BackendInterface $caldavBackend, $principalInfo, LoggerInterface $logger) {
public function __construct(
BackendInterface $caldavBackend,
array $principalInfo,
LoggerInterface $logger,
private bool $returnCachedSubscriptions
) {
parent::__construct($caldavBackend, $principalInfo);
$this->l10n = \OC::$server->getL10N('dav');
$this->config = \OC::$server->getConfig();
@ -219,8 +221,4 @@ class CalendarHome extends \Sabre\CalDAV\CalendarHome {
$principalUri = $this->principalInfo['uri'];
return $this->caldavBackend->calendarSearch($principalUri, $filters, $limit, $offset);
}
public function enableCachedSubscriptionsForThisRequest() {
$this->returnCachedSubscriptions = true;
}
}

@ -32,6 +32,8 @@ use Sabre\DAVACL\PrincipalBackend;
class CalendarRoot extends \Sabre\CalDAV\CalendarRoot {
private LoggerInterface $logger;
private array $returnCachedSubscriptions = [];
public function __construct(
PrincipalBackend\BackendInterface $principalBackend,
Backend\BackendInterface $caldavBackend,
@ -43,7 +45,12 @@ class CalendarRoot extends \Sabre\CalDAV\CalendarRoot {
}
public function getChildForPrincipal(array $principal) {
return new CalendarHome($this->caldavBackend, $principal, $this->logger);
return new CalendarHome(
$this->caldavBackend,
$principal,
$this->logger,
array_key_exists($principal['uri'], $this->returnCachedSubscriptions)
);
}
public function getName() {
@ -56,4 +63,8 @@ class CalendarRoot extends \Sabre\CalDAV\CalendarRoot {
return parent::getName();
}
public function enableReturnCachedSubscriptions(string $principalUri): void {
$this->returnCachedSubscriptions['principals/users/' . $principalUri] = true;
}
}

@ -41,7 +41,7 @@ use OCA\DAV\CalDAV\EventComparisonService;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\Defaults;
use OCP\IConfig;
use OCP\IUserManager;
use OCP\IUserSession;
use OCP\Mail\IMailer;
use OCP\Util;
use Psr\Log\LoggerInterface;
@ -69,13 +69,12 @@ use Sabre\VObject\Reader;
* @license http://sabre.io/license/ Modified BSD License
*/
class IMipPlugin extends SabreIMipPlugin {
private ?string $userId;
private IUserSession $userSession;
private IConfig $config;
private IMailer $mailer;
private LoggerInterface $logger;
private ITimeFactory $timeFactory;
private Defaults $defaults;
private IUserManager $userManager;
private ?VCalendar $vCalendar = null;
private IMipService $imipService;
public const MAX_DATE = '2038-01-01';
@ -90,18 +89,16 @@ class IMipPlugin extends SabreIMipPlugin {
LoggerInterface $logger,
ITimeFactory $timeFactory,
Defaults $defaults,
IUserManager $userManager,
$userId,
IUserSession $userSession,
IMipService $imipService,
EventComparisonService $eventComparisonService) {
parent::__construct('');
$this->userId = $userId;
$this->userSession = $userSession;
$this->config = $config;
$this->mailer = $mailer;
$this->logger = $logger;
$this->timeFactory = $timeFactory;
$this->defaults = $defaults;
$this->userManager = $userManager;
$this->imipService = $imipService;
$this->eventComparisonService = $eventComparisonService;
}
@ -206,17 +203,16 @@ class IMipPlugin extends SabreIMipPlugin {
$this->imipService->setL10n($attendee);
// Build the sender name.
// Due to a bug in sabre, the senderName property for an iTIP message
// can actually also be a VObject Property
/** @var Parameter|string|null $senderName */
$senderName = $iTipMessage->senderName ?: null;
if($senderName instanceof Parameter) {
$senderName = $senderName->getValue() ?? null;
}
// Try to get the sender name from the current user id if available.
if ($this->userId !== null && ($senderName === null || empty(trim($senderName)))) {
$senderName = $this->userManager->getDisplayName($this->userId);
// Due to a bug in sabre, the senderName property for an iTIP message can actually also be a VObject Property
// If the iTIP message senderName is null or empty use the user session name as the senderName
if (($iTipMessage->senderName instanceof Parameter) && !empty(trim($iTipMessage->senderName->getValue()))) {
$senderName = trim($iTipMessage->senderName->getValue());
} elseif (is_string($iTipMessage->senderName) && !empty(trim($iTipMessage->senderName))) {
$senderName = trim($iTipMessage->senderName);
} elseif ($this->userSession->getUser() !== null) {
$senderName = trim($this->userSession->getUser()->getDisplayName());
} else {
$senderName = '';
}
$sender = substr($iTipMessage->sender, 7);

@ -682,7 +682,7 @@ class IMipService {
return false;
}
$type = $cuType->getValue() ?? 'INDIVIDUAL';
if (\in_array(strtoupper($type), ['RESOURCE', 'ROOM', 'UNKNOWN'], true)) {
if (\in_array(strtoupper($type), ['RESOURCE', 'ROOM'], true)) {
// Don't send emails to things
return true;
}

@ -32,6 +32,7 @@ use OCA\UserStatus\Service\StatusService as UserStatusService;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\Calendar\IManager;
use OCP\DB\Exception;
use OCP\ICache;
use OCP\ICacheFactory;
use OCP\IUser as User;
@ -72,7 +73,18 @@ class StatusService {
}
if(empty($calendarEvents)) {
$this->userStatusService->revertUserStatus($userId, IUserStatus::MESSAGE_CALENDAR_BUSY);
try {
$this->userStatusService->revertUserStatus($userId, IUserStatus::MESSAGE_CALENDAR_BUSY);
} catch (Exception $e) {
if ($e->getReason() === Exception::REASON_UNIQUE_CONSTRAINT_VIOLATION) {
// A different process might have written another status
// update to the DB while we're processing our stuff.
// We cannot safely restore the status as we don't know which one is valid at this point
// So let's silently log this one and exit
$this->logger->debug('Unique constraint violation for live user status', ['exception' => $e]);
return;
}
}
$this->logger->debug('No calendar events found for status check', ['user' => $userId]);
return;
}
@ -118,7 +130,18 @@ class StatusService {
});
if(empty($applicableEvents)) {
$this->userStatusService->revertUserStatus($userId, IUserStatus::MESSAGE_CALENDAR_BUSY);
try {
$this->userStatusService->revertUserStatus($userId, IUserStatus::MESSAGE_CALENDAR_BUSY);
} catch (Exception $e) {
if ($e->getReason() === Exception::REASON_UNIQUE_CONSTRAINT_VIOLATION) {
// A different process might have written another status
// update to the DB while we're processing our stuff.
// We cannot safely restore the status as we don't know which one is valid at this point
// So let's silently log this one and exit
$this->logger->debug('Unique constraint violation for live user status', ['exception' => $e]);
return;
}
}
$this->logger->debug('No status relevant events found, skipping calendar status change', ['user' => $userId]);
return;
}

@ -26,7 +26,7 @@ declare(strict_types=1);
*/
namespace OCA\DAV\CalDAV\WebcalCaching;
use OCA\DAV\CalDAV\CalendarHome;
use OCA\DAV\CalDAV\CalendarRoot;
use OCP\IRequest;
use Sabre\DAV\Exception\NotFound;
use Sabre\DAV\Server;
@ -71,6 +71,11 @@ class Plugin extends ServerPlugin {
if ($magicHeader === 'On') {
$this->enabled = true;
}
$isExportRequest = $request->getMethod() === 'GET' && array_key_exists('export', $request->getParams());
if ($isExportRequest) {
$this->enabled = true;
}
}
/**
@ -85,7 +90,7 @@ class Plugin extends ServerPlugin {
*/
public function initialize(Server $server) {
$this->server = $server;
$server->on('beforeMethod:*', [$this, 'beforeMethod']);
$server->on('beforeMethod:*', [$this, 'beforeMethod'], 15);
}
/**
@ -107,16 +112,11 @@ class Plugin extends ServerPlugin {
return;
}
// $calendarHomePath will look like: calendars/username
$calendarHomePath = $pathParts[0] . '/' . $pathParts[1];
try {
$calendarHome = $this->server->tree->getNodeForPath($calendarHomePath);
if (!($calendarHome instanceof CalendarHome)) {
//how did we end up here?
return;
$calendarRoot = $this->server->tree->getNodeForPath($pathParts[0]);
if ($calendarRoot instanceof CalendarRoot) {
$calendarRoot->enableReturnCachedSubscriptions($pathParts[1]);
}
$calendarHome->enableCachedSubscriptionsForThisRequest();
} catch (NotFound $ex) {
return;
}

@ -27,6 +27,7 @@
*/
namespace OCA\DAV\Connector\Sabre;
use OCA\DAV\CalDAV\CachedSubscription;
use OCA\DAV\CalDAV\Calendar;
use OCA\DAV\CardDAV\AddressBook;
use Sabre\CalDAV\Principal\User;
@ -61,6 +62,7 @@ class DavAclPlugin extends \Sabre\DAVACL\Plugin {
$type = 'Addressbook';
break;
case Calendar::class:
case CachedSubscription::class:
$type = 'Calendar';
break;
default:

@ -469,20 +469,28 @@ class Directory extends \OCA\DAV\Connector\Sabre\Node implements \Sabre\DAV\ICol
public function copyInto($targetName, $sourcePath, INode $sourceNode) {
if ($sourceNode instanceof File || $sourceNode instanceof Directory) {
$destinationPath = $this->getPath() . '/' . $targetName;
$sourcePath = $sourceNode->getPath();
try {
$destinationPath = $this->getPath() . '/' . $targetName;
$sourcePath = $sourceNode->getPath();
if (!$this->fileView->isCreatable($this->getPath())) {
throw new \Sabre\DAV\Exception\Forbidden();
}
if (!$this->fileView->isCreatable($this->getPath())) {
throw new \Sabre\DAV\Exception\Forbidden();
}
try {
$this->fileView->verifyPath($this->getPath(), $targetName);
} catch (InvalidPathException $ex) {
throw new InvalidPath($ex->getMessage());
}
try {
$this->fileView->verifyPath($this->getPath(), $targetName);
} catch (InvalidPathException $ex) {
throw new InvalidPath($ex->getMessage());
}
return $this->fileView->copy($sourcePath, $destinationPath);
return $this->fileView->copy($sourcePath, $destinationPath);
} catch (StorageNotAvailableException $e) {
throw new ServiceUnavailable($e->getMessage());
} catch (ForbiddenException $ex) {
throw new Forbidden($ex->getMessage(), $ex->getRetry());
} catch (LockedException $e) {
throw new FileLocked($e->getMessage(), $e->getCode(), $e);
}
}
return false;

@ -125,7 +125,7 @@ class File extends Node implements IFile {
* different object on a subsequent GET you are strongly recommended to not
* return an ETag, and just return null.
*
* @param resource $data
* @param resource|string $data
*
* @throws Forbidden
* @throws UnsupportedMediaType

@ -30,6 +30,7 @@ use OC\Files\Search\SearchBinaryOperator;
use OC\Files\Search\SearchComparison;
use OC\Files\Search\SearchOrder;
use OC\Files\Search\SearchQuery;
use OC\Files\Storage\Wrapper\Jail;
use OC\Files\View;
use OCA\DAV\Connector\Sabre\CachingTree;
use OCA\DAV\Connector\Sabre\Directory;
@ -39,6 +40,8 @@ use OCP\Files\Cache\ICacheEntry;
use OCP\Files\Folder;
use OCP\Files\IRootFolder;
use OCP\Files\Node;
use OCP\Files\Search\ISearchBinaryOperator;
use OCP\Files\Search\ISearchComparison;
use OCP\Files\Search\ISearchOperator;
use OCP\Files\Search\ISearchOrder;
use OCP\Files\Search\ISearchQuery;
@ -152,28 +155,74 @@ class FileSearchBackend implements ISearchBackend {
public function preloadPropertyFor(array $nodes, array $requestProperties): void {
}
/**
* @param Query $search
* @return SearchResult[]
*/
public function search(Query $search): array {
if (count($search->from) !== 1) {
throw new \InvalidArgumentException('Searching more than one folder is not supported');
}
$query = $this->transformQuery($search);
$scope = $search->from[0];
if ($scope->path === null) {
private function getFolderForPath(?string $path = null): Folder {
if ($path === null) {
throw new \InvalidArgumentException('Using uri\'s as scope is not supported, please use a path relative to the search arbiter instead');
}
$node = $this->tree->getNodeForPath($scope->path);
$node = $this->tree->getNodeForPath($path);
if (!$node instanceof Directory) {
throw new \InvalidArgumentException('Search is only supported on directories');
}
$fileInfo = $node->getFileInfo();
$folder = $this->rootFolder->get($fileInfo->getPath());
/** @var Folder $folder $results */
$results = $folder->search($query);
/** @var Folder */
return $this->rootFolder->get($fileInfo->getPath());
}
/**
* @param Query $search
* @return SearchResult[]
*/
public function search(Query $search): array {
switch (count($search->from)) {
case 0:
throw new \InvalidArgumentException('You need to specify a scope for the search.');
break;
case 1:
$scope = $search->from[0];
$folder = $this->getFolderForPath($scope->path);
$query = $this->transformQuery($search);
$results = $folder->search($query);
break;
default:
$scopes = [];
foreach ($search->from as $scope) {
$folder = $this->getFolderForPath($scope->path);
$folderStorage = $folder->getStorage();
if ($folderStorage->instanceOfStorage(Jail::class)) {
/** @var Jail $folderStorage */
$internalPath = $folderStorage->getUnjailedPath($folder->getInternalPath());
} else {
$internalPath = $folder->getInternalPath();
}
$scopes[] = new SearchBinaryOperator(
ISearchBinaryOperator::OPERATOR_AND,
[
new SearchComparison(
ISearchComparison::COMPARE_EQUAL,
'storage',
$folderStorage->getCache()->getNumericStorageId(),
''
),
new SearchComparison(
ISearchComparison::COMPARE_LIKE,
'path',
$internalPath . '/%',
''
),
]
);
}
$scopeOperators = new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, $scopes);
$query = $this->transformQuery($search, $scopeOperators);
$userFolder = $this->rootFolder->getUserFolder($this->user->getUID());
$results = $userFolder->search($query);
}
/** @var SearchResult[] $nodes */
$nodes = array_map(function (Node $node) {
@ -288,7 +337,7 @@ class FileSearchBackend implements ISearchBackend {
*
* @return ISearchQuery
*/
private function transformQuery(Query $query): ISearchQuery {
private function transformQuery(Query $query, ?SearchBinaryOperator $scopeOperators = null): ISearchQuery {
$orders = array_map(function (Order $order): ISearchOrder {
$direction = $order->order === Order::ASC ? ISearchOrder::DIRECTION_ASCENDING : ISearchOrder::DIRECTION_DESCENDING;
if (str_starts_with($order->property->name, FilesPlugin::FILE_METADATA_PREFIX)) {
@ -316,8 +365,16 @@ class FileSearchBackend implements ISearchBackend {
throw new \InvalidArgumentException('Invalid search query, maximum operator limit of ' . self::OPERATOR_LIMIT . ' exceeded, got ' . $operatorCount . ' operators');
}
/** @var SearchBinaryOperator|SearchComparison */
$queryOperators = $this->transformSearchOperation($query->where);
if ($scopeOperators === null) {
$operators = $queryOperators;
} else {
$operators = new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [$queryOperators, $scopeOperators]);
}
return new SearchQuery(
$this->transformSearchOperation($query->where),
$operators,
(int)$limit->maxResults,
$offset,
$orders,

@ -39,6 +39,7 @@ namespace OCA\DAV;
use OCA\DAV\AppInfo\PluginManager;
use OCA\DAV\BulkUpload\BulkUploadPlugin;
use OCA\DAV\CalDAV\BirthdayService;
use OCA\DAV\CalDAV\Schedule\IMipPlugin;
use OCA\DAV\CalDAV\Security\RateLimitingPlugin;
use OCA\DAV\CardDAV\HasPhotoPlugin;
use OCA\DAV\CardDAV\ImageExportPlugin;
@ -176,12 +177,10 @@ class Server {
// calendar plugins
if ($this->requestIsForSubtree(['calendars', 'public-calendars', 'system-calendars', 'principals'])) {
$this->server->addPlugin(new DAV\Sharing\Plugin($authBackend, \OC::$server->getRequest(), \OC::$server->getConfig()));
$this->server->addPlugin(new \OCA\DAV\CalDAV\Plugin());
$this->server->addPlugin(new \OCA\DAV\CalDAV\ICSExportPlugin\ICSExportPlugin(\OC::$server->getConfig(), $logger));
$this->server->addPlugin(new \OCA\DAV\CalDAV\Schedule\Plugin(\OC::$server->getConfig(), \OC::$server->get(LoggerInterface::class)));
if (\OC::$server->getConfig()->getAppValue('dav', 'sendInvitations', 'yes') === 'yes') {
$this->server->addPlugin(\OC::$server->query(\OCA\DAV\CalDAV\Schedule\IMipPlugin::class));
}
$this->server->addPlugin(\OC::$server->get(\OCA\DAV\CalDAV\Trashbin\Plugin::class));
$this->server->addPlugin(new \OCA\DAV\CalDAV\WebcalCaching\Plugin($request));
@ -190,7 +189,6 @@ class Server {
}
$this->server->addPlugin(new \Sabre\CalDAV\Notifications\Plugin());
$this->server->addPlugin(new DAV\Sharing\Plugin($authBackend, \OC::$server->getRequest(), \OC::$server->getConfig()));
$this->server->addPlugin(new \OCA\DAV\CalDAV\Publishing\PublishPlugin(
\OC::$server->getConfig(),
\OC::$server->getURLGenerator()
@ -304,6 +302,18 @@ class Server {
\OC::$server->getCommentsManager(),
$userSession
));
if (\OC::$server->getConfig()->getAppValue('dav', 'sendInvitations', 'yes') === 'yes') {
$this->server->addPlugin(new IMipPlugin(
\OC::$server->get(\OCP\IConfig::class),
\OC::$server->get(\OCP\Mail\IMailer::class),
\OC::$server->get(LoggerInterface::class),
\OC::$server->get(\OCP\AppFramework\Utility\ITimeFactory::class),
\OC::$server->get(\OCP\Defaults::class),
$userSession,
\OC::$server->get(\OCA\DAV\CalDAV\Schedule\IMipService::class),
\OC::$server->get(\OCA\DAV\CalDAV\EventComparisonService::class)
));
}
$this->server->addPlugin(new \OCA\DAV\CalDAV\Search\SearchPlugin());
if ($view !== null) {
$this->server->addPlugin(new FilesReportPlugin(

@ -0,0 +1,96 @@
<?php
declare(strict_types=1);
/**
* @copyright 2024 Daniel Kesselberg <mail@danielkesselberg.de>
*
* @author Daniel Kesselberg <mail@danielkesselberg.de>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\DAV\Tests\unit\CalDAV;
use OCA\DAV\CalDAV\CachedSubscription;
use OCA\DAV\CalDAV\CachedSubscriptionImpl;
use OCA\DAV\CalDAV\CalDavBackend;
use Test\TestCase;
class CachedSubscriptionImplTest extends TestCase {
private CachedSubscription $cachedSubscription;
private array $cachedSubscriptionInfo;
private CachedSubscriptionImpl $cachedSubscriptionImpl;
private CalDavBackend $backend;
protected function setUp(): void {
parent::setUp();
$this->cachedSubscription = $this->createMock(CachedSubscription::class);
$this->cachedSubscriptionInfo = [
'id' => 'fancy_id_123',
'{DAV:}displayname' => 'user readable name 123',
'{http://apple.com/ns/ical/}calendar-color' => '#AABBCC',
'uri' => '/this/is/a/uri',
'source' => 'https://test.localhost/calendar1',
];
$this->backend = $this->createMock(CalDavBackend::class);
$this->cachedSubscriptionImpl = new CachedSubscriptionImpl(
$this->cachedSubscription,
$this->cachedSubscriptionInfo,
$this->backend
);
}
public function testGetKey(): void {
$this->assertEquals($this->cachedSubscriptionImpl->getKey(), 'fancy_id_123');
}
public function testGetDisplayname(): void {
$this->assertEquals($this->cachedSubscriptionImpl->getDisplayName(), 'user readable name 123');
}
public function testGetDisplayColor(): void {
$this->assertEquals($this->cachedSubscriptionImpl->getDisplayColor(), '#AABBCC');
}
public function testGetSource(): void {
$this->assertEquals($this->cachedSubscriptionImpl->getSource(), 'https://test.localhost/calendar1');
}
public function testSearch(): void {
$this->backend->expects($this->once())
->method('search')
->with($this->cachedSubscriptionInfo, 'abc', ['def'], ['ghi'], 42, 1337)
->willReturn(['SEARCHRESULTS']);
$result = $this->cachedSubscriptionImpl->search('abc', ['def'], ['ghi'], 42, 1337);
$this->assertEquals($result, ['SEARCHRESULTS']);
}
public function testGetPermissionRead(): void {
$this->cachedSubscription->expects($this->once())
->method('getACL')
->with()
->willReturn([
['privilege' => '{DAV:}read']
]);
$this->assertEquals(1, $this->cachedSubscriptionImpl->getPermissions());
}
}

@ -0,0 +1,88 @@
<?php
declare(strict_types=1);
/**
* @copyright 2024 Daniel Kesselberg <mail@danielkesselberg.de>
*
* @author Daniel Kesselberg <mail@danielkesselberg.de>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\DAV\Tests\unit\CalDAV;
use OCA\DAV\CalDAV\CachedSubscriptionImpl;
use OCA\DAV\CalDAV\CachedSubscriptionProvider;
use OCA\DAV\CalDAV\CalDavBackend;
use Test\TestCase;
class CachedSubscriptionProviderTest extends TestCase {
private CalDavBackend $backend;
private CachedSubscriptionProvider $provider;
protected function setUp(): void {
parent::setUp();
$this->backend = $this->createMock(CalDavBackend::class);
$this->backend
->expects(self::once())
->method('getSubscriptionsForUser')
->with('user-principal-123')
->willReturn([
[
'id' => 'subscription-1',
'uri' => 'subscription-1',
'principaluris' => 'user-principal-123',
'source' => 'https://localhost/subscription-1',
// A subscription array has actually more properties.
],
[
'id' => 'subscription-2',
'uri' => 'subscription-2',
'principaluri' => 'user-principal-123',
'source' => 'https://localhost/subscription-2',
// A subscription array has actually more properties.
]
]);
$this->provider = new CachedSubscriptionProvider($this->backend);
}
public function testGetCalendars() {
$calendars = $this->provider->getCalendars(
'user-principal-123',
[]
);
$this->assertCount(2, $calendars);
$this->assertInstanceOf(CachedSubscriptionImpl::class, $calendars[0]);
$this->assertInstanceOf(CachedSubscriptionImpl::class, $calendars[1]);
}
public function testGetCalendarsFilterByUri() {
$calendars = $this->provider->getCalendars(
'user-principal-123',
['subscription-1']
);
$this->assertCount(1, $calendars);
$this->assertInstanceOf(CachedSubscriptionImpl::class, $calendars[0]);
$this->assertEquals('subscription-1', $calendars[0]->getUri());
}
}

@ -61,6 +61,11 @@ class CachedSubscriptionTest extends \Test\TestCase {
'principal' => '{DAV:}authenticated',
'protected' => true,
],
[
'privilege' => '{DAV:}write-properties',
'principal' => 'user1',
'protected' => 'true'
]
], $calendar->getACL());
}

@ -26,6 +26,7 @@
namespace OCA\DAV\Tests\unit\CalDAV;
use OCA\DAV\AppInfo\PluginManager;
use OCA\DAV\CalDAV\CachedSubscription;
use OCA\DAV\CalDAV\CalDavBackend;
use OCA\DAV\CalDAV\CalendarHome;
use OCA\DAV\CalDAV\Integration\ExternalCalendar;
@ -35,6 +36,7 @@ use OCA\DAV\CalDAV\Trashbin\TrashbinHome;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Log\LoggerInterface;
use Sabre\CalDAV\Schedule\Inbox;
use Sabre\CalDAV\Subscriptions\Subscription;
use Sabre\DAV\MkCol;
use Test\TestCase;
@ -68,13 +70,13 @@ class CalendarHomeTest extends TestCase {
$this->calendarHome = new CalendarHome(
$this->backend,
$this->principalInfo,
$this->logger
$this->logger,
false
);
// Replace PluginManager with our mock
$reflection = new \ReflectionClass($this->calendarHome);
$reflectionProperty = $reflection->getProperty('pluginManager');
$reflectionProperty->setAccessible(true);
$reflectionProperty->setValue($this->calendarHome, $this->pluginManager);
}
@ -249,4 +251,124 @@ class CalendarHomeTest extends TestCase {
$actual = $this->calendarHome->getChild('app-generated--calendar_plugin_2--calendar-uri-from-backend');
$this->assertEquals($externalCalendarMock, $actual);
}
public function testGetChildrenSubscriptions(): void {
$this->backend
->expects(self::once())
->method('getCalendarsForUser')
->with('user-principal-123')
->willReturn([]);
$this->backend
->expects(self::once())
->method('getSubscriptionsForUser')
->with('user-principal-123')
->willReturn([
[
'id' => 'subscription-1',
'uri' => 'subscription-1',
'principaluri' => 'user-principal-123',
'source' => 'https://localhost/subscription-1',
// A subscription array has actually more properties.
],
[
'id' => 'subscription-2',
'uri' => 'subscription-2',
'principaluri' => 'user-principal-123',
'source' => 'https://localhost/subscription-2',
// A subscription array has actually more properties.
]
]);
/*
* @FIXME: PluginManager should be injected via constructor.
*/
$pluginManager = $this->createMock(PluginManager::class);
$pluginManager
->expects(self::once())
->method('getCalendarPlugins')
->with()
->willReturn([]);
$calendarHome = new CalendarHome(
$this->backend,
$this->principalInfo,
$this->logger,
false
);
$reflection = new \ReflectionClass($calendarHome);
$reflectionProperty = $reflection->getProperty('pluginManager');
$reflectionProperty->setValue($calendarHome, $pluginManager);
$actual = $calendarHome->getChildren();
$this->assertCount(5, $actual);
$this->assertInstanceOf(Inbox::class, $actual[0]);
$this->assertInstanceOf(Outbox::class, $actual[1]);
$this->assertInstanceOf(TrashbinHome::class, $actual[2]);
$this->assertInstanceOf(Subscription::class, $actual[3]);
$this->assertInstanceOf(Subscription::class, $actual[4]);
}
public function testGetChildrenCachedSubscriptions(): void {
$this->backend
->expects(self::once())
->method('getCalendarsForUser')
->with('user-principal-123')
->willReturn([]);
$this->backend
->expects(self::once())
->method('getSubscriptionsForUser')
->with('user-principal-123')
->willReturn([
[
'id' => 'subscription-1',
'uri' => 'subscription-1',
'principaluris' => 'user-principal-123',
'source' => 'https://localhost/subscription-1',
// A subscription array has actually more properties.
],
[
'id' => 'subscription-2',
'uri' => 'subscription-2',
'principaluri' => 'user-principal-123',
'source' => 'https://localhost/subscription-2',
// A subscription array has actually more properties.
]
]);
/*
* @FIXME: PluginManager should be injected via constructor.
*/
$pluginManager = $this->createMock(PluginManager::class);
$pluginManager
->expects(self::once())
->method('getCalendarPlugins')
->with()
->willReturn([]);
$calendarHome = new CalendarHome(
$this->backend,
$this->principalInfo,
$this->logger,
true
);
$reflection = new \ReflectionClass($calendarHome);
$reflectionProperty = $reflection->getProperty('pluginManager');
$reflectionProperty->setValue($calendarHome, $pluginManager);
$actual = $calendarHome->getChildren();
$this->assertCount(5, $actual);
$this->assertInstanceOf(Inbox::class, $actual[0]);
$this->assertInstanceOf(Outbox::class, $actual[1]);
$this->assertInstanceOf(TrashbinHome::class, $actual[2]);
$this->assertInstanceOf(CachedSubscription::class, $actual[3]);
$this->assertInstanceOf(CachedSubscription::class, $actual[4]);
}
}

@ -39,9 +39,6 @@ use Sabre\VObject\Component\VEvent;
use Sabre\VObject\ITip\Message;
use Sabre\VObject\Reader;
/**
* @group DB
*/
class CalendarImplTest extends \Test\TestCase {
/** @var CalendarImpl */
private $calendarImpl;

@ -35,7 +35,8 @@ use OCA\DAV\CalDAV\Schedule\IMipService;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\Defaults;
use OCP\IConfig;
use OCP\IUserManager;
use OCP\IUser;
use OCP\IUserSession;
use OCP\Mail\IAttachment;
use OCP\Mail\IEMailTemplate;
use OCP\Mail\IMailer;
@ -68,8 +69,11 @@ class IMipPluginTest extends TestCase {
/** @var IConfig|MockObject */
private $config;
/** @var IUserManager|MockObject */
private $userManager;
/** @var IUserSession|MockObject */
private $userSession;
/** @var IUser|MockObject */
private $user;
/** @var IMipPlugin */
private $plugin;
@ -107,8 +111,16 @@ class IMipPluginTest extends TestCase {
$this->timeFactory->method('getTime')->willReturn(1496912528); // 2017-01-01
$this->config = $this->createMock(IConfig::class);
$this->user = $this->createMock(IUser::class);
/*
$this->user->method('getUID');
$this->user->method('getDisplayName');
*/
$this->userManager = $this->createMock(IUserManager::class);
$this->userSession = $this->createMock(IUserSession::class);
$this->userSession->method('getUser')
->willReturn($this->user);
$this->defaults = $this->createMock(Defaults::class);
$this->defaults->method('getName')
@ -124,8 +136,7 @@ class IMipPluginTest extends TestCase {
$this->logger,
$this->timeFactory,
$this->defaults,
$this->userManager,
'user123',
$this->userSession,
$this->service,
$this->eventComparisonService
);
@ -213,8 +224,15 @@ class IMipPluginTest extends TestCase {
->method('buildBodyData')
->with($newVevent, $oldVEvent)
->willReturn($data);
$this->userManager->expects(self::never())
->method('getDisplayName');
$this->user->expects(self::any())
->method('getUID')
->willReturn('user1');
$this->user->expects(self::any())
->method('getDisplayName')
->willReturn('Mr. Wizard');
$this->userSession->expects(self::any())
->method('getUser')
->willReturn($this->user);
$this->service->expects(self::once())
->method('getFrom');
$this->service->expects(self::once())
@ -307,8 +325,15 @@ class IMipPluginTest extends TestCase {
->willReturn(true);
$this->service->expects(self::never())
->method('buildBodyData');
$this->userManager->expects(self::never())
->method('getDisplayName');
$this->user->expects(self::any())
->method('getUID')
->willReturn('user1');
$this->user->expects(self::any())
->method('getDisplayName')
->willReturn('Mr. Wizard');
$this->userSession->expects(self::any())
->method('getUser')
->willReturn($this->user);
$this->service->expects(self::never())
->method('getFrom');
$this->service->expects(self::never())
@ -331,7 +356,6 @@ class IMipPluginTest extends TestCase {
$this->assertEquals('1.0', $message->getScheduleStatus());
}
public function testParsingRecurrence(): void {
$message = new Message();
$message->method = 'REQUEST';
@ -404,9 +428,15 @@ class IMipPluginTest extends TestCase {
->method('buildBodyData')
->with($newVevent, null)
->willReturn($data);
$this->userManager->expects(self::once())
$this->user->expects(self::any())
->method('getUID')
->willReturn('user1');
$this->user->expects(self::any())
->method('getDisplayName')
->willReturn('Mr. Wizard');
$this->userSession->expects(self::any())
->method('getUser')
->willReturn($this->user);
$this->service->expects(self::once())
->method('getFrom');
$this->service->expects(self::once())
@ -529,8 +559,15 @@ class IMipPluginTest extends TestCase {
->method('buildBodyData')
->with($newVevent, null)
->willReturn($data);
$this->userManager->expects(self::never())
->method('getDisplayName');
$this->user->expects(self::any())
->method('getUID')
->willReturn('user1');
$this->user->expects(self::any())
->method('getDisplayName')
->willReturn('Mr. Wizard');
$this->userSession->expects(self::any())
->method('getUser')
->willReturn($this->user);
$this->service->expects(self::once())
->method('getFrom');
$this->service->expects(self::once())
@ -618,8 +655,15 @@ class IMipPluginTest extends TestCase {
->method('buildBodyData')
->with($newVevent, null)
->willReturn($data);
$this->userManager->expects(self::never())
->method('getDisplayName');
$this->user->expects(self::any())
->method('getUID')
->willReturn('user1');
$this->user->expects(self::any())
->method('getDisplayName')
->willReturn('Mr. Wizard');
$this->userSession->expects(self::any())
->method('getUser')
->willReturn($this->user);
$this->service->expects(self::once())
->method('getFrom');
$this->service->expects(self::once())
@ -704,9 +748,15 @@ class IMipPluginTest extends TestCase {
->method('buildBodyData')
->with($newVevent, null)
->willReturn($data);
$this->userManager->expects(self::once())
$this->user->expects(self::any())
->method('getUID')
->willReturn('user1');
$this->user->expects(self::any())
->method('getDisplayName')
->willReturn('Mr. Wizard');
$this->userSession->expects(self::any())
->method('getUser')
->willReturn($this->user);
$this->service->expects(self::once())
->method('getFrom');
$this->service->expects(self::once())

@ -48,17 +48,64 @@ class PluginTest extends \Test\TestCase {
$this->assertEquals(false, $plugin->isCachingEnabledForThisRequest());
}
public function testEnabled(): void {
public function testEnabledUserAgent(): void {
$request = $this->createMock(IRequest::class);
$request->expects($this->once())
->method('isUserAgent')
->with(Plugin::ENABLE_FOR_CLIENTS)
->willReturn(false);
->willReturn(true);
$request->expects($this->once())
->method('getHeader')
->with('X-NC-CalDAV-Webcal-Caching')
->willReturn('');
$request->expects($this->once())
->method('getMethod')
->willReturn('REPORT');
$request->expects($this->never())
->method('getParams');
$plugin = new Plugin($request);
$this->assertEquals(true, $plugin->isCachingEnabledForThisRequest());
}
public function testEnabledWebcalCachingHeader(): void {
$request = $this->createMock(IRequest::class);
$request->expects($this->once())
->method('isUserAgent')
->with(Plugin::ENABLE_FOR_CLIENTS)
->willReturn(false);
$request->expects($this->once())
->method('getHeader')
->with('X-NC-CalDAV-Webcal-Caching')
->willReturn('On');
$request->expects($this->once())
->method('getMethod')
->willReturn('REPORT');
$request->expects($this->never())
->method('getParams');
$plugin = new Plugin($request);
$this->assertEquals(true, $plugin->isCachingEnabledForThisRequest());
}
public function testEnabledExportRequest(): void {
$request = $this->createMock(IRequest::class);
$request->expects($this->once())
->method('isUserAgent')
->with(Plugin::ENABLE_FOR_CLIENTS)
->willReturn(false);
$request->expects($this->once())
->method('getHeader')
->with('X-NC-CalDAV-Webcal-Caching')
->willReturn('');
$request->expects($this->once())
->method('getMethod')
->willReturn('GET');
$request->expects($this->once())
->method('getParams')
->willReturn(['export' => '']);
$plugin = new Plugin($request);

@ -42,6 +42,8 @@ use OCP\Files\ForbiddenException;
use OCP\Files\Storage;
use OCP\IConfig;
use OCP\IRequestId;
use OCP\ITempManager;
use OCP\IUserManager;
use OCP\Lock\ILockingProvider;
use PHPUnit\Framework\MockObject\MockObject;
use Test\HookHelper;
@ -86,7 +88,7 @@ class FileTest extends TestCase {
}
protected function tearDown(): void {
$userManager = \OC::$server->getUserManager();
$userManager = \OCP\Server::get(IUserManager::class);
$userManager->get($this->user)->delete();
parent::tearDown();
@ -177,13 +179,13 @@ class FileTest extends TestCase {
public function testSimplePutFails($thrownException, $expectedException, $checkPreviousClass = true): void {
// setup
$storage = $this->getMockBuilder(Local::class)
->setMethods(['writeStream'])
->setConstructorArgs([['datadir' => \OC::$server->getTempManager()->getTemporaryFolder()]])
->onlyMethods(['writeStream'])
->setConstructorArgs([['datadir' => \OCP\Server::get(ITempManager::class)->getTemporaryFolder()]])
->getMock();
\OC\Files\Filesystem::mount($storage, [], $this->user . '/');
/** @var View | MockObject $view */
$view = $this->getMockBuilder(View::class)
->setMethods(['getRelativePath', 'resolvePath'])
->onlyMethods(['getRelativePath', 'resolvePath'])
->getMock();
$view->expects($this->atLeastOnce())
->method('resolvePath')
@ -238,12 +240,13 @@ class FileTest extends TestCase {
public function testChunkedPutFails($thrownException, $expectedException, $checkPreviousClass = false): void {
// setup
$storage = $this->getMockBuilder(Local::class)
->setMethods(['fopen'])
->setConstructorArgs([['datadir' => \OC::$server->getTempManager()->getTemporaryFolder()]])
->onlyMethods(['fopen'])
->setConstructorArgs([['datadir' => \OCP\Server::get(ITempManager::class)->getTemporaryFolder()]])
->getMock();
\OC\Files\Filesystem::mount($storage, [], $this->user . '/');
/** @var View|MockObject */
$view = $this->getMockBuilder(View::class)
->setMethods(['getRelativePath', 'resolvePath'])
->onlyMethods(['getRelativePath', 'resolvePath'])
->getMock();
$view->expects($this->atLeastOnce())
->method('resolvePath')
@ -340,7 +343,7 @@ class FileTest extends TestCase {
/** @var \OCA\DAV\Connector\Sabre\File | MockObject $file */
$file = $this->getMockBuilder(\OCA\DAV\Connector\Sabre\File::class)
->setConstructorArgs([$view, $info, null, $request])
->setMethods(['header'])
->onlyMethods(['header'])
->getMock();
// beforeMethod locks
@ -690,8 +693,9 @@ class FileTest extends TestCase {
*/
public function testSimplePutFailsSizeCheck(): void {
// setup
/** @var View|MockObject */
$view = $this->getMockBuilder(View::class)
->setMethods(['rename', 'getRelativePath', 'filesize'])
->onlyMethods(['rename', 'getRelativePath', 'filesize'])
->getMock();
$view->expects($this->any())
->method('rename')
@ -820,8 +824,9 @@ class FileTest extends TestCase {
*/
public function testSimplePutInvalidChars(): void {
// setup
/** @var View|MockObject */
$view = $this->getMockBuilder(View::class)
->setMethods(['getRelativePath'])
->onlyMethods(['getRelativePath'])
->getMock();
$view->expects($this->any())
->method('getRelativePath')
@ -859,8 +864,9 @@ class FileTest extends TestCase {
$this->expectException(\OCA\DAV\Connector\Sabre\Exception\InvalidPath::class);
// setup
/** @var View|MockObject */
$view = $this->getMockBuilder(View::class)
->setMethods(['getRelativePath'])
->onlyMethods(['getRelativePath'])
->getMock();
$view->expects($this->any())
@ -878,8 +884,9 @@ class FileTest extends TestCase {
public function testUploadAbort(): void {
// setup
/** @var View|MockObject */
$view = $this->getMockBuilder(View::class)
->setMethods(['rename', 'getRelativePath', 'filesize'])
->onlyMethods(['rename', 'getRelativePath', 'filesize'])
->getMock();
$view->expects($this->any())
->method('rename')
@ -927,6 +934,7 @@ class FileTest extends TestCase {
public function testDeleteWhenAllowed(): void {
// setup
/** @var View|MockObject */
$view = $this->getMockBuilder(View::class)
->getMock();
@ -950,6 +958,7 @@ class FileTest extends TestCase {
$this->expectException(\Sabre\DAV\Exception\Forbidden::class);
// setup
/** @var View|MockObject */
$view = $this->getMockBuilder(View::class)
->getMock();
@ -969,6 +978,7 @@ class FileTest extends TestCase {
$this->expectException(\Sabre\DAV\Exception\Forbidden::class);
// setup
/** @var View|MockObject */
$view = $this->getMockBuilder(View::class)
->getMock();
@ -993,6 +1003,7 @@ class FileTest extends TestCase {
$this->expectException(\OCA\DAV\Connector\Sabre\Exception\Forbidden::class);
// setup
/** @var View|MockObject */
$view = $this->getMockBuilder(View::class)
->getMock();
@ -1060,7 +1071,7 @@ class FileTest extends TestCase {
$wasLockedPre = false;
$wasLockedPost = false;
$eventHandler = $this->getMockBuilder(\stdclass::class)
->setMethods(['writeCallback', 'postWriteCallback'])
->addMethods(['writeCallback', 'postWriteCallback'])
->getMock();
// both pre and post hooks might need access to the file,
@ -1166,8 +1177,9 @@ class FileTest extends TestCase {
public function testGetFopenFails(): void {
$this->expectException(\Sabre\DAV\Exception\ServiceUnavailable::class);
/** @var View|MockObject */
$view = $this->getMockBuilder(View::class)
->setMethods(['fopen'])
->onlyMethods(['fopen'])
->getMock();
$view->expects($this->atLeastOnce())
->method('fopen')
@ -1187,8 +1199,9 @@ class FileTest extends TestCase {
public function testGetFopenThrows(): void {
$this->expectException(\OCA\DAV\Connector\Sabre\Exception\Forbidden::class);
/** @var View|MockObject */
$view = $this->getMockBuilder(View::class)
->setMethods(['fopen'])
->onlyMethods(['fopen'])
->getMock();
$view->expects($this->atLeastOnce())
->method('fopen')
@ -1208,8 +1221,9 @@ class FileTest extends TestCase {
public function testGetThrowsIfNoPermission(): void {
$this->expectException(\Sabre\DAV\Exception\NotFound::class);
/** @var View|MockObject */
$view = $this->getMockBuilder(View::class)
->setMethods(['fopen'])
->onlyMethods(['fopen'])
->getMock();
$view->expects($this->never())
->method('fopen');

@ -12,7 +12,12 @@ OC.L10N.register(
"Couldn't establish a federated share, maybe the password was wrong." : "No fue posible establecer el elemento compartido federado, tal vez la contraseña sea incorrecta. ",
"Federated Share request sent, you will receive an invitation. Check your notifications." : "Solicitud de elemento compartido Federado enviada, recibiras una invitación. Verifica tus notificaciones.",
"Couldn't establish a federated share, it looks like the server to federate with is too old (Nextcloud <= 9)." : "No fue posible establecer el elemento compartido, parece que el servidor es obsoleto (Nextcloud <=9).",
"It is not allowed to send federated group shares from this server." : "No está permitido enviar recursos compartidos federados de grupos desde este servidor.",
"Sharing %1$s failed, because this item is already shared with the account %2$s" : "No se pudo compartir %1$s, porque este elemento ya está compartido con la cuenta %2$s",
"Not allowed to create a federated share to the same account" : "No está permitido crear un recurso compartido federado a la misma cuenta",
"Federated shares require read permissions" : "Los recursos compartidos federados requieren permiso de lectura",
"File is already shared with %s" : "El archivo ya ha sido compartido con %s",
"Sharing %1$s failed, could not find %2$s, maybe the server is currently unreachable or uses a self-signed certificate." : "Falló al compartir %1$s, no se pudo encontrar %2$s, quizás el servidor no se puede alcanzar en este momento o usa un certificado autofirmado.",
"Could not find share" : "No fue posible encontrar el elemento compartido",
"Federated sharing" : "Elementos compartidos",
"You received {share} as a remote share from {user} (on behalf of {behalf})" : "Has recibido {share} como un elemento compartido remoto de {user} (de parte de {behalf})",
@ -23,19 +28,37 @@ OC.L10N.register(
"Sharing" : "Compartiendo",
"Federated file sharing" : "Compartir elementos",
"Provide federated file sharing across servers" : "Provee el compartir archivos federados entre servidores",
"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 comparten entre servidores. Esto incluye los recursos compartidos entre usuarios en este servidor, así como si hacen uso de intercambios federados.",
"Allow people on this server to send shares to other servers (this option also allows WebDAV access to public shares)" : "Permitir a los usuarios de este servidor de enviar recursos compartidos a otros servidores (esta opción también permite el acceso WebDAV a los recursos compartidos públicos)",
"Allow people on this server to receive shares from other servers" : "Permitir a los usuarios de este servidor de recibir recursos compartidos desde otros servidores",
"Allow people on this server to send shares to groups on other servers" : "Permitir a los usuarios de este servidor de enviar recursos compartidos a grupos en otros servidores",
"Allow people on this server to receive group shares from other servers" : "Permitir a los usuarios de este servidor de recibir recursos compartidos de grupos de otros servidores",
"Search global and public address book for people" : "Buscar personas en las libretas de direcciones tanto global como pública",
"Allow people to publish their data to a global and public address book" : "Permitir a los usuarios publicar sus datos libretas de direcciones tanto global como pública",
"Unable to update federated files sharing config" : "No se pudo actualizar la configuración de intercambio federado de archivos",
"Federated Cloud" : "Nube Federada",
"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",
"Your Federated Cloud ID:" : "Tu ID de Nube Federada:",
"Share it so your friends can share files with you:" : "Compártelo para que tus amigos puedan compartir archivos contigo:",
"Facebook" : "Facebook",
"Twitter" : "Twitter",
"Diaspora" : "Diaspora",
"Add to your website" : "Agregar a tu sitio web",
"Share with me via Nextcloud" : "Compartir conmigo vía Nextcloud",
"HTML Code:" : "Código HTML:",
"Share with me through my #Nextcloud Federated Cloud ID, see {url}" : "Comparte conmigo a través de mi identificador de nube federada de #Nextcloud, vea {url}",
"Share with me through my #Nextcloud Federated Cloud ID" : "Compartir conmigo a través de mi ID de Nube Federada #Nextcloud",
"Cloud ID copied to the clipboard" : "Identificador de nube copiado al portapapeles",
"Copy to clipboard" : "Copiar al portapapeles",
"Clipboard is not available" : "El portapapeles no está disponible",
"Copied!" : "¡Copiado!",
"Sharing %1$s failed, because this item is already shared with user %2$s" : "No se pudo compartir %1$s, porque este elemento ya está compartido con el usuario %2$s",
"Not allowed to create a federated share with the same user" : "No está permitido crear un elelmento compartido federado con el mismo usuario",
"Adjust how people can share between servers. This includes shares between users on this server as well if they are using federated sharing." : "Ajustar la forma en que los usuarios comparten entre servidores. Esto incluye los recursos compartidos entre personas en este servidor, así como si hacen uso de intercambios federados.",
"Allow users on this server to send shares to other servers (this option also allows WebDAV access to public shares)" : "Permitir a los usuarios de este servidor de enviar recursos compartidos a otros servidores (esta opción también permite acceso WebDAV a los recursos compartidos públicos)",
"Allow users on this server to receive shares from other servers" : "Permitirle alos usuarios de este servidor recibir elementos compartidos de otros servidores",
"Allow users on this server to send shares to groups on other servers" : "Permitir a los usuarios de este servidor de enviar recursos compartidos a grupos de otros servidores",
"Allow users on this server to receive group shares from other servers" : "Permitir a los usuarios de este servidor de recibir recursos compartidos de grupos de otros servidores",
"Search global and public address book for users" : "Buscar usuarios en las libretas de contactos globales y públicas",
"Allow users to publish their data to a global and public address book" : "Permitirle a los usuarios publicar sus datos a una libreta de direcciones global y pública"
},

@ -10,7 +10,12 @@
"Couldn't establish a federated share, maybe the password was wrong." : "No fue posible establecer el elemento compartido federado, tal vez la contraseña sea incorrecta. ",
"Federated Share request sent, you will receive an invitation. Check your notifications." : "Solicitud de elemento compartido Federado enviada, recibiras una invitación. Verifica tus notificaciones.",
"Couldn't establish a federated share, it looks like the server to federate with is too old (Nextcloud <= 9)." : "No fue posible establecer el elemento compartido, parece que el servidor es obsoleto (Nextcloud <=9).",
"It is not allowed to send federated group shares from this server." : "No está permitido enviar recursos compartidos federados de grupos desde este servidor.",
"Sharing %1$s failed, because this item is already shared with the account %2$s" : "No se pudo compartir %1$s, porque este elemento ya está compartido con la cuenta %2$s",
"Not allowed to create a federated share to the same account" : "No está permitido crear un recurso compartido federado a la misma cuenta",
"Federated shares require read permissions" : "Los recursos compartidos federados requieren permiso de lectura",
"File is already shared with %s" : "El archivo ya ha sido compartido con %s",
"Sharing %1$s failed, could not find %2$s, maybe the server is currently unreachable or uses a self-signed certificate." : "Falló al compartir %1$s, no se pudo encontrar %2$s, quizás el servidor no se puede alcanzar en este momento o usa un certificado autofirmado.",
"Could not find share" : "No fue posible encontrar el elemento compartido",
"Federated sharing" : "Elementos compartidos",
"You received {share} as a remote share from {user} (on behalf of {behalf})" : "Has recibido {share} como un elemento compartido remoto de {user} (de parte de {behalf})",
@ -21,19 +26,37 @@
"Sharing" : "Compartiendo",
"Federated file sharing" : "Compartir elementos",
"Provide federated file sharing across servers" : "Provee el compartir archivos federados entre servidores",
"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 comparten entre servidores. Esto incluye los recursos compartidos entre usuarios en este servidor, así como si hacen uso de intercambios federados.",
"Allow people on this server to send shares to other servers (this option also allows WebDAV access to public shares)" : "Permitir a los usuarios de este servidor de enviar recursos compartidos a otros servidores (esta opción también permite el acceso WebDAV a los recursos compartidos públicos)",
"Allow people on this server to receive shares from other servers" : "Permitir a los usuarios de este servidor de recibir recursos compartidos desde otros servidores",
"Allow people on this server to send shares to groups on other servers" : "Permitir a los usuarios de este servidor de enviar recursos compartidos a grupos en otros servidores",
"Allow people on this server to receive group shares from other servers" : "Permitir a los usuarios de este servidor de recibir recursos compartidos de grupos de otros servidores",
"Search global and public address book for people" : "Buscar personas en las libretas de direcciones tanto global como pública",
"Allow people to publish their data to a global and public address book" : "Permitir a los usuarios publicar sus datos libretas de direcciones tanto global como pública",
"Unable to update federated files sharing config" : "No se pudo actualizar la configuración de intercambio federado de archivos",
"Federated Cloud" : "Nube Federada",
"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",
"Your Federated Cloud ID:" : "Tu ID de Nube Federada:",
"Share it so your friends can share files with you:" : "Compártelo para que tus amigos puedan compartir archivos contigo:",
"Facebook" : "Facebook",
"Twitter" : "Twitter",
"Diaspora" : "Diaspora",
"Add to your website" : "Agregar a tu sitio web",
"Share with me via Nextcloud" : "Compartir conmigo vía Nextcloud",
"HTML Code:" : "Código HTML:",
"Share with me through my #Nextcloud Federated Cloud ID, see {url}" : "Comparte conmigo a través de mi identificador de nube federada de #Nextcloud, vea {url}",
"Share with me through my #Nextcloud Federated Cloud ID" : "Compartir conmigo a través de mi ID de Nube Federada #Nextcloud",
"Cloud ID copied to the clipboard" : "Identificador de nube copiado al portapapeles",
"Copy to clipboard" : "Copiar al portapapeles",
"Clipboard is not available" : "El portapapeles no está disponible",
"Copied!" : "¡Copiado!",
"Sharing %1$s failed, because this item is already shared with user %2$s" : "No se pudo compartir %1$s, porque este elemento ya está compartido con el usuario %2$s",
"Not allowed to create a federated share with the same user" : "No está permitido crear un elelmento compartido federado con el mismo usuario",
"Adjust how people can share between servers. This includes shares between users on this server as well if they are using federated sharing." : "Ajustar la forma en que los usuarios comparten entre servidores. Esto incluye los recursos compartidos entre personas en este servidor, así como si hacen uso de intercambios federados.",
"Allow users on this server to send shares to other servers (this option also allows WebDAV access to public shares)" : "Permitir a los usuarios de este servidor de enviar recursos compartidos a otros servidores (esta opción también permite acceso WebDAV a los recursos compartidos públicos)",
"Allow users on this server to receive shares from other servers" : "Permitirle alos usuarios de este servidor recibir elementos compartidos de otros servidores",
"Allow users on this server to send shares to groups on other servers" : "Permitir a los usuarios de este servidor de enviar recursos compartidos a grupos de otros servidores",
"Allow users on this server to receive group shares from other servers" : "Permitir a los usuarios de este servidor de recibir recursos compartidos de grupos de otros servidores",
"Search global and public address book for users" : "Buscar usuarios en las libretas de contactos globales y públicas",
"Allow users to publish their data to a global and public address book" : "Permitirle a los usuarios publicar sus datos a una libreta de direcciones global y pública"
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"

@ -13,6 +13,7 @@ OC.L10N.register(
"Federated Share request sent, you will receive an invitation. Check your notifications." : "Federatutako partekatze eskaera bidali da, gonbidapena jasoko duzu. Begiratu jakinarazpenetan.",
"Couldn't establish a federated share, it looks like the server to federate with is too old (Nextcloud <= 9)." : "Ezin izan da federatutako partekatze bat ezarri, badirudi federatu nahi duzun zerbitzaria zaharregia dela (Nextcloud <= 9).",
"It is not allowed to send federated group shares from this server." : "Ezin dira federatutako talde-partekatzeak bidali zerbitzari honetatik.",
"Sharing %1$s failed, because this item is already shared with the account %2$s" : "%1$spartekatzeak huts egin du, dagoeneko %2$skontuarekin partekatuta dagoelako",
"Federated shares require read permissions" : "Federatutako partekatzeek irakurtzeko baimenak behar dituzte",
"File is already shared with %s" : "Fitxategia %s(r)ekin partekatuta dago jada",
"Sharing %1$s failed, could not find %2$s, maybe the server is currently unreachable or uses a self-signed certificate." : "%1$s partekatzeak huts egin du, ezin izan da %2$s aurkitu, agian zerbitzaria lineaz kanpo dago edo bere buruak sinatutako ziurtagiria darabil.",

@ -11,6 +11,7 @@
"Federated Share request sent, you will receive an invitation. Check your notifications." : "Federatutako partekatze eskaera bidali da, gonbidapena jasoko duzu. Begiratu jakinarazpenetan.",
"Couldn't establish a federated share, it looks like the server to federate with is too old (Nextcloud <= 9)." : "Ezin izan da federatutako partekatze bat ezarri, badirudi federatu nahi duzun zerbitzaria zaharregia dela (Nextcloud <= 9).",
"It is not allowed to send federated group shares from this server." : "Ezin dira federatutako talde-partekatzeak bidali zerbitzari honetatik.",
"Sharing %1$s failed, because this item is already shared with the account %2$s" : "%1$spartekatzeak huts egin du, dagoeneko %2$skontuarekin partekatuta dagoelako",
"Federated shares require read permissions" : "Federatutako partekatzeek irakurtzeko baimenak behar dituzte",
"File is already shared with %s" : "Fitxategia %s(r)ekin partekatuta dago jada",
"Sharing %1$s failed, could not find %2$s, maybe the server is currently unreachable or uses a self-signed certificate." : "%1$s partekatzeak huts egin du, ezin izan da %2$s aurkitu, agian zerbitzaria lineaz kanpo dago edo bere buruak sinatutako ziurtagiria darabil.",

@ -13,6 +13,8 @@ OC.L10N.register(
"Federated Share request sent, you will receive an invitation. Check your notifications." : "Wysłano żądanie Udostępniania Federacyjnego, otrzymasz zaproszenie. Sprawdzaj swoje powiadomienia.",
"Couldn't establish a federated share, it looks like the server to federate with is too old (Nextcloud <= 9)." : "Nie można ustanowić udostępniania federacyjnego. Wygląda na to, że serwer wybrany do udostępnienia jest zbyt stary (Nextcloud <= 9).",
"It is not allowed to send federated group shares from this server." : "Niedozwolone jest wysyłanie grupowych udostępnień federacyjnych z tego serwera.",
"Sharing %1$s failed, because this item is already shared with the account %2$s" : "Udostępnianie %1$s nie powiodło się, ponieważ ten element został już udostępniony kontu %2$s",
"Not allowed to create a federated share to the same account" : "Niedozwolone jest tworzenie udziału federacyjnego na tym samym koncie",
"Federated shares require read permissions" : "Udostępnienia federacyjne wymagają uprawnień do odczytu",
"File is already shared with %s" : "Plik jest już udostępniony dla %s",
"Sharing %1$s failed, could not find %2$s, maybe the server is currently unreachable or uses a self-signed certificate." : "Udostępnianie %1$s nie powiodło się, nie można odnaleźć %2$s, być może serwer jest nieosiągalny lub używa certyfikatu z podpisem własnym.",
@ -26,6 +28,13 @@ OC.L10N.register(
"Sharing" : "Udostępnianie",
"Federated file sharing" : "Udostępnianie federacyjne plików",
"Provide federated file sharing across servers" : "Zezwól na udostępnianie federacyjne plików na serwerach",
"Adjust how people can share between servers. This includes shares between people on this server as well if they are using federated sharing." : "Dostosuj sposób udostępniania między serwerami. Obejmuje to również udostępnianie między ludźmi na tym serwerze, jeśli korzystają z udostępniania federacyjnego.",
"Allow people on this server to send shares to other servers (this option also allows WebDAV access to public shares)" : "Zezwalaj ludziom na tym serwerze na wysłanie udostępnień do innych serwerów (opcja ta umożliwia również dostęp WebDAV do udostępnień publicznych)",
"Allow people on this server to receive shares from other servers" : "Zezwalaj osobom na tym serwerze na otrzymywanie współdzielenia z innych serwerów",
"Allow people on this server to send shares to groups on other servers" : "Zezwalaj osobom na tym serwerze na wysyłanie współdzielenia do grup na innych serwerach",
"Allow people on this server to receive group shares from other servers" : "Zezwalaj osobom na tym serwerze na otrzymywanie współdzielenia grupowego z innych serwerów",
"Search global and public address book for people" : "Przeszukuj globalną i publiczną książkę adresową osób",
"Allow people to publish their data to a global and public address book" : "Pozwól ludziom publikować swoje dane w globalnej i publicznej książce adresowej",
"Unable to update federated files sharing config" : "Nie można zaktualizować konfiguracji udostępniania federacyjnego plików",
"Federated Cloud" : "Chmura Federacyjna",
"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" : "Możesz udostępniać każdemu, kto używa serwera Nextcloud lub innych serwerów i usług kompatybilnych z Open Cloud Mesh (OCM). Wystarczy, że wpiszesz ID Chmury Federacyjnej w oknie udostępniania, według przykładu: osoba@chmura.przykładowa.com",

@ -11,6 +11,8 @@
"Federated Share request sent, you will receive an invitation. Check your notifications." : "Wysłano żądanie Udostępniania Federacyjnego, otrzymasz zaproszenie. Sprawdzaj swoje powiadomienia.",
"Couldn't establish a federated share, it looks like the server to federate with is too old (Nextcloud <= 9)." : "Nie można ustanowić udostępniania federacyjnego. Wygląda na to, że serwer wybrany do udostępnienia jest zbyt stary (Nextcloud <= 9).",
"It is not allowed to send federated group shares from this server." : "Niedozwolone jest wysyłanie grupowych udostępnień federacyjnych z tego serwera.",
"Sharing %1$s failed, because this item is already shared with the account %2$s" : "Udostępnianie %1$s nie powiodło się, ponieważ ten element został już udostępniony kontu %2$s",
"Not allowed to create a federated share to the same account" : "Niedozwolone jest tworzenie udziału federacyjnego na tym samym koncie",
"Federated shares require read permissions" : "Udostępnienia federacyjne wymagają uprawnień do odczytu",
"File is already shared with %s" : "Plik jest już udostępniony dla %s",
"Sharing %1$s failed, could not find %2$s, maybe the server is currently unreachable or uses a self-signed certificate." : "Udostępnianie %1$s nie powiodło się, nie można odnaleźć %2$s, być może serwer jest nieosiągalny lub używa certyfikatu z podpisem własnym.",
@ -24,6 +26,13 @@
"Sharing" : "Udostępnianie",
"Federated file sharing" : "Udostępnianie federacyjne plików",
"Provide federated file sharing across servers" : "Zezwól na udostępnianie federacyjne plików na serwerach",
"Adjust how people can share between servers. This includes shares between people on this server as well if they are using federated sharing." : "Dostosuj sposób udostępniania między serwerami. Obejmuje to również udostępnianie między ludźmi na tym serwerze, jeśli korzystają z udostępniania federacyjnego.",
"Allow people on this server to send shares to other servers (this option also allows WebDAV access to public shares)" : "Zezwalaj ludziom na tym serwerze na wysłanie udostępnień do innych serwerów (opcja ta umożliwia również dostęp WebDAV do udostępnień publicznych)",
"Allow people on this server to receive shares from other servers" : "Zezwalaj osobom na tym serwerze na otrzymywanie współdzielenia z innych serwerów",
"Allow people on this server to send shares to groups on other servers" : "Zezwalaj osobom na tym serwerze na wysyłanie współdzielenia do grup na innych serwerach",
"Allow people on this server to receive group shares from other servers" : "Zezwalaj osobom na tym serwerze na otrzymywanie współdzielenia grupowego z innych serwerów",
"Search global and public address book for people" : "Przeszukuj globalną i publiczną książkę adresową osób",
"Allow people to publish their data to a global and public address book" : "Pozwól ludziom publikować swoje dane w globalnej i publicznej książce adresowej",
"Unable to update federated files sharing config" : "Nie można zaktualizować konfiguracji udostępniania federacyjnego plików",
"Federated Cloud" : "Chmura Federacyjna",
"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" : "Możesz udostępniać każdemu, kto używa serwera Nextcloud lub innych serwerów i usług kompatybilnych z Open Cloud Mesh (OCM). Wystarczy, że wpiszesz ID Chmury Federacyjnej w oknie udostępniania, według przykładu: osoba@chmura.przykładowa.com",

@ -7,6 +7,9 @@ OC.L10N.register(
"Could not add server" : "Nie można dodać serwera",
"Trusted servers" : "Zaufane serwery",
"Federation" : "Federacja",
"Federation allows you to connect with other trusted servers to exchange the account directory." : "Federacja umożliwia łączenie się z innymi zaufanymi serwerami w celu wymiany katalogu kont.",
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing." : "Federacja umożliwia łączenie się z innymi zaufanymi serwerami w celu wymiany katalogu kont. Na przykład będzie to używane do automatycznego uzupełniania kont zewnętrznych na potrzeby udostępniania federacyjnego.",
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing. It is not necessary to add a server as trusted server in order to create a federated share." : "Federacja umożliwia łączenie się z innymi zaufanymi serwerami w celu wymiany katalogu kont. Na przykład zostanie to użyte do automatycznego uzupełniania dla zewnętrznych kont przy udostępnianiu federacyjnym. Nie jest konieczne dodawanie serwera jako serwera zaufanego w celu utworzenia udostępnienia federacyjnego.",
"+ Add trusted server" : "+ Dodaj zaufany serwer",
"Trusted server" : "Zaufany serwer",
"Add" : "Dodaj",

@ -5,6 +5,9 @@
"Could not add server" : "Nie można dodać serwera",
"Trusted servers" : "Zaufane serwery",
"Federation" : "Federacja",
"Federation allows you to connect with other trusted servers to exchange the account directory." : "Federacja umożliwia łączenie się z innymi zaufanymi serwerami w celu wymiany katalogu kont.",
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing." : "Federacja umożliwia łączenie się z innymi zaufanymi serwerami w celu wymiany katalogu kont. Na przykład będzie to używane do automatycznego uzupełniania kont zewnętrznych na potrzeby udostępniania federacyjnego.",
"Federation allows you to connect with other trusted servers to exchange the account directory. For example this will be used to auto-complete external accounts for federated sharing. It is not necessary to add a server as trusted server in order to create a federated share." : "Federacja umożliwia łączenie się z innymi zaufanymi serwerami w celu wymiany katalogu kont. Na przykład zostanie to użyte do automatycznego uzupełniania dla zewnętrznych kont przy udostępnianiu federacyjnym. Nie jest konieczne dodawanie serwera jako serwera zaufanego w celu utworzenia udostępnienia federacyjnego.",
"+ Add trusted server" : "+ Dodaj zaufany serwer",
"Trusted server" : "Zaufany serwer",
"Add" : "Dodaj",

@ -184,6 +184,7 @@ OC.L10N.register(
"Folder name" : "اسم المجلد",
"This node is unavailable" : "هذه العُقْدَة node غير متوفرة ",
"Download file {name}" : " تنزيل الملف {name}",
"Invalid file name" : "اسم الملف غير صحيح",
"\"{name}\" is not an allowed filetype." : "\"{name}\" ليس نوع ملف مسموحًا به.",
"{newName} already exists." : "{newName} موجود بالفعل.",
"\"{char}\" is not allowed inside a file name." : "\"{char}\" حرفٌ غير مسموح به في اسم الملف.",

@ -182,6 +182,7 @@
"Folder name" : "اسم المجلد",
"This node is unavailable" : "هذه العُقْدَة node غير متوفرة ",
"Download file {name}" : " تنزيل الملف {name}",
"Invalid file name" : "اسم الملف غير صحيح",
"\"{name}\" is not an allowed filetype." : "\"{name}\" ليس نوع ملف مسموحًا به.",
"{newName} already exists." : "{newName} موجود بالفعل.",
"\"{char}\" is not allowed inside a file name." : "\"{char}\" حرفٌ غير مسموح به في اسم الملف.",

@ -184,6 +184,7 @@ OC.L10N.register(
"Folder name" : "Nom de la carpeta",
"This node is unavailable" : "Aquest node no està disponible",
"Download file {name}" : "Baixa el fitxer {name}",
"Invalid file name" : "El nom del fitxer no és vàlid",
"\"{name}\" is not an allowed filetype." : "«{name}» no és un tipus de fitxer permès.",
"{newName} already exists." : "{newName} ja existeix.",
"\"{char}\" is not allowed inside a file name." : "El caràcter «{char}» no es pot utilitzar en el nom dels fitxers.",

@ -182,6 +182,7 @@
"Folder name" : "Nom de la carpeta",
"This node is unavailable" : "Aquest node no està disponible",
"Download file {name}" : "Baixa el fitxer {name}",
"Invalid file name" : "El nom del fitxer no és vàlid",
"\"{name}\" is not an allowed filetype." : "«{name}» no és un tipus de fitxer permès.",
"{newName} already exists." : "{newName} ja existeix.",
"\"{char}\" is not allowed inside a file name." : "El caràcter «{char}» no es pot utilitzar en el nom dels fitxers.",

@ -184,6 +184,7 @@ OC.L10N.register(
"Folder name" : "Název složky",
"This node is unavailable" : "Tento uzel není k dispozici",
"Download file {name}" : "Stáhnout soubor {name}",
"Invalid file name" : "Neplatný název souboru",
"\"{name}\" is not an allowed filetype." : "„{name}“ není dovoleným typem souboru.",
"{newName} already exists." : "{newName} už existuje.",
"\"{char}\" is not allowed inside a file name." : "„{char}“ není povolený znak v názvu souboru.",
@ -197,6 +198,7 @@ OC.L10N.register(
"Toggle selection for all files and folders" : "Vybrat / zrušit výběr všech souborů a složek",
"\"{displayName}\" failed on some elements " : "„{displayName}“ se pro některé prvky nezdařilo",
"\"{displayName}\" batch action executed successfully" : "hromadná akce „{displayName}“ úspěšně vykonána",
"{count} selected" : "vybráno {count}",
"List of files and folders." : "Seznam souborů a složek.",
"Column headers with buttons are sortable." : "Podle těch sloupců, které mají v záhlaví tlačítko, je možné řadit.",
"This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list." : "Seznam není vykreslen celý z důvodu nároků na výkon. Soubory budou dokreslovány, jak se budete posouvat seznamem.",
@ -297,9 +299,18 @@ OC.L10N.register(
"In folder" : "Ve složce",
"Search in folder: {folder}" : "Hledat ve složce: {folder}",
"One of the dropped files could not be processed" : "Jeden z přetažených souborů se nepodařilo zpracovat",
"Your browser does not support the Filesystem API. Directories will not be uploaded" : "Vámi využívaný prohlížeč nepodporuje aplikační program. rozhraní pro přístup k souborovému systému (Filesytem API). Složky nebudou nahrány",
"No files to upload" : "Ž8dné soubory k nahrání",
"Unable to create the directory {directory}" : "Nepodařilo se vytvořit složku {directory}",
"Some files could not be uploaded" : "Některé soubory nebylo možné nahrát",
"Files uploaded successfully" : "Soubor úspěšně nahrán",
"No files to process" : "Žádné soubory ke zpracování",
"Some files could not be copied" : "Některé soubory nebylo možné zkopírovat",
"Some files could not be moved" : "Některé soubory nebylo možné přesunout",
"Files copied successfully" : "Soubory úspěšně zkopírovány",
"Files moved successfully" : "Soubory úspěšně přesunuty",
"Conflicts resolution skipped" : "Řešení kolizí přeskočeno",
"Upload cancelled" : "Nahrávání zrušen",
"_{folderCount} folder_::_{folderCount} folders_" : ["{folderCount} složka","{folderCount} složky","{folderCount} složek","{folderCount} složky"],
"_{fileCount} file_::_{fileCount} files_" : ["{fileCount} soubor","{fileCount} soubory","{fileCount} souborů","{fileCount} soubory"],
"_1 file and {folderCount} folder_::_1 file and {folderCount} folders_" : ["1 soubor a {folderCount} složka","1 soubor a {folderCount} složky","1 soubor a {folderCount} složek","1 soubor a {folderCount} složky"],

@ -182,6 +182,7 @@
"Folder name" : "Název složky",
"This node is unavailable" : "Tento uzel není k dispozici",
"Download file {name}" : "Stáhnout soubor {name}",
"Invalid file name" : "Neplatný název souboru",
"\"{name}\" is not an allowed filetype." : "„{name}“ není dovoleným typem souboru.",
"{newName} already exists." : "{newName} už existuje.",
"\"{char}\" is not allowed inside a file name." : "„{char}“ není povolený znak v názvu souboru.",
@ -195,6 +196,7 @@
"Toggle selection for all files and folders" : "Vybrat / zrušit výběr všech souborů a složek",
"\"{displayName}\" failed on some elements " : "„{displayName}“ se pro některé prvky nezdařilo",
"\"{displayName}\" batch action executed successfully" : "hromadná akce „{displayName}“ úspěšně vykonána",
"{count} selected" : "vybráno {count}",
"List of files and folders." : "Seznam souborů a složek.",
"Column headers with buttons are sortable." : "Podle těch sloupců, které mají v záhlaví tlačítko, je možné řadit.",
"This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list." : "Seznam není vykreslen celý z důvodu nároků na výkon. Soubory budou dokreslovány, jak se budete posouvat seznamem.",
@ -295,9 +297,18 @@
"In folder" : "Ve složce",
"Search in folder: {folder}" : "Hledat ve složce: {folder}",
"One of the dropped files could not be processed" : "Jeden z přetažených souborů se nepodařilo zpracovat",
"Your browser does not support the Filesystem API. Directories will not be uploaded" : "Vámi využívaný prohlížeč nepodporuje aplikační program. rozhraní pro přístup k souborovému systému (Filesytem API). Složky nebudou nahrány",
"No files to upload" : "Ž8dné soubory k nahrání",
"Unable to create the directory {directory}" : "Nepodařilo se vytvořit složku {directory}",
"Some files could not be uploaded" : "Některé soubory nebylo možné nahrát",
"Files uploaded successfully" : "Soubor úspěšně nahrán",
"No files to process" : "Žádné soubory ke zpracování",
"Some files could not be copied" : "Některé soubory nebylo možné zkopírovat",
"Some files could not be moved" : "Některé soubory nebylo možné přesunout",
"Files copied successfully" : "Soubory úspěšně zkopírovány",
"Files moved successfully" : "Soubory úspěšně přesunuty",
"Conflicts resolution skipped" : "Řešení kolizí přeskočeno",
"Upload cancelled" : "Nahrávání zrušen",
"_{folderCount} folder_::_{folderCount} folders_" : ["{folderCount} složka","{folderCount} složky","{folderCount} složek","{folderCount} složky"],
"_{fileCount} file_::_{fileCount} files_" : ["{fileCount} soubor","{fileCount} soubory","{fileCount} souborů","{fileCount} soubory"],
"_1 file and {folderCount} folder_::_1 file and {folderCount} folders_" : ["1 soubor a {folderCount} složka","1 soubor a {folderCount} složky","1 soubor a {folderCount} složek","1 soubor a {folderCount} složky"],

@ -184,6 +184,7 @@ OC.L10N.register(
"Folder name" : "Ordnername",
"This node is unavailable" : "Dieser Knoten ist nicht verfügbar",
"Download file {name}" : "Datei {name} herunterladen",
"Invalid file name" : "Ungültiger Dateiname",
"\"{name}\" is not an allowed filetype." : "\"{name}\" ist kein zulässiger Dateityp.",
"{newName} already exists." : "{newName} existiert bereits.",
"\"{char}\" is not allowed inside a file name." : "\"{char}“ ist innerhalb eines Dateinamens nicht zulässig.",

@ -182,6 +182,7 @@
"Folder name" : "Ordnername",
"This node is unavailable" : "Dieser Knoten ist nicht verfügbar",
"Download file {name}" : "Datei {name} herunterladen",
"Invalid file name" : "Ungültiger Dateiname",
"\"{name}\" is not an allowed filetype." : "\"{name}\" ist kein zulässiger Dateityp.",
"{newName} already exists." : "{newName} existiert bereits.",
"\"{char}\" is not allowed inside a file name." : "\"{char}“ ist innerhalb eines Dateinamens nicht zulässig.",

@ -184,6 +184,7 @@ OC.L10N.register(
"Folder name" : "Folder name",
"This node is unavailable" : "This node is unavailable",
"Download file {name}" : "Download file {name}",
"Invalid file name" : "Invalid file name",
"\"{name}\" is not an allowed filetype." : "\"{name}\" is not an allowed filetype.",
"{newName} already exists." : "{newName} already exists.",
"\"{char}\" is not allowed inside a file name." : "\"{char}\" is not allowed inside a file name.",

@ -182,6 +182,7 @@
"Folder name" : "Folder name",
"This node is unavailable" : "This node is unavailable",
"Download file {name}" : "Download file {name}",
"Invalid file name" : "Invalid file name",
"\"{name}\" is not an allowed filetype." : "\"{name}\" is not an allowed filetype.",
"{newName} already exists." : "{newName} already exists.",
"\"{char}\" is not allowed inside a file name." : "\"{char}\" is not allowed inside a file name.",

@ -188,6 +188,7 @@ OC.L10N.register(
"Could not rename \"{oldName}\", it does not exist any more" : "Kohdetta \"{oldName}\" ei voitu nimetä uudelleen, koska sitä ei ole enää olemassa",
"The name \"{newName}\" is already used in the folder \"{dir}\". Please choose a different name." : "Nimi \"{newName}\" on jo käytössä kansiossa \"{dir}\". Valitse toinen nimi.",
"Could not rename \"{oldName}\"" : "Ei voitu nimetä uudelleen \"{oldName}\"",
"{count} selected" : "{count} valittu",
"List of files and folders." : "Luettelo tiedostoista ja kansioista.",
"Column headers with buttons are sortable." : "Painikkeilla varustetut sarakeotsikot ovat järjestettävissä.",
"This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list." : "Tätä luetteloa ei ole esitetty täysin suorituskykyyn liittyvistä syistä. Tiedostot esitetään sitä mukaa, kun selaat luetteloa.",
@ -266,6 +267,7 @@ OC.L10N.register(
"A file or folder with that name already exists in this folder" : "Tiedosto tai kansio tällä nimellä on jo olemassa tässä kansiossa",
"The files are locked" : "Tiedostot on lukittu",
"The file does not exist anymore" : "Tiedostoa ei ole enää olemassa",
"Choose destination" : "Valitse kohde",
"Copy to {target}" : "Kopioi kohteeseen {target}",
"Move to {target}" : "Siirrä kohteeseen {target}",
"Move or copy operation failed" : "Siirto- tai kopiointitoiminto epäonnistui",
@ -278,10 +280,18 @@ OC.L10N.register(
"Create new templates folder" : "Luo uusi mallipohjien kansio",
"Templates" : "Mallipohjat",
"New template folder" : "Uusi mallipohjien kansio",
"In folder" : "Kansiossa",
"Search in folder: {folder}" : "Etsi kansiosta: {folder}",
"Your browser does not support the Filesystem API. Directories will not be uploaded" : "Selaimesi ei tue Filesystem API -rajapintaa. Kansioita ei lähetetä",
"No files to upload" : "Ei lähetettäviä tiedostoja",
"Unable to create the directory {directory}" : "Kansiota {directory} ei voi luoda",
"Some files could not be uploaded" : "Joitain tiedostoja ei voitu lähettää",
"Files uploaded successfully" : "Tiedostot lähetetty onnistuneesti",
"No files to process" : "Ei tiedostoja käsiteltäväksi",
"Some files could not be copied" : "Joitain tiedostoja ei voitu kopioida",
"Some files could not be moved" : "Joitain tiedostoja ei voitu siirtää",
"Files copied successfully" : "Tiedostot kopioitu onnistuneesti",
"Files moved successfully" : "Tiedostot siirretty onnistuneesti",
"_{folderCount} folder_::_{folderCount} folders_" : ["{folderCount} kansio","{folderCount} kansiota"],
"_{fileCount} file_::_{fileCount} files_" : ["{fileCount} tiedosto","{fileCount} tiedostoa"],
"_1 file and {folderCount} folder_::_1 file and {folderCount} folders_" : ["1 tiedosto ja {folderCount} kansio","1 tiedosto ja {folderCount} kansiota"],

@ -186,6 +186,7 @@
"Could not rename \"{oldName}\", it does not exist any more" : "Kohdetta \"{oldName}\" ei voitu nimetä uudelleen, koska sitä ei ole enää olemassa",
"The name \"{newName}\" is already used in the folder \"{dir}\". Please choose a different name." : "Nimi \"{newName}\" on jo käytössä kansiossa \"{dir}\". Valitse toinen nimi.",
"Could not rename \"{oldName}\"" : "Ei voitu nimetä uudelleen \"{oldName}\"",
"{count} selected" : "{count} valittu",
"List of files and folders." : "Luettelo tiedostoista ja kansioista.",
"Column headers with buttons are sortable." : "Painikkeilla varustetut sarakeotsikot ovat järjestettävissä.",
"This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list." : "Tätä luetteloa ei ole esitetty täysin suorituskykyyn liittyvistä syistä. Tiedostot esitetään sitä mukaa, kun selaat luetteloa.",
@ -264,6 +265,7 @@
"A file or folder with that name already exists in this folder" : "Tiedosto tai kansio tällä nimellä on jo olemassa tässä kansiossa",
"The files are locked" : "Tiedostot on lukittu",
"The file does not exist anymore" : "Tiedostoa ei ole enää olemassa",
"Choose destination" : "Valitse kohde",
"Copy to {target}" : "Kopioi kohteeseen {target}",
"Move to {target}" : "Siirrä kohteeseen {target}",
"Move or copy operation failed" : "Siirto- tai kopiointitoiminto epäonnistui",
@ -276,10 +278,18 @@
"Create new templates folder" : "Luo uusi mallipohjien kansio",
"Templates" : "Mallipohjat",
"New template folder" : "Uusi mallipohjien kansio",
"In folder" : "Kansiossa",
"Search in folder: {folder}" : "Etsi kansiosta: {folder}",
"Your browser does not support the Filesystem API. Directories will not be uploaded" : "Selaimesi ei tue Filesystem API -rajapintaa. Kansioita ei lähetetä",
"No files to upload" : "Ei lähetettäviä tiedostoja",
"Unable to create the directory {directory}" : "Kansiota {directory} ei voi luoda",
"Some files could not be uploaded" : "Joitain tiedostoja ei voitu lähettää",
"Files uploaded successfully" : "Tiedostot lähetetty onnistuneesti",
"No files to process" : "Ei tiedostoja käsiteltäväksi",
"Some files could not be copied" : "Joitain tiedostoja ei voitu kopioida",
"Some files could not be moved" : "Joitain tiedostoja ei voitu siirtää",
"Files copied successfully" : "Tiedostot kopioitu onnistuneesti",
"Files moved successfully" : "Tiedostot siirretty onnistuneesti",
"_{folderCount} folder_::_{folderCount} folders_" : ["{folderCount} kansio","{folderCount} kansiota"],
"_{fileCount} file_::_{fileCount} files_" : ["{fileCount} tiedosto","{fileCount} tiedostoa"],
"_1 file and {folderCount} folder_::_1 file and {folderCount} folders_" : ["1 tiedosto ja {folderCount} kansio","1 tiedosto ja {folderCount} kansiota"],

@ -37,7 +37,7 @@ OC.L10N.register(
"Set reminder" : "Définir un rappel",
"Edit locally" : "Éditer localement",
"Open" : "Ouvrir",
"Delete file" : "Effacer le fichier ",
"Delete file" : "Supprimer le fichier ",
"Delete folder" : "Supprimer le dossier",
"Disconnect storage" : "Déconnecter ce support de stockage",
"Leave this share" : "Quitter ce partage",
@ -184,6 +184,7 @@ OC.L10N.register(
"Folder name" : "Nom du dossier",
"This node is unavailable" : "Ce nœud est indisponible ",
"Download file {name}" : "Télécharger le fichier {name}",
"Invalid file name" : "Nom de fichier invalide",
"\"{name}\" is not an allowed filetype." : "\"{name}\" n'est pas un type de fichier autorisé.",
"{newName} already exists." : "{newName} existe déjà.",
"\"{char}\" is not allowed inside a file name." : "\"{char}\" n'est pas autorisé dans un nom de fichier.",
@ -266,7 +267,7 @@ OC.L10N.register(
"Delete and unshare" : "Supprimer et ne plus partager",
"Leave these shares" : "Quitter ces partages",
"Disconnect storages" : "Déconnecter les supports de stockage",
"Delete files" : "Effacer les fichiers",
"Delete files" : "Supprimer les fichiers",
"Delete folders" : "Supprimer les dossiers",
"You are about to delete {count} items." : "Vous êtes sur le point de supprimer {count} éléments.",
"Confirm deletion" : "Confirmer la suppression",

@ -35,7 +35,7 @@
"Set reminder" : "Définir un rappel",
"Edit locally" : "Éditer localement",
"Open" : "Ouvrir",
"Delete file" : "Effacer le fichier ",
"Delete file" : "Supprimer le fichier ",
"Delete folder" : "Supprimer le dossier",
"Disconnect storage" : "Déconnecter ce support de stockage",
"Leave this share" : "Quitter ce partage",
@ -182,6 +182,7 @@
"Folder name" : "Nom du dossier",
"This node is unavailable" : "Ce nœud est indisponible ",
"Download file {name}" : "Télécharger le fichier {name}",
"Invalid file name" : "Nom de fichier invalide",
"\"{name}\" is not an allowed filetype." : "\"{name}\" n'est pas un type de fichier autorisé.",
"{newName} already exists." : "{newName} existe déjà.",
"\"{char}\" is not allowed inside a file name." : "\"{char}\" n'est pas autorisé dans un nom de fichier.",
@ -264,7 +265,7 @@
"Delete and unshare" : "Supprimer et ne plus partager",
"Leave these shares" : "Quitter ces partages",
"Disconnect storages" : "Déconnecter les supports de stockage",
"Delete files" : "Effacer les fichiers",
"Delete files" : "Supprimer les fichiers",
"Delete folders" : "Supprimer les dossiers",
"You are about to delete {count} items." : "Vous êtes sur le point de supprimer {count} éléments.",
"Confirm deletion" : "Confirmer la suppression",

@ -40,7 +40,7 @@ OC.L10N.register(
"Delete file" : "Eliminar ficheiro",
"Delete folder" : "Eliminar o cartafol",
"Disconnect storage" : "Desconectar o almacenamento",
"Leave this share" : "Deixa esta compartición",
"Leave this share" : "Deixar esta compartición",
"Could not load info for file \"{file}\"" : "Non foi posíbel cargar información para o ficheiro «{file}»",
"Files" : "Ficheiros",
"Details" : "Detalles",
@ -101,12 +101,12 @@ OC.L10N.register(
"Your storage is almost full ({usedSpacePercent}%)." : "O seu espazo de almacenamento está case cheo ({usedSpacePercent}%).",
"_matches \"{filter}\"_::_match \"{filter}\"_" : ["coincide con «{filter}»","coinciden con «{filter}»"],
"View in folder" : "Ver no cartafol",
"Direct link was copied (only works for people who have access to this file/folder)" : "Copiouse a ligazón directa (só funciona para persoas que teñan acceso a este ficheiro/cartafol)",
"Direct link was copied (only works for people who have access to this file/folder)" : "Foi copiada a ligazón directa (só funciona para as persoas que teñen acceso a este ficheiro/cartafol)",
"Path" : "Ruta",
"_%n byte_::_%n bytes_" : ["%n byte","%n bytes"],
"Favorited" : "Marcado como favorito",
"Favorite" : "Favorito",
"Copy direct link (only works for people who have access to this file/folder)" : "Copiar ligazón directa (só funciona para persoas que teñan acceso a este ficheiro/cartafol)",
"Copy direct link (only works for people who have access to this file/folder)" : "Copiar a ligazón directa (só funciona para persoas con acceso a este ficheiro/cartafol)",
"New folder" : "Novo cartafol",
"Create new folder" : "Crear un cartafol novo",
"Upload file" : "Enviar ficheiro",
@ -127,7 +127,7 @@ OC.L10N.register(
"Restored by {user}" : "Restaurado por {user}",
"Renamed by {user}" : "Renomeado por {user}",
"Moved by {user}" : "Movido por {user}",
"\"remote account\"" : "\"conta remota\"",
"\"remote account\"" : "«conta remota»",
"You created {file}" : "{file} foi creado por Vde.",
"You created an encrypted file in {file}" : "Vde. creo un ficheiro cifrado en {file}",
"{user} created {file}" : "{user} creou {file}",
@ -169,7 +169,7 @@ OC.L10N.register(
"The ownership transfer of {path} from {user} has completed." : "Completouse a transferencia da propiedade de {path} cara a {user}.",
"in %s" : "en %s",
"File Management" : "Xestión de ficheiros",
"Current directory path" : "Ruta actual do directorio",
"Current directory path" : "Ruta do directorio actual",
"Reload current directory" : "Recargar o directorio actual",
"Go to the \"{dir}\" directory" : "Vaia ao directorio «{dir}».",
"Drag and drop files here to upload" : "Arrastre e solte os ficheiros aquí para envialos",
@ -177,8 +177,8 @@ OC.L10N.register(
"You dont have permission to upload or create files here" : "Non ten permiso para enviar ou crear ficheiros aquí.",
"\"{displayName}\" action executed successfully" : "A acción «{displayName}» executouse correctamente",
"\"{displayName}\" action failed" : "A acción «{displayName}» fallou",
"Toggle selection for file \"{displayName}\"" : "Alternar a selección para o ficheiro \"{displayName}\"",
"Toggle selection for folder \"{displayName}\"" : "Alternar a selección para o cartafol \"{displayName}\"",
"Toggle selection for file \"{displayName}\"" : "Conmutar a selección para o ficheiro «{displayName}»",
"Toggle selection for folder \"{displayName}\"" : "Conmutar a selección para o cartafol «{displayName}»",
"Rename file" : "Renomear o ficheiro",
"File name" : "Nome de ficheiro",
"Folder name" : "Nome do cartafol",
@ -194,7 +194,7 @@ OC.L10N.register(
"The name \"{newName}\" is already used in the folder \"{dir}\". Please choose a different name." : "O nome «{newName}» xa se utiliza no cartafol «{dir}». Escolla un nome diferente.",
"Could not rename \"{oldName}\"" : "Non foi posíbel renomear «{oldName}»",
"Total rows summary" : "Resumo total de filas",
"Toggle selection for all files and folders" : "Alterna a selección para todos os ficheiros e cartafoles",
"Toggle selection for all files and folders" : "Conmutar a selección para todos os ficheiros e cartafoles",
"\"{displayName}\" failed on some elements " : "Produciuse un fallo nalgúns elementos de «{displayName}» ",
"\"{displayName}\" batch action executed successfully" : "A acción por lotes «{displayName}» executouse correctamente",
"List of files and folders." : "Lista de ficheiros e cartafoles",
@ -238,11 +238,11 @@ OC.L10N.register(
"Open the files app settings" : "Abrir os axustes da aplicación de ficheiros",
"Files settings" : "Axustes de Ficheiros",
"File cannot be accessed" : "Non é posíbel acceder ao ficheiro",
"The file could not be found or you do not have permissions to view it. Ask the sender to share it." : "Non foi posíbel atopar o ficheiro ou non tes permisos para velo. Solicita ao remitente que o comparta.",
"Your files" : "Os teus ficheiros",
"The file could not be found or you do not have permissions to view it. Ask the sender to share it." : "Non foi posíbel atopar o ficheiro ou non ten permiso para velo. Pídalle ao remitente que o comparta.",
"Your files" : "Os seus ficheiros",
"Open in files" : "Abrir en ficheiros",
"Sort favorites first" : "Ordene antes os favoritos",
"Sort folders before files" : "Ordenar cartafoles antes de ficheiros",
"Sort folders before files" : "Ordenar os cartafoles diante dos ficheiros",
"Show hidden files" : "Amosar os ficheiros agochados",
"Crop image previews" : "Recortar a vista previa das imaxes",
"Enable the grid view" : "Activar á vista de grade",
@ -262,12 +262,12 @@ OC.L10N.register(
"Blank" : "Baleiro",
"Unable to create new file from template" : "Non é posíbel crear un novo ficheiro a partir do modelo",
"Delete permanently" : "Eliminar definitivamente",
"Delete and unshare" : "Borrar e deixar de compartir",
"Leave these shares" : "Deixa estes compartidos",
"Disconnect storages" : "Desconecte os almacenamentos",
"Delete and unshare" : "Eliminar e deixar de compartir",
"Leave these shares" : "Deixar estas comparticións",
"Disconnect storages" : "Desconectar os almacenamentos",
"Delete files" : "Eliminar ficheiros",
"Delete folders" : "Borrar cartafoles",
"You are about to delete {count} items." : "Estás a piques de borrar {count} elementos.",
"Delete folders" : "Eliminar cartafoles",
"You are about to delete {count} items." : "Está a piques de eliminar {count} elementos.",
"Confirm deletion" : "Confirmar a eliminación",
"Cancel" : "Cancelar",
"Deletion cancelled" : "Cancelouse a eliminación",
@ -276,11 +276,11 @@ OC.L10N.register(
"You cannot move a file/folder onto itself or into a subfolder of itself" : "Non é posíbel mover un ficheiro/cartafol sobre si mesmo ou a un subcartafol de si mesmo",
"(copy)" : "(copiar)",
"(copy %n)" : "(copiar %n)",
"Move cancelled" : "Movemento cancelado",
"Move cancelled" : "Cancelouse o movemento",
"A file or folder with that name already exists in this folder" : "Neste cartafol xa existe un ficheiro ou cartafol con ese nome",
"The files are locked" : "Os ficheiros están bloqueados",
"The file does not exist anymore" : "O ficheiro xa non existe",
"Choose destination" : "Escolla o destino",
"Choose destination" : "Escoller o destino",
"Copy to {target}" : "Copiar en {target}",
"Move to {target}" : "Mover a {target}",
"Cancelled move or copy operation" : "Foi cancelada a operación de movemento ou copia",
@ -295,16 +295,16 @@ OC.L10N.register(
"Templates" : "Modelos",
"New template folder" : "Novo cartafol de modelos",
"In folder" : "No cartafol",
"Search in folder: {folder}" : "Busca no cartafol: {folder}",
"Search in folder: {folder}" : "Buscar no cartafol: {folder}",
"One of the dropped files could not be processed" : "Non foi posíbel procesar un dos ficheiros arrastrados",
"Your browser does not support the Filesystem API. Directories will not be uploaded" : "O teu navegador non é compatible coa API do sistema de ficheiros. Os directorios non se cargarán",
"No files to upload" : "Non hai ficheiros que cargar",
"Your browser does not support the Filesystem API. Directories will not be uploaded" : "O seu navegador non é compatíbel coa API do sistema de ficheiros. Os directorios non van ser enviados",
"No files to upload" : "Non hai ficheiros que enviar",
"Unable to create the directory {directory}" : "Non foi posíbel crear o directorio {directory}",
"Some files could not be uploaded" : "Algúns ficheiros non se puideron cargar",
"Some files could not be uploaded" : "Non foi posíbel enviar algúns ficheiros",
"Files uploaded successfully" : "Ficheiros cargados con éxito",
"No files to process" : "Non hai ficheiros para procesar",
"Some files could not be copied" : "Algúns ficheiros non se puideron copiar",
"Some files could not be moved" : "Algúns ficheiros non puideron seren movidos",
"Some files could not be copied" : "Non foi posíbel copiar algúns ficheiros",
"Some files could not be moved" : "Non foi posíbel mover algúns ficheiros",
"Files copied successfully" : "Copiáronse correctamente os ficheiros",
"Files moved successfully" : "Movéronse correctamente os ficheiros",
"Conflicts resolution skipped" : "Omitiuse a resolución dos conflitos",

@ -38,7 +38,7 @@
"Delete file" : "Eliminar ficheiro",
"Delete folder" : "Eliminar o cartafol",
"Disconnect storage" : "Desconectar o almacenamento",
"Leave this share" : "Deixa esta compartición",
"Leave this share" : "Deixar esta compartición",
"Could not load info for file \"{file}\"" : "Non foi posíbel cargar información para o ficheiro «{file}»",
"Files" : "Ficheiros",
"Details" : "Detalles",
@ -99,12 +99,12 @@
"Your storage is almost full ({usedSpacePercent}%)." : "O seu espazo de almacenamento está case cheo ({usedSpacePercent}%).",
"_matches \"{filter}\"_::_match \"{filter}\"_" : ["coincide con «{filter}»","coinciden con «{filter}»"],
"View in folder" : "Ver no cartafol",
"Direct link was copied (only works for people who have access to this file/folder)" : "Copiouse a ligazón directa (só funciona para persoas que teñan acceso a este ficheiro/cartafol)",
"Direct link was copied (only works for people who have access to this file/folder)" : "Foi copiada a ligazón directa (só funciona para as persoas que teñen acceso a este ficheiro/cartafol)",
"Path" : "Ruta",
"_%n byte_::_%n bytes_" : ["%n byte","%n bytes"],
"Favorited" : "Marcado como favorito",
"Favorite" : "Favorito",
"Copy direct link (only works for people who have access to this file/folder)" : "Copiar ligazón directa (só funciona para persoas que teñan acceso a este ficheiro/cartafol)",
"Copy direct link (only works for people who have access to this file/folder)" : "Copiar a ligazón directa (só funciona para persoas con acceso a este ficheiro/cartafol)",
"New folder" : "Novo cartafol",
"Create new folder" : "Crear un cartafol novo",
"Upload file" : "Enviar ficheiro",
@ -125,7 +125,7 @@
"Restored by {user}" : "Restaurado por {user}",
"Renamed by {user}" : "Renomeado por {user}",
"Moved by {user}" : "Movido por {user}",
"\"remote account\"" : "\"conta remota\"",
"\"remote account\"" : "«conta remota»",
"You created {file}" : "{file} foi creado por Vde.",
"You created an encrypted file in {file}" : "Vde. creo un ficheiro cifrado en {file}",
"{user} created {file}" : "{user} creou {file}",
@ -167,7 +167,7 @@
"The ownership transfer of {path} from {user} has completed." : "Completouse a transferencia da propiedade de {path} cara a {user}.",
"in %s" : "en %s",
"File Management" : "Xestión de ficheiros",
"Current directory path" : "Ruta actual do directorio",
"Current directory path" : "Ruta do directorio actual",
"Reload current directory" : "Recargar o directorio actual",
"Go to the \"{dir}\" directory" : "Vaia ao directorio «{dir}».",
"Drag and drop files here to upload" : "Arrastre e solte os ficheiros aquí para envialos",
@ -175,8 +175,8 @@
"You dont have permission to upload or create files here" : "Non ten permiso para enviar ou crear ficheiros aquí.",
"\"{displayName}\" action executed successfully" : "A acción «{displayName}» executouse correctamente",
"\"{displayName}\" action failed" : "A acción «{displayName}» fallou",
"Toggle selection for file \"{displayName}\"" : "Alternar a selección para o ficheiro \"{displayName}\"",
"Toggle selection for folder \"{displayName}\"" : "Alternar a selección para o cartafol \"{displayName}\"",
"Toggle selection for file \"{displayName}\"" : "Conmutar a selección para o ficheiro «{displayName}»",
"Toggle selection for folder \"{displayName}\"" : "Conmutar a selección para o cartafol «{displayName}»",
"Rename file" : "Renomear o ficheiro",
"File name" : "Nome de ficheiro",
"Folder name" : "Nome do cartafol",
@ -192,7 +192,7 @@
"The name \"{newName}\" is already used in the folder \"{dir}\". Please choose a different name." : "O nome «{newName}» xa se utiliza no cartafol «{dir}». Escolla un nome diferente.",
"Could not rename \"{oldName}\"" : "Non foi posíbel renomear «{oldName}»",
"Total rows summary" : "Resumo total de filas",
"Toggle selection for all files and folders" : "Alterna a selección para todos os ficheiros e cartafoles",
"Toggle selection for all files and folders" : "Conmutar a selección para todos os ficheiros e cartafoles",
"\"{displayName}\" failed on some elements " : "Produciuse un fallo nalgúns elementos de «{displayName}» ",
"\"{displayName}\" batch action executed successfully" : "A acción por lotes «{displayName}» executouse correctamente",
"List of files and folders." : "Lista de ficheiros e cartafoles",
@ -236,11 +236,11 @@
"Open the files app settings" : "Abrir os axustes da aplicación de ficheiros",
"Files settings" : "Axustes de Ficheiros",
"File cannot be accessed" : "Non é posíbel acceder ao ficheiro",
"The file could not be found or you do not have permissions to view it. Ask the sender to share it." : "Non foi posíbel atopar o ficheiro ou non tes permisos para velo. Solicita ao remitente que o comparta.",
"Your files" : "Os teus ficheiros",
"The file could not be found or you do not have permissions to view it. Ask the sender to share it." : "Non foi posíbel atopar o ficheiro ou non ten permiso para velo. Pídalle ao remitente que o comparta.",
"Your files" : "Os seus ficheiros",
"Open in files" : "Abrir en ficheiros",
"Sort favorites first" : "Ordene antes os favoritos",
"Sort folders before files" : "Ordenar cartafoles antes de ficheiros",
"Sort folders before files" : "Ordenar os cartafoles diante dos ficheiros",
"Show hidden files" : "Amosar os ficheiros agochados",
"Crop image previews" : "Recortar a vista previa das imaxes",
"Enable the grid view" : "Activar á vista de grade",
@ -260,12 +260,12 @@
"Blank" : "Baleiro",
"Unable to create new file from template" : "Non é posíbel crear un novo ficheiro a partir do modelo",
"Delete permanently" : "Eliminar definitivamente",
"Delete and unshare" : "Borrar e deixar de compartir",
"Leave these shares" : "Deixa estes compartidos",
"Disconnect storages" : "Desconecte os almacenamentos",
"Delete and unshare" : "Eliminar e deixar de compartir",
"Leave these shares" : "Deixar estas comparticións",
"Disconnect storages" : "Desconectar os almacenamentos",
"Delete files" : "Eliminar ficheiros",
"Delete folders" : "Borrar cartafoles",
"You are about to delete {count} items." : "Estás a piques de borrar {count} elementos.",
"Delete folders" : "Eliminar cartafoles",
"You are about to delete {count} items." : "Está a piques de eliminar {count} elementos.",
"Confirm deletion" : "Confirmar a eliminación",
"Cancel" : "Cancelar",
"Deletion cancelled" : "Cancelouse a eliminación",
@ -274,11 +274,11 @@
"You cannot move a file/folder onto itself or into a subfolder of itself" : "Non é posíbel mover un ficheiro/cartafol sobre si mesmo ou a un subcartafol de si mesmo",
"(copy)" : "(copiar)",
"(copy %n)" : "(copiar %n)",
"Move cancelled" : "Movemento cancelado",
"Move cancelled" : "Cancelouse o movemento",
"A file or folder with that name already exists in this folder" : "Neste cartafol xa existe un ficheiro ou cartafol con ese nome",
"The files are locked" : "Os ficheiros están bloqueados",
"The file does not exist anymore" : "O ficheiro xa non existe",
"Choose destination" : "Escolla o destino",
"Choose destination" : "Escoller o destino",
"Copy to {target}" : "Copiar en {target}",
"Move to {target}" : "Mover a {target}",
"Cancelled move or copy operation" : "Foi cancelada a operación de movemento ou copia",
@ -293,16 +293,16 @@
"Templates" : "Modelos",
"New template folder" : "Novo cartafol de modelos",
"In folder" : "No cartafol",
"Search in folder: {folder}" : "Busca no cartafol: {folder}",
"Search in folder: {folder}" : "Buscar no cartafol: {folder}",
"One of the dropped files could not be processed" : "Non foi posíbel procesar un dos ficheiros arrastrados",
"Your browser does not support the Filesystem API. Directories will not be uploaded" : "O teu navegador non é compatible coa API do sistema de ficheiros. Os directorios non se cargarán",
"No files to upload" : "Non hai ficheiros que cargar",
"Your browser does not support the Filesystem API. Directories will not be uploaded" : "O seu navegador non é compatíbel coa API do sistema de ficheiros. Os directorios non van ser enviados",
"No files to upload" : "Non hai ficheiros que enviar",
"Unable to create the directory {directory}" : "Non foi posíbel crear o directorio {directory}",
"Some files could not be uploaded" : "Algúns ficheiros non se puideron cargar",
"Some files could not be uploaded" : "Non foi posíbel enviar algúns ficheiros",
"Files uploaded successfully" : "Ficheiros cargados con éxito",
"No files to process" : "Non hai ficheiros para procesar",
"Some files could not be copied" : "Algúns ficheiros non se puideron copiar",
"Some files could not be moved" : "Algúns ficheiros non puideron seren movidos",
"Some files could not be copied" : "Non foi posíbel copiar algúns ficheiros",
"Some files could not be moved" : "Non foi posíbel mover algúns ficheiros",
"Files copied successfully" : "Copiáronse correctamente os ficheiros",
"Files moved successfully" : "Movéronse correctamente os ficheiros",
"Conflicts resolution skipped" : "Omitiuse a resolución dos conflitos",

@ -177,6 +177,8 @@ OC.L10N.register(
"You dont have permission to upload or create files here" : "Qui non hai i permessi per caricare o creare file",
"\"{displayName}\" action executed successfully" : "L'azione \"{displayName}\" è stata eseguita correttamente",
"\"{displayName}\" action failed" : "L'azione \"{displayName}\" non è riuscita",
"Toggle selection for file \"{displayName}\"" : "Attiva/disattiva la selezione per il file \"{displayName}\"",
"Toggle selection for folder \"{displayName}\"" : "Attiva/disattiva la selezione per la cartella \"{displayName}\"",
"Rename file" : "Rinomina file",
"File name" : "Nome file",
"Folder name" : "Nome della cartella",
@ -192,8 +194,10 @@ OC.L10N.register(
"The name \"{newName}\" is already used in the folder \"{dir}\". Please choose a different name." : "Il nome \"{newName}\" è attualmente in uso nella cartella \"{dir}\". Scegli un nome diverso.",
"Could not rename \"{oldName}\"" : "Impossibile rinominare \"{oldName}\"",
"Total rows summary" : "Riepilogo totale delle righe",
"Toggle selection for all files and folders" : "Attiva/disattiva la selezione per tutti i file e le cartelle",
"\"{displayName}\" failed on some elements " : "\"{displayName}\" non è riuscita su alcuni elementi",
"\"{displayName}\" batch action executed successfully" : "L'azione batch \"{displayName}\" è stata eseguita correttamente",
"{count} selected" : "{count} selezionati",
"List of files and folders." : "Lista di file e cartelle.",
"Column headers with buttons are sortable." : "Le intestazioni di colonna con pulsanti sono ordinabili.",
"This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list." : "Questa lista non è stata mostrata completamente per ragioni di prestazioni. I file verranno mostrati durante la navigazione della lista.",
@ -204,6 +208,7 @@ OC.L10N.register(
"Could not refresh storage stats" : "Impossibile aggiornare le statistiche di archiviazione",
"Your storage is full, files can not be updated or synced anymore!" : "Lo spazio di archiviazione è pieno, i file non possono essere più aggiornati o sincronizzati!",
"Create" : "Crea",
"A file or folder with that name already exists." : "Esiste già un file o una cartella con lo stesso nome.",
"Transfer ownership of a file or folder" : " Trasferisci la proprietà di un file o di una cartella",
"Choose file or folder to transfer" : "Scegli file o cartella da trasferire",
"Change" : "Modifica",
@ -234,6 +239,7 @@ OC.L10N.register(
"Open the files app settings" : "Apri le impostazioni dell'applicazione File",
"Files settings" : "Impostazioni File",
"File cannot be accessed" : "Il file non possono essere acceduti",
"The file could not be found or you do not have permissions to view it. Ask the sender to share it." : "Impossibile trovare il file oppure non disponi dei permessi per visualizzarlo. Chiedi al mittente di condividerlo.",
"Your files" : "I tuoi files",
"Open in files" : "Apri in file",
"Sort favorites first" : "Ordina prima i preferiti",
@ -258,6 +264,7 @@ OC.L10N.register(
"Unable to create new file from template" : "Impossibile creare un nuovo file dal modello",
"Delete permanently" : "Elimina permanentemente",
"Delete and unshare" : "Elimina e annulla la condivisione",
"Leave these shares" : "Abbandona queste condivisioni",
"Disconnect storages" : "Disconnetti il supporto di archiviazione",
"Delete files" : "Elimina i file",
"Delete folders" : "Elimina la cartella",
@ -287,10 +294,22 @@ OC.L10N.register(
"Unable to initialize the templates directory" : "Impossibile inizializzare la cartella dei modelli",
"Create new templates folder" : "Crea una nuova cartella dei modelli",
"Templates" : "Modelli",
"New template folder" : "Nuova cartella dei modelli",
"In folder" : "Nella cartella",
"Search in folder: {folder}" : "Cerca nella cartella: {folder}",
"One of the dropped files could not be processed" : "Impossibile elaborare uno dei file eliminati",
"Your browser does not support the Filesystem API. Directories will not be uploaded" : "Il tuo browser non supporta l'API del file system. Le directory non verranno caricate",
"No files to upload" : "Nessun file da caricare",
"Unable to create the directory {directory}" : "Impossibile creare la directory {directory}",
"Some files could not be uploaded" : "Alcuni file non possono essere caricati",
"Files uploaded successfully" : "Files caricati correttamente",
"No files to process" : "Nessun file da elaborare",
"Some files could not be copied" : "Alcuni file non possono essere copiati",
"Some files could not be moved" : "Alcuni file non possono essere spostati",
"Files copied successfully" : "File copiati correttamente",
"Files moved successfully" : "File spostati correttamente",
"Conflicts resolution skipped" : "Risoluzione dei conflitti saltata",
"Upload cancelled" : "Caricamento annullato",
"_{folderCount} folder_::_{folderCount} folders_" : ["{folderCount} cartella","{folderCount} cartelle","{folderCount} cartelle"],
"_{fileCount} file_::_{fileCount} files_" : ["{fileCount} file","{fileCount} file","{fileCount} file"],
"_1 file and {folderCount} folder_::_1 file and {folderCount} folders_" : ["1 file e {folderCount} cartella","1 file e {folderCount} cartelle","1 file e {folderCount} cartelle"],
@ -301,6 +320,10 @@ OC.L10N.register(
"Files and folders you mark as favorite will show up here" : "I file e le cartelle che marchi come preferiti saranno mostrati qui",
"All files" : "Tutti i file",
"List of your files and folders." : "Lista dei tuoi file e cartelle.",
"Personal Files" : "File personali",
"List of your files and folders that are not shared." : "Elenco dei file e delle cartelle che non sono condivisi.",
"No personal files found" : "Nessun file personale trovato",
"Files that are not shared will show up here." : "I file che non vengono condivisi verranno visualizzati qui.",
"List of recently modified files and folders." : "Lista di file e cartelle modificati di recente.",
"No recently modified files" : "Nessun file modificato di recente",
"Files and folders you recently modified will show up here." : "I file e le cartelle che hai modificato di recente saranno mostrati qui.",

@ -175,6 +175,8 @@
"You dont have permission to upload or create files here" : "Qui non hai i permessi per caricare o creare file",
"\"{displayName}\" action executed successfully" : "L'azione \"{displayName}\" è stata eseguita correttamente",
"\"{displayName}\" action failed" : "L'azione \"{displayName}\" non è riuscita",
"Toggle selection for file \"{displayName}\"" : "Attiva/disattiva la selezione per il file \"{displayName}\"",
"Toggle selection for folder \"{displayName}\"" : "Attiva/disattiva la selezione per la cartella \"{displayName}\"",
"Rename file" : "Rinomina file",
"File name" : "Nome file",
"Folder name" : "Nome della cartella",
@ -190,8 +192,10 @@
"The name \"{newName}\" is already used in the folder \"{dir}\". Please choose a different name." : "Il nome \"{newName}\" è attualmente in uso nella cartella \"{dir}\". Scegli un nome diverso.",
"Could not rename \"{oldName}\"" : "Impossibile rinominare \"{oldName}\"",
"Total rows summary" : "Riepilogo totale delle righe",
"Toggle selection for all files and folders" : "Attiva/disattiva la selezione per tutti i file e le cartelle",
"\"{displayName}\" failed on some elements " : "\"{displayName}\" non è riuscita su alcuni elementi",
"\"{displayName}\" batch action executed successfully" : "L'azione batch \"{displayName}\" è stata eseguita correttamente",
"{count} selected" : "{count} selezionati",
"List of files and folders." : "Lista di file e cartelle.",
"Column headers with buttons are sortable." : "Le intestazioni di colonna con pulsanti sono ordinabili.",
"This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list." : "Questa lista non è stata mostrata completamente per ragioni di prestazioni. I file verranno mostrati durante la navigazione della lista.",
@ -202,6 +206,7 @@
"Could not refresh storage stats" : "Impossibile aggiornare le statistiche di archiviazione",
"Your storage is full, files can not be updated or synced anymore!" : "Lo spazio di archiviazione è pieno, i file non possono essere più aggiornati o sincronizzati!",
"Create" : "Crea",
"A file or folder with that name already exists." : "Esiste già un file o una cartella con lo stesso nome.",
"Transfer ownership of a file or folder" : " Trasferisci la proprietà di un file o di una cartella",
"Choose file or folder to transfer" : "Scegli file o cartella da trasferire",
"Change" : "Modifica",
@ -232,6 +237,7 @@
"Open the files app settings" : "Apri le impostazioni dell'applicazione File",
"Files settings" : "Impostazioni File",
"File cannot be accessed" : "Il file non possono essere acceduti",
"The file could not be found or you do not have permissions to view it. Ask the sender to share it." : "Impossibile trovare il file oppure non disponi dei permessi per visualizzarlo. Chiedi al mittente di condividerlo.",
"Your files" : "I tuoi files",
"Open in files" : "Apri in file",
"Sort favorites first" : "Ordina prima i preferiti",
@ -256,6 +262,7 @@
"Unable to create new file from template" : "Impossibile creare un nuovo file dal modello",
"Delete permanently" : "Elimina permanentemente",
"Delete and unshare" : "Elimina e annulla la condivisione",
"Leave these shares" : "Abbandona queste condivisioni",
"Disconnect storages" : "Disconnetti il supporto di archiviazione",
"Delete files" : "Elimina i file",
"Delete folders" : "Elimina la cartella",
@ -285,10 +292,22 @@
"Unable to initialize the templates directory" : "Impossibile inizializzare la cartella dei modelli",
"Create new templates folder" : "Crea una nuova cartella dei modelli",
"Templates" : "Modelli",
"New template folder" : "Nuova cartella dei modelli",
"In folder" : "Nella cartella",
"Search in folder: {folder}" : "Cerca nella cartella: {folder}",
"One of the dropped files could not be processed" : "Impossibile elaborare uno dei file eliminati",
"Your browser does not support the Filesystem API. Directories will not be uploaded" : "Il tuo browser non supporta l'API del file system. Le directory non verranno caricate",
"No files to upload" : "Nessun file da caricare",
"Unable to create the directory {directory}" : "Impossibile creare la directory {directory}",
"Some files could not be uploaded" : "Alcuni file non possono essere caricati",
"Files uploaded successfully" : "Files caricati correttamente",
"No files to process" : "Nessun file da elaborare",
"Some files could not be copied" : "Alcuni file non possono essere copiati",
"Some files could not be moved" : "Alcuni file non possono essere spostati",
"Files copied successfully" : "File copiati correttamente",
"Files moved successfully" : "File spostati correttamente",
"Conflicts resolution skipped" : "Risoluzione dei conflitti saltata",
"Upload cancelled" : "Caricamento annullato",
"_{folderCount} folder_::_{folderCount} folders_" : ["{folderCount} cartella","{folderCount} cartelle","{folderCount} cartelle"],
"_{fileCount} file_::_{fileCount} files_" : ["{fileCount} file","{fileCount} file","{fileCount} file"],
"_1 file and {folderCount} folder_::_1 file and {folderCount} folders_" : ["1 file e {folderCount} cartella","1 file e {folderCount} cartelle","1 file e {folderCount} cartelle"],
@ -299,6 +318,10 @@
"Files and folders you mark as favorite will show up here" : "I file e le cartelle che marchi come preferiti saranno mostrati qui",
"All files" : "Tutti i file",
"List of your files and folders." : "Lista dei tuoi file e cartelle.",
"Personal Files" : "File personali",
"List of your files and folders that are not shared." : "Elenco dei file e delle cartelle che non sono condivisi.",
"No personal files found" : "Nessun file personale trovato",
"Files that are not shared will show up here." : "I file che non vengono condivisi verranno visualizzati qui.",
"List of recently modified files and folders." : "Lista di file e cartelle modificati di recente.",
"No recently modified files" : "Nessun file modificato di recente",
"Files and folders you recently modified will show up here." : "I file e le cartelle che hai modificato di recente saranno mostrati qui.",

@ -197,6 +197,7 @@ OC.L10N.register(
"Toggle selection for all files and folders" : "모든 파일 선택/선택해제",
"\"{displayName}\" failed on some elements " : "\"{displayName}\" 이 일부 요소들에서 실패함",
"\"{displayName}\" batch action executed successfully" : "\"{displayName}\" 일괄 작업을 성공적으로 실행함",
"{count} selected" : "{count}개 선택됨",
"List of files and folders." : "파일과 폴더의 목록",
"Column headers with buttons are sortable." : "버튼이 있는 열 머리글은 정렬할 수 있습니다.",
"This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list." : "성능 상의 이유로 목록을 전부 표시하지 않았습니다. 목록을 탐색하면 파일들이 표시됩니다.",
@ -296,9 +297,17 @@ OC.L10N.register(
"New template folder" : "새 템플릿 폴더",
"Search in folder: {folder}" : "폴더에서 검색: {folder}",
"One of the dropped files could not be processed" : "드롭한 파일 중 하나를 처리할 수 없습니다",
"Your browser does not support the Filesystem API. Directories will not be uploaded" : "이 브라우저는 Filesystem API를 지원하지 않습니다. 디렉토리가 업로드 되지 않을 것입니다.",
"No files to upload" : "업로드할 파일이 없음",
"Unable to create the directory {directory}" : "디렉토리 {directory}을(를) 생성할 수 없음",
"Some files could not be uploaded" : "일부 파일을 업로드할 수 없었습니다.",
"Files uploaded successfully" : "파일을 성공적으로 업로드했습니다.",
"No files to process" : "처리할 파일이 없음",
"Some files could not be copied" : "일부 파일을 복사할 수 없음",
"Some files could not be moved" : "일부 파일을 이동할 수 없음",
"Files copied successfully" : "파일을 성공적으로 복사함",
"Files moved successfully" : "파일을 성공적으로 이동함",
"Upload cancelled" : "업로드가 취소됨",
"_{folderCount} folder_::_{folderCount} folders_" : ["{folderCount}개 폴더"],
"_{fileCount} file_::_{fileCount} files_" : ["{fileCount}개 파일"],
"_1 file and {folderCount} folder_::_1 file and {folderCount} folders_" : ["1개 파일과 {folderCount}개 폴더"],

@ -195,6 +195,7 @@
"Toggle selection for all files and folders" : "모든 파일 선택/선택해제",
"\"{displayName}\" failed on some elements " : "\"{displayName}\" 이 일부 요소들에서 실패함",
"\"{displayName}\" batch action executed successfully" : "\"{displayName}\" 일괄 작업을 성공적으로 실행함",
"{count} selected" : "{count}개 선택됨",
"List of files and folders." : "파일과 폴더의 목록",
"Column headers with buttons are sortable." : "버튼이 있는 열 머리글은 정렬할 수 있습니다.",
"This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list." : "성능 상의 이유로 목록을 전부 표시하지 않았습니다. 목록을 탐색하면 파일들이 표시됩니다.",
@ -294,9 +295,17 @@
"New template folder" : "새 템플릿 폴더",
"Search in folder: {folder}" : "폴더에서 검색: {folder}",
"One of the dropped files could not be processed" : "드롭한 파일 중 하나를 처리할 수 없습니다",
"Your browser does not support the Filesystem API. Directories will not be uploaded" : "이 브라우저는 Filesystem API를 지원하지 않습니다. 디렉토리가 업로드 되지 않을 것입니다.",
"No files to upload" : "업로드할 파일이 없음",
"Unable to create the directory {directory}" : "디렉토리 {directory}을(를) 생성할 수 없음",
"Some files could not be uploaded" : "일부 파일을 업로드할 수 없었습니다.",
"Files uploaded successfully" : "파일을 성공적으로 업로드했습니다.",
"No files to process" : "처리할 파일이 없음",
"Some files could not be copied" : "일부 파일을 복사할 수 없음",
"Some files could not be moved" : "일부 파일을 이동할 수 없음",
"Files copied successfully" : "파일을 성공적으로 복사함",
"Files moved successfully" : "파일을 성공적으로 이동함",
"Upload cancelled" : "업로드가 취소됨",
"_{folderCount} folder_::_{folderCount} folders_" : ["{folderCount}개 폴더"],
"_{fileCount} file_::_{fileCount} files_" : ["{fileCount}개 파일"],
"_1 file and {folderCount} folder_::_1 file and {folderCount} folders_" : ["1개 파일과 {folderCount}개 폴더"],

@ -197,6 +197,7 @@ OC.L10N.register(
"Toggle selection for all files and folders" : "Veksle valg for alle filer og mapper",
"\"{displayName}\" failed on some elements " : "\"{displayName}\" feilet på noen elementer",
"\"{displayName}\" batch action executed successfully" : "\"{displayName}\" massehandling utført",
"{count} selected" : "{count} valgt",
"List of files and folders." : "Liste over filer og mapper.",
"Column headers with buttons are sortable." : "Kolonneoverskrifter med knapper kan sorteres.",
"This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list." : "Denne listen er ikke fullstendig gjengitt av ytelsesgrunner. Filene gjengis når du navigerer gjennom listen.",

@ -195,6 +195,7 @@
"Toggle selection for all files and folders" : "Veksle valg for alle filer og mapper",
"\"{displayName}\" failed on some elements " : "\"{displayName}\" feilet på noen elementer",
"\"{displayName}\" batch action executed successfully" : "\"{displayName}\" massehandling utført",
"{count} selected" : "{count} valgt",
"List of files and folders." : "Liste over filer og mapper.",
"Column headers with buttons are sortable." : "Kolonneoverskrifter med knapper kan sorteres.",
"This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list." : "Denne listen er ikke fullstendig gjengitt av ytelsesgrunner. Filene gjengis når du navigerer gjennom listen.",

@ -197,6 +197,7 @@ OC.L10N.register(
"Toggle selection for all files and folders" : "Przełącz zaznaczenie dla wszystkich plików i katalogów",
"\"{displayName}\" failed on some elements " : "\"{displayName}\" nie powiodło się w przypadku niektórych elementów",
"\"{displayName}\" batch action executed successfully" : "Akcja wsadowa \"{displayName}\" została wykonana pomyślnie",
"{count} selected" : "wybrano {count}",
"List of files and folders." : "Lista plików i katalogów.",
"Column headers with buttons are sortable." : "Nagłówki kolumn z przyciskami są sortowalne.",
"This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list." : "Ta lista nie jest w pełni renderowana ze względu na wydajność. Pliki będą renderowane podczas poruszania się po liście.",
@ -293,12 +294,22 @@ OC.L10N.register(
"Unable to initialize the templates directory" : "Nie można zainicjować katalogu szablonów",
"Create new templates folder" : "Stwórz nowy folder z szablonami",
"Templates" : "Szablony",
"New template folder" : "Nowy katalog szablonów",
"In folder" : "W katalogu",
"Search in folder: {folder}" : "Szukaj w katalogu: {folder}",
"One of the dropped files could not be processed" : "Jeden z upuszczonych plików nie mógł być przetworzony",
"Your browser does not support the Filesystem API. Directories will not be uploaded" : "Twoja przeglądarka nie obsługuje interfejsu API systemu plików. Katalogi nie zostaną przesłane",
"No files to upload" : "Brak plików do przesłania",
"Unable to create the directory {directory}" : "Nie można utworzyć katalogu {directory}",
"Some files could not be uploaded" : "Nie udało się wysłać niektórych plików",
"Files uploaded successfully" : "Pliki przesłane pomyślnie",
"No files to process" : "Brak plików do przetworzenia",
"Some files could not be copied" : "Nie udało się skopiować niektórych plików",
"Some files could not be moved" : "Niektóre pliki nie mogły zostać przeniesione",
"Files copied successfully" : "Pliki skopiowane pomyślnie",
"Files moved successfully" : "Pliki zostały przeniesione pomyślnie",
"Conflicts resolution skipped" : "Pominięto rozwiązywanie konfliktów",
"Upload cancelled" : "Anulowano przesyłanie",
"_{folderCount} folder_::_{folderCount} folders_" : ["{folderCount} katalog","{folderCount} katalogi","{folderCount} katalogów","{folderCount} katalogów"],
"_{fileCount} file_::_{fileCount} files_" : ["{fileCount} plik","{fileCount} pliki","{fileCount} plików","{fileCount} plików"],
"_1 file and {folderCount} folder_::_1 file and {folderCount} folders_" : ["1 plik i {folderCount} katalog","1 plik i {folderCount} katalogi","1 plik i {folderCount} katalogów","1 plik i {folderCount} katalogów"],

@ -195,6 +195,7 @@
"Toggle selection for all files and folders" : "Przełącz zaznaczenie dla wszystkich plików i katalogów",
"\"{displayName}\" failed on some elements " : "\"{displayName}\" nie powiodło się w przypadku niektórych elementów",
"\"{displayName}\" batch action executed successfully" : "Akcja wsadowa \"{displayName}\" została wykonana pomyślnie",
"{count} selected" : "wybrano {count}",
"List of files and folders." : "Lista plików i katalogów.",
"Column headers with buttons are sortable." : "Nagłówki kolumn z przyciskami są sortowalne.",
"This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list." : "Ta lista nie jest w pełni renderowana ze względu na wydajność. Pliki będą renderowane podczas poruszania się po liście.",
@ -291,12 +292,22 @@
"Unable to initialize the templates directory" : "Nie można zainicjować katalogu szablonów",
"Create new templates folder" : "Stwórz nowy folder z szablonami",
"Templates" : "Szablony",
"New template folder" : "Nowy katalog szablonów",
"In folder" : "W katalogu",
"Search in folder: {folder}" : "Szukaj w katalogu: {folder}",
"One of the dropped files could not be processed" : "Jeden z upuszczonych plików nie mógł być przetworzony",
"Your browser does not support the Filesystem API. Directories will not be uploaded" : "Twoja przeglądarka nie obsługuje interfejsu API systemu plików. Katalogi nie zostaną przesłane",
"No files to upload" : "Brak plików do przesłania",
"Unable to create the directory {directory}" : "Nie można utworzyć katalogu {directory}",
"Some files could not be uploaded" : "Nie udało się wysłać niektórych plików",
"Files uploaded successfully" : "Pliki przesłane pomyślnie",
"No files to process" : "Brak plików do przetworzenia",
"Some files could not be copied" : "Nie udało się skopiować niektórych plików",
"Some files could not be moved" : "Niektóre pliki nie mogły zostać przeniesione",
"Files copied successfully" : "Pliki skopiowane pomyślnie",
"Files moved successfully" : "Pliki zostały przeniesione pomyślnie",
"Conflicts resolution skipped" : "Pominięto rozwiązywanie konfliktów",
"Upload cancelled" : "Anulowano przesyłanie",
"_{folderCount} folder_::_{folderCount} folders_" : ["{folderCount} katalog","{folderCount} katalogi","{folderCount} katalogów","{folderCount} katalogów"],
"_{fileCount} file_::_{fileCount} files_" : ["{fileCount} plik","{fileCount} pliki","{fileCount} plików","{fileCount} plików"],
"_1 file and {folderCount} folder_::_1 file and {folderCount} folders_" : ["1 plik i {folderCount} katalog","1 plik i {folderCount} katalogi","1 plik i {folderCount} katalogów","1 plik i {folderCount} katalogów"],

@ -197,6 +197,7 @@ OC.L10N.register(
"Toggle selection for all files and folders" : "Prepnúť výber pre všetky súbory a adresáre",
"\"{displayName}\" failed on some elements " : "\"{displayName}\" zlyhalo na niektorých prvkoch.",
"\"{displayName}\" batch action executed successfully" : "Hromadná operácia \"{displayName}\" bola úspešne vykonaná",
"{count} selected" : "{count} vybraných",
"List of files and folders." : "Zoznam súborov a priečinkov.",
"Column headers with buttons are sortable." : "Stĺpce hlavičiek s tlačidlami sú triediteľné.",
"This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list." : "Tento zoznam nie je úplne vykreslený z dôvodov výkonu. Súbory budú vykreslené, keď budete prechádzať zoznamom.",

@ -195,6 +195,7 @@
"Toggle selection for all files and folders" : "Prepnúť výber pre všetky súbory a adresáre",
"\"{displayName}\" failed on some elements " : "\"{displayName}\" zlyhalo na niektorých prvkoch.",
"\"{displayName}\" batch action executed successfully" : "Hromadná operácia \"{displayName}\" bola úspešne vykonaná",
"{count} selected" : "{count} vybraných",
"List of files and folders." : "Zoznam súborov a priečinkov.",
"Column headers with buttons are sortable." : "Stĺpce hlavičiek s tlačidlami sú triediteľné.",
"This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list." : "Tento zoznam nie je úplne vykreslený z dôvodov výkonu. Súbory budú vykreslené, keď budete prechádzať zoznamom.",

@ -184,6 +184,7 @@ OC.L10N.register(
"Folder name" : "Назив фасцикле",
"This node is unavailable" : "Овај чвор није доступан",
"Download file {name}" : "Преузми фајл {name}",
"Invalid file name" : "Неисправно име фајла",
"\"{name}\" is not an allowed filetype." : "„{name}” није дозвољени тип фајла.",
"{newName} already exists." : "{newName} већ постоји.",
"\"{char}\" is not allowed inside a file name." : "„{char}“ није дозвољен каракетер у имену фајла.",
@ -197,6 +198,7 @@ OC.L10N.register(
"Toggle selection for all files and folders" : "Укљ./искљ. избор за све фајлове и фолдере",
"\"{displayName}\" failed on some elements " : "„{displayName}” није успело на неким елементима",
"\"{displayName}\" batch action executed successfully" : "Пакетна акција „{displayName}” се успешно извршила",
"{count} selected" : "{count} изабрано",
"List of files and folders." : "Листа фајлова и фолдера.",
"Column headers with buttons are sortable." : "Заглавља колона са дугмићима могу да се соритрају.",
"This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list." : "Ова листа није у потпуности приказана из разлога перформанси. Фајлови ће се приказивати како се крећете кроз листу.",

@ -182,6 +182,7 @@
"Folder name" : "Назив фасцикле",
"This node is unavailable" : "Овај чвор није доступан",
"Download file {name}" : "Преузми фајл {name}",
"Invalid file name" : "Неисправно име фајла",
"\"{name}\" is not an allowed filetype." : "„{name}” није дозвољени тип фајла.",
"{newName} already exists." : "{newName} већ постоји.",
"\"{char}\" is not allowed inside a file name." : "„{char}“ није дозвољен каракетер у имену фајла.",
@ -195,6 +196,7 @@
"Toggle selection for all files and folders" : "Укљ./искљ. избор за све фајлове и фолдере",
"\"{displayName}\" failed on some elements " : "„{displayName}” није успело на неким елементима",
"\"{displayName}\" batch action executed successfully" : "Пакетна акција „{displayName}” се успешно извршила",
"{count} selected" : "{count} изабрано",
"List of files and folders." : "Листа фајлова и фолдера.",
"Column headers with buttons are sortable." : "Заглавља колона са дугмићима могу да се соритрају.",
"This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list." : "Ова листа није у потпуности приказана из разлога перформанси. Фајлови ће се приказивати како се крећете кроз листу.",

@ -197,6 +197,7 @@ OC.L10N.register(
"Toggle selection for all files and folders" : "Växla markering för alla filer och mappar",
"\"{displayName}\" failed on some elements " : "\"{displayName}\" misslyckades med vissa element",
"\"{displayName}\" batch action executed successfully" : "Batchåtgärden \"{displayName}\" har utförts",
"{count} selected" : "{count} valda",
"List of files and folders." : "Lista över filer och mappar.",
"Column headers with buttons are sortable." : "Kolumnrubriker med knappar är sorterbara.",
"This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list." : "Denna lista är inte helt återgiven av prestandaskäl. Filerna kommer att renderas när du navigerar genom listan.",

@ -195,6 +195,7 @@
"Toggle selection for all files and folders" : "Växla markering för alla filer och mappar",
"\"{displayName}\" failed on some elements " : "\"{displayName}\" misslyckades med vissa element",
"\"{displayName}\" batch action executed successfully" : "Batchåtgärden \"{displayName}\" har utförts",
"{count} selected" : "{count} valda",
"List of files and folders." : "Lista över filer och mappar.",
"Column headers with buttons are sortable." : "Kolumnrubriker med knappar är sorterbara.",
"This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list." : "Denna lista är inte helt återgiven av prestandaskäl. Filerna kommer att renderas när du navigerar genom listan.",

@ -184,6 +184,7 @@ OC.L10N.register(
"Folder name" : "Klasör adı",
"This node is unavailable" : "Bu düğüm kullanılamıyor",
"Download file {name}" : "{name} dosyasını indir",
"Invalid file name" : "Dosya adı geçersiz",
"\"{name}\" is not an allowed filetype." : "\"{name}\" dosya türüne izin verilmiyor.",
"{newName} already exists." : "{newName} zaten var.",
"\"{char}\" is not allowed inside a file name." : "Dosya adlarında \"{char}\" karakteri kullanılamaz.",
@ -197,6 +198,7 @@ OC.L10N.register(
"Toggle selection for all files and folders" : "Tüm dosyaları ve klasörleri seç/bırak",
"\"{displayName}\" failed on some elements " : "\"{displayName}\" toplu işlemi bazı bileşenlerde tamamlanamadı",
"\"{displayName}\" batch action executed successfully" : "\"{displayName}\" toplu işlemi tamamlandı",
"{count} selected" : "{count} seçilmiş",
"List of files and folders." : "Dosya ve klasörlerin listesi.",
"Column headers with buttons are sortable." : "Düğmeler olan sütunlar sıralanabilir.",
"This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list." : "Başarımı olumsuz etkilememek için listenin tümü görüntülenmiyor. Listede ilerledikçe dosyalar görüntülenecek.",

@ -182,6 +182,7 @@
"Folder name" : "Klasör adı",
"This node is unavailable" : "Bu düğüm kullanılamıyor",
"Download file {name}" : "{name} dosyasını indir",
"Invalid file name" : "Dosya adı geçersiz",
"\"{name}\" is not an allowed filetype." : "\"{name}\" dosya türüne izin verilmiyor.",
"{newName} already exists." : "{newName} zaten var.",
"\"{char}\" is not allowed inside a file name." : "Dosya adlarında \"{char}\" karakteri kullanılamaz.",
@ -195,6 +196,7 @@
"Toggle selection for all files and folders" : "Tüm dosyaları ve klasörleri seç/bırak",
"\"{displayName}\" failed on some elements " : "\"{displayName}\" toplu işlemi bazı bileşenlerde tamamlanamadı",
"\"{displayName}\" batch action executed successfully" : "\"{displayName}\" toplu işlemi tamamlandı",
"{count} selected" : "{count} seçilmiş",
"List of files and folders." : "Dosya ve klasörlerin listesi.",
"Column headers with buttons are sortable." : "Düğmeler olan sütunlar sıralanabilir.",
"This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list." : "Başarımı olumsuz etkilememek için listenin tümü görüntülenmiyor. Listede ilerledikçe dosyalar görüntülenecek.",

@ -175,15 +175,15 @@ OC.L10N.register(
"Drag and drop files here to upload" : "Перетягніть файли сюди для завантаження",
"Your have used your space quota and cannot upload files anymore" : "Ви вже використали квоту на місце та не можете завантажувати файли",
"You dont have permission to upload or create files here" : "У вас недостатньо прав для завантаження або створення файлів тут",
"\"{displayName}\" action executed successfully" : "Дію \"{displayName}\" успішно виконано",
"\"{displayName}\" action failed" : "Дію \"{displayName}\" не вдалося виконати",
"\"{displayName}\" action executed successfully" : "\"{displayName}\" успішно виконано",
"\"{displayName}\" action failed" : "Не вдалося виконати \"{displayName}\"",
"Toggle selection for file \"{displayName}\"" : "Перемкнути вибір для файлу \"{displayName}\"",
"Toggle selection for folder \"{displayName}\"" : "Перемкнути вибір для каталогу \"{displayName}\"",
"Rename file" : "Перейменувати файл",
"File name" : "Ім'я файлу",
"Folder name" : "Назва каталогу",
"This node is unavailable" : "Цей вузол не доступний",
"Download file {name}" : "Звантажити файл {name}",
"Download file {name}" : "Відкрити файл {name}",
"\"{name}\" is not an allowed filetype." : "\"{name}\" є недозволеним типом файлу.",
"{newName} already exists." : "{newName} вже присутній.",
"\"{char}\" is not allowed inside a file name." : "Неприпустимий \"{char}\" у назві файлу.",
@ -197,6 +197,7 @@ OC.L10N.register(
"Toggle selection for all files and folders" : "Перемкнути вибір для всіх файлів та каталогів",
"\"{displayName}\" failed on some elements " : "\"{displayName}\" не показується в окремих елементах",
"\"{displayName}\" batch action executed successfully" : "Операцію \"{displayName}\" успішно виконано",
"{count} selected" : "{count} вибрано",
"List of files and folders." : "Список файлів та каталогів",
"Column headers with buttons are sortable." : "Назви стовпців з кнопками можна впорядковувати",
"This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list." : "Список не подається повністю з міркувань обчислювальних потужностей. Файли показуватимуться під час прокручування списку.",
@ -245,7 +246,7 @@ OC.L10N.register(
"Sort folders before files" : "Впорядковувати каталоги поререду файлів",
"Show hidden files" : "Показувати приховані файли",
"Crop image previews" : "Попередній перегляд перед кадруванням",
"Enable the grid view" : "Увімкнути перегляд у вигляді сітки",
"Enable the grid view" : "Увімкнути подання сіткою",
"Additional settings" : "Додатково",
"WebDAV" : "WebDAV",
"WebDAV URL" : "URL-адреса WebDAV",

@ -173,15 +173,15 @@
"Drag and drop files here to upload" : "Перетягніть файли сюди для завантаження",
"Your have used your space quota and cannot upload files anymore" : "Ви вже використали квоту на місце та не можете завантажувати файли",
"You dont have permission to upload or create files here" : "У вас недостатньо прав для завантаження або створення файлів тут",
"\"{displayName}\" action executed successfully" : "Дію \"{displayName}\" успішно виконано",
"\"{displayName}\" action failed" : "Дію \"{displayName}\" не вдалося виконати",
"\"{displayName}\" action executed successfully" : "\"{displayName}\" успішно виконано",
"\"{displayName}\" action failed" : "Не вдалося виконати \"{displayName}\"",
"Toggle selection for file \"{displayName}\"" : "Перемкнути вибір для файлу \"{displayName}\"",
"Toggle selection for folder \"{displayName}\"" : "Перемкнути вибір для каталогу \"{displayName}\"",
"Rename file" : "Перейменувати файл",
"File name" : "Ім'я файлу",
"Folder name" : "Назва каталогу",
"This node is unavailable" : "Цей вузол не доступний",
"Download file {name}" : "Звантажити файл {name}",
"Download file {name}" : "Відкрити файл {name}",
"\"{name}\" is not an allowed filetype." : "\"{name}\" є недозволеним типом файлу.",
"{newName} already exists." : "{newName} вже присутній.",
"\"{char}\" is not allowed inside a file name." : "Неприпустимий \"{char}\" у назві файлу.",
@ -195,6 +195,7 @@
"Toggle selection for all files and folders" : "Перемкнути вибір для всіх файлів та каталогів",
"\"{displayName}\" failed on some elements " : "\"{displayName}\" не показується в окремих елементах",
"\"{displayName}\" batch action executed successfully" : "Операцію \"{displayName}\" успішно виконано",
"{count} selected" : "{count} вибрано",
"List of files and folders." : "Список файлів та каталогів",
"Column headers with buttons are sortable." : "Назви стовпців з кнопками можна впорядковувати",
"This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list." : "Список не подається повністю з міркувань обчислювальних потужностей. Файли показуватимуться під час прокручування списку.",
@ -243,7 +244,7 @@
"Sort folders before files" : "Впорядковувати каталоги поререду файлів",
"Show hidden files" : "Показувати приховані файли",
"Crop image previews" : "Попередній перегляд перед кадруванням",
"Enable the grid view" : "Увімкнути перегляд у вигляді сітки",
"Enable the grid view" : "Увімкнути подання сіткою",
"Additional settings" : "Додатково",
"WebDAV" : "WebDAV",
"WebDAV URL" : "URL-адреса WebDAV",

@ -184,6 +184,7 @@ OC.L10N.register(
"Folder name" : "文件夹名称",
"This node is unavailable" : "此节点不可用",
"Download file {name}" : "下载文件 {name}",
"Invalid file name" : "无效文件名称",
"\"{name}\" is not an allowed filetype." : "“{name}”不是允许的文件类型",
"{newName} already exists." : "{newName}已经存在。",
"\"{char}\" is not allowed inside a file name." : "不允许文件名中包含 “{char}”",

@ -182,6 +182,7 @@
"Folder name" : "文件夹名称",
"This node is unavailable" : "此节点不可用",
"Download file {name}" : "下载文件 {name}",
"Invalid file name" : "无效文件名称",
"\"{name}\" is not an allowed filetype." : "“{name}”不是允许的文件类型",
"{newName} already exists." : "{newName}已经存在。",
"\"{char}\" is not allowed inside a file name." : "不允许文件名中包含 “{char}”",

@ -184,6 +184,7 @@ OC.L10N.register(
"Folder name" : "資料夾名稱",
"This node is unavailable" : "此節點不可用",
"Download file {name}" : "下載檔案 {name}",
"Invalid file name" : "檔案名稱無效",
"\"{name}\" is not an allowed filetype." : "「{name}」是不允許的檔案類型。",
"{newName} already exists." : "{newName} 已經存在。",
"\"{char}\" is not allowed inside a file name." : "不允許檔案名稱中出現 \"{char}\"。",

@ -182,6 +182,7 @@
"Folder name" : "資料夾名稱",
"This node is unavailable" : "此節點不可用",
"Download file {name}" : "下載檔案 {name}",
"Invalid file name" : "檔案名稱無效",
"\"{name}\" is not an allowed filetype." : "「{name}」是不允許的檔案類型。",
"{newName} already exists." : "{newName} 已經存在。",
"\"{char}\" is not allowed inside a file name." : "不允許檔案名稱中出現 \"{char}\"。",

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

Loading…
Cancel
Save