summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/encryption/appinfo/application.php15
-rw-r--r--apps/encryption/lib/crypto/decryptall.php143
-rw-r--r--apps/encryption/lib/crypto/encryption.php36
-rw-r--r--apps/encryption/lib/session.php60
-rw-r--r--apps/encryption/tests/lib/SessionTest.php55
-rw-r--r--apps/encryption/tests/lib/crypto/decryptalltest.php125
-rw-r--r--apps/encryption/tests/lib/crypto/encryptionTest.php78
-rw-r--r--apps/files/appinfo/remote.php3
-rw-r--r--apps/files/css/detailsView.css13
-rw-r--r--apps/files/css/files.css33
-rw-r--r--apps/files/js/fileinfomodel.js8
-rw-r--r--apps/files/js/filelist.js20
-rw-r--r--apps/files/js/mainfileinfodetailview.js108
-rw-r--r--apps/files/l10n/da.js2
-rw-r--r--apps/files/l10n/da.json2
-rw-r--r--apps/files/l10n/pt_PT.js9
-rw-r--r--apps/files/l10n/pt_PT.json9
-rw-r--r--apps/files_external/l10n/da.js12
-rw-r--r--apps/files_external/l10n/da.json12
-rw-r--r--apps/files_external/l10n/fi_FI.js2
-rw-r--r--apps/files_external/l10n/fi_FI.json2
-rw-r--r--apps/files_external/l10n/it.js6
-rw-r--r--apps/files_external/l10n/it.json6
-rw-r--r--apps/files_external/l10n/nb_NO.js11
-rw-r--r--apps/files_external/l10n/nb_NO.json11
-rw-r--r--apps/files_external/l10n/nl.js12
-rw-r--r--apps/files_external/l10n/nl.json12
-rw-r--r--apps/files_external/l10n/pt_BR.js11
-rw-r--r--apps/files_external/l10n/pt_BR.json11
-rw-r--r--apps/files_external/l10n/th_TH.js1
-rw-r--r--apps/files_external/l10n/th_TH.json1
-rw-r--r--apps/files_external/lib/amazons3.php5
-rw-r--r--apps/files_external/lib/backend/smb.php13
-rw-r--r--apps/files_external/lib/config/configadapter.php2
-rw-r--r--apps/files_external/service/userglobalstoragesservice.php57
-rw-r--r--apps/files_external/tests/backends/amazons3.php6
-rwxr-xr-xapps/files_external/tests/env/start-amazons3-ceph.sh81
-rwxr-xr-xapps/files_external/tests/env/stop-amazons3-ceph.sh36
-rw-r--r--apps/files_external/tests/service/userglobalstoragesservicetest.php80
-rw-r--r--apps/files_sharing/api/server2server.php13
-rw-r--r--apps/files_sharing/api/sharees.php14
-rw-r--r--apps/files_sharing/appinfo/app.php18
-rw-r--r--apps/files_sharing/css/sharetabview.css74
-rw-r--r--apps/files_sharing/js/share.js96
-rw-r--r--apps/files_sharing/js/sharetabview.js52
-rw-r--r--apps/files_sharing/l10n/cs_CZ.js1
-rw-r--r--apps/files_sharing/l10n/cs_CZ.json1
-rw-r--r--apps/files_sharing/l10n/da.js2
-rw-r--r--apps/files_sharing/l10n/da.json2
-rw-r--r--apps/files_sharing/l10n/el.js1
-rw-r--r--apps/files_sharing/l10n/el.json1
-rw-r--r--apps/files_sharing/l10n/fi_FI.js2
-rw-r--r--apps/files_sharing/l10n/fi_FI.json2
-rw-r--r--apps/files_sharing/l10n/fr.js1
-rw-r--r--apps/files_sharing/l10n/fr.json1
-rw-r--r--apps/files_sharing/l10n/hu_HU.js1
-rw-r--r--apps/files_sharing/l10n/hu_HU.json1
-rw-r--r--apps/files_sharing/l10n/id.js1
-rw-r--r--apps/files_sharing/l10n/id.json1
-rw-r--r--apps/files_sharing/l10n/it.js2
-rw-r--r--apps/files_sharing/l10n/it.json2
-rw-r--r--apps/files_sharing/l10n/ko.js1
-rw-r--r--apps/files_sharing/l10n/ko.json1
-rw-r--r--apps/files_sharing/l10n/nb_NO.js1
-rw-r--r--apps/files_sharing/l10n/nb_NO.json1
-rw-r--r--apps/files_sharing/l10n/nl.js2
-rw-r--r--apps/files_sharing/l10n/nl.json2
-rw-r--r--apps/files_sharing/l10n/pt_BR.js2
-rw-r--r--apps/files_sharing/l10n/pt_BR.json2
-rw-r--r--apps/files_sharing/l10n/sk_SK.js3
-rw-r--r--apps/files_sharing/l10n/sk_SK.json3
-rw-r--r--apps/files_sharing/l10n/th_TH.js2
-rw-r--r--apps/files_sharing/l10n/th_TH.json2
-rw-r--r--apps/files_sharing/lib/capabilities.php7
-rw-r--r--apps/files_sharing/lib/external/manager.php4
-rw-r--r--apps/files_sharing/lib/notifier.php2
-rw-r--r--apps/files_sharing/publicwebdav.php3
-rw-r--r--apps/files_sharing/tests/api/shareestest.php112
-rw-r--r--apps/files_sharing/tests/capabilities.php35
-rw-r--r--apps/files_sharing/tests/js/shareSpec.js125
-rw-r--r--apps/files_versions/appinfo/app.php3
-rw-r--r--apps/files_versions/appinfo/application.php11
-rw-r--r--apps/files_versions/appinfo/install.php23
-rw-r--r--apps/files_versions/appinfo/update.php3
-rw-r--r--apps/files_versions/css/versions.css15
-rw-r--r--apps/files_versions/js/versionstabview.js3
-rw-r--r--apps/files_versions/l10n/ar.js4
-rw-r--r--apps/files_versions/l10n/ar.json4
-rw-r--r--apps/files_versions/l10n/ast.js4
-rw-r--r--apps/files_versions/l10n/ast.json4
-rw-r--r--apps/files_versions/l10n/az.js4
-rw-r--r--apps/files_versions/l10n/az.json4
-rw-r--r--apps/files_versions/l10n/bg_BG.js4
-rw-r--r--apps/files_versions/l10n/bg_BG.json4
-rw-r--r--apps/files_versions/l10n/bn_BD.js4
-rw-r--r--apps/files_versions/l10n/bn_BD.json4
-rw-r--r--apps/files_versions/l10n/bn_IN.js4
-rw-r--r--apps/files_versions/l10n/bn_IN.json4
-rw-r--r--apps/files_versions/l10n/bs.js4
-rw-r--r--apps/files_versions/l10n/bs.json4
-rw-r--r--apps/files_versions/l10n/ca.js4
-rw-r--r--apps/files_versions/l10n/ca.json4
-rw-r--r--apps/files_versions/l10n/cs_CZ.js4
-rw-r--r--apps/files_versions/l10n/cs_CZ.json4
-rw-r--r--apps/files_versions/l10n/da.js4
-rw-r--r--apps/files_versions/l10n/da.json4
-rw-r--r--apps/files_versions/l10n/de.js4
-rw-r--r--apps/files_versions/l10n/de.json4
-rw-r--r--apps/files_versions/l10n/de_DE.js4
-rw-r--r--apps/files_versions/l10n/de_DE.json4
-rw-r--r--apps/files_versions/l10n/el.js4
-rw-r--r--apps/files_versions/l10n/el.json4
-rw-r--r--apps/files_versions/l10n/en_GB.js4
-rw-r--r--apps/files_versions/l10n/en_GB.json4
-rw-r--r--apps/files_versions/l10n/eo.js4
-rw-r--r--apps/files_versions/l10n/eo.json4
-rw-r--r--apps/files_versions/l10n/es.js4
-rw-r--r--apps/files_versions/l10n/es.json4
-rw-r--r--apps/files_versions/l10n/es_AR.js4
-rw-r--r--apps/files_versions/l10n/es_AR.json4
-rw-r--r--apps/files_versions/l10n/es_MX.js4
-rw-r--r--apps/files_versions/l10n/es_MX.json4
-rw-r--r--apps/files_versions/l10n/et_EE.js4
-rw-r--r--apps/files_versions/l10n/et_EE.json4
-rw-r--r--apps/files_versions/l10n/eu.js4
-rw-r--r--apps/files_versions/l10n/eu.json4
-rw-r--r--apps/files_versions/l10n/fa.js4
-rw-r--r--apps/files_versions/l10n/fa.json4
-rw-r--r--apps/files_versions/l10n/fi_FI.js4
-rw-r--r--apps/files_versions/l10n/fi_FI.json4
-rw-r--r--apps/files_versions/l10n/fr.js4
-rw-r--r--apps/files_versions/l10n/fr.json4
-rw-r--r--apps/files_versions/l10n/gl.js4
-rw-r--r--apps/files_versions/l10n/gl.json4
-rw-r--r--apps/files_versions/l10n/hr.js4
-rw-r--r--apps/files_versions/l10n/hr.json4
-rw-r--r--apps/files_versions/l10n/hu_HU.js4
-rw-r--r--apps/files_versions/l10n/hu_HU.json4
-rw-r--r--apps/files_versions/l10n/id.js4
-rw-r--r--apps/files_versions/l10n/id.json4
-rw-r--r--apps/files_versions/l10n/is.js4
-rw-r--r--apps/files_versions/l10n/is.json4
-rw-r--r--apps/files_versions/l10n/it.js4
-rw-r--r--apps/files_versions/l10n/it.json4
-rw-r--r--apps/files_versions/l10n/ja.js4
-rw-r--r--apps/files_versions/l10n/ja.json4
-rw-r--r--apps/files_versions/l10n/km.js4
-rw-r--r--apps/files_versions/l10n/km.json4
-rw-r--r--apps/files_versions/l10n/kn.js4
-rw-r--r--apps/files_versions/l10n/kn.json4
-rw-r--r--apps/files_versions/l10n/ko.js4
-rw-r--r--apps/files_versions/l10n/ko.json4
-rw-r--r--apps/files_versions/l10n/lb.js4
-rw-r--r--apps/files_versions/l10n/lb.json4
-rw-r--r--apps/files_versions/l10n/lt_LT.js4
-rw-r--r--apps/files_versions/l10n/lt_LT.json4
-rw-r--r--apps/files_versions/l10n/lv.js4
-rw-r--r--apps/files_versions/l10n/lv.json4
-rw-r--r--apps/files_versions/l10n/mk.js4
-rw-r--r--apps/files_versions/l10n/mk.json4
-rw-r--r--apps/files_versions/l10n/ms_MY.js4
-rw-r--r--apps/files_versions/l10n/ms_MY.json4
-rw-r--r--apps/files_versions/l10n/nb_NO.js4
-rw-r--r--apps/files_versions/l10n/nb_NO.json4
-rw-r--r--apps/files_versions/l10n/nl.js4
-rw-r--r--apps/files_versions/l10n/nl.json4
-rw-r--r--apps/files_versions/l10n/nn_NO.js4
-rw-r--r--apps/files_versions/l10n/nn_NO.json4
-rw-r--r--apps/files_versions/l10n/oc.js4
-rw-r--r--apps/files_versions/l10n/oc.json4
-rw-r--r--apps/files_versions/l10n/pl.js4
-rw-r--r--apps/files_versions/l10n/pl.json4
-rw-r--r--apps/files_versions/l10n/pt_BR.js4
-rw-r--r--apps/files_versions/l10n/pt_BR.json4
-rw-r--r--apps/files_versions/l10n/pt_PT.js4
-rw-r--r--apps/files_versions/l10n/pt_PT.json4
-rw-r--r--apps/files_versions/l10n/ro.js4
-rw-r--r--apps/files_versions/l10n/ro.json4
-rw-r--r--apps/files_versions/l10n/ru.js4
-rw-r--r--apps/files_versions/l10n/ru.json4
-rw-r--r--apps/files_versions/l10n/sk_SK.js4
-rw-r--r--apps/files_versions/l10n/sk_SK.json4
-rw-r--r--apps/files_versions/l10n/sl.js4
-rw-r--r--apps/files_versions/l10n/sl.json4
-rw-r--r--apps/files_versions/l10n/sq.js4
-rw-r--r--apps/files_versions/l10n/sq.json4
-rw-r--r--apps/files_versions/l10n/sr.js4
-rw-r--r--apps/files_versions/l10n/sr.json4
-rw-r--r--apps/files_versions/l10n/sr@latin.js4
-rw-r--r--apps/files_versions/l10n/sr@latin.json4
-rw-r--r--apps/files_versions/l10n/sv.js4
-rw-r--r--apps/files_versions/l10n/sv.json4
-rw-r--r--apps/files_versions/l10n/th_TH.js4
-rw-r--r--apps/files_versions/l10n/th_TH.json4
-rw-r--r--apps/files_versions/l10n/tr.js4
-rw-r--r--apps/files_versions/l10n/tr.json4
-rw-r--r--apps/files_versions/l10n/uk.js4
-rw-r--r--apps/files_versions/l10n/uk.json4
-rw-r--r--apps/files_versions/l10n/vi.js4
-rw-r--r--apps/files_versions/l10n/vi.json4
-rw-r--r--apps/files_versions/l10n/zh_CN.js4
-rw-r--r--apps/files_versions/l10n/zh_CN.json4
-rw-r--r--apps/files_versions/l10n/zh_TW.js4
-rw-r--r--apps/files_versions/l10n/zh_TW.json4
-rw-r--r--apps/files_versions/lib/backgroundjob/expireversions.php98
-rw-r--r--apps/files_versions/lib/expiration.php198
-rw-r--r--apps/files_versions/lib/storage.php92
-rw-r--r--apps/files_versions/tests/expirationtest.php204
-rw-r--r--apps/user_ldap/l10n/da.js12
-rw-r--r--apps/user_ldap/l10n/da.json12
210 files changed, 2309 insertions, 545 deletions
diff --git a/apps/encryption/appinfo/application.php b/apps/encryption/appinfo/application.php
index 75107b2723c..515a408fa2c 100644
--- a/apps/encryption/appinfo/application.php
+++ b/apps/encryption/appinfo/application.php
@@ -30,6 +30,7 @@ use OCA\Encryption\Controller\RecoveryController;
use OCA\Encryption\Controller\SettingsController;
use OCA\Encryption\Controller\StatusController;
use OCA\Encryption\Crypto\Crypt;
+use OCA\Encryption\Crypto\DecryptAll;
use OCA\Encryption\Crypto\EncryptAll;
use OCA\Encryption\Crypto\Encryption;
use OCA\Encryption\HookManager;
@@ -113,7 +114,9 @@ class Application extends \OCP\AppFramework\App {
$container->query('Crypt'),
$container->query('KeyManager'),
$container->query('Util'),
+ $container->query('Session'),
$container->query('EncryptAll'),
+ $container->query('DecryptAll'),
$container->getServer()->getLogger(),
$container->getServer()->getL10N($container->getAppName())
);
@@ -242,6 +245,18 @@ class Application extends \OCP\AppFramework\App {
}
);
+ $container->registerService('DecryptAll',
+ function (IAppContainer $c) {
+ return new DecryptAll(
+ $c->query('Util'),
+ $c->query('KeyManager'),
+ $c->query('Crypt'),
+ $c->query('Session'),
+ new QuestionHelper()
+ );
+ }
+ );
+
}
public function registerSettings() {
diff --git a/apps/encryption/lib/crypto/decryptall.php b/apps/encryption/lib/crypto/decryptall.php
new file mode 100644
index 00000000000..599cd82aa4d
--- /dev/null
+++ b/apps/encryption/lib/crypto/decryptall.php
@@ -0,0 +1,143 @@
+<?php
+/**
+ * @author Björn Schießle <schiessle@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+
+namespace OCA\Encryption\Crypto;
+
+
+use OCA\Encryption\KeyManager;
+use OCA\Encryption\Session;
+use OCA\Encryption\Util;
+use Symfony\Component\Console\Helper\QuestionHelper;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Question\ConfirmationQuestion;
+use Symfony\Component\Console\Question\Question;
+
+class DecryptAll {
+
+ /** @var Util */
+ protected $util;
+
+ /** @var QuestionHelper */
+ protected $questionHelper;
+
+ /** @var Crypt */
+ protected $crypt;
+
+ /** @var KeyManager */
+ protected $keyManager;
+
+ /** @var Session */
+ protected $session;
+
+ /**
+ * @param Util $util
+ * @param KeyManager $keyManager
+ * @param Crypt $crypt
+ * @param Session $session
+ * @param QuestionHelper $questionHelper
+ */
+ public function __construct(
+ Util $util,
+ KeyManager $keyManager,
+ Crypt $crypt,
+ Session $session,
+ QuestionHelper $questionHelper
+ ) {
+ $this->util = $util;
+ $this->keyManager = $keyManager;
+ $this->crypt = $crypt;
+ $this->session = $session;
+ $this->questionHelper = $questionHelper;
+ }
+
+ /**
+ * prepare encryption module to decrypt all files
+ *
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ * @param $user
+ * @return bool
+ */
+ public function prepare(InputInterface $input, OutputInterface $output, $user) {
+
+ $question = new Question('Please enter the recovery key password: ');
+ $recoveryKeyId = $this->keyManager->getRecoveryKeyId();
+
+ if (!empty($user)) {
+ $questionUseLoginPassword = new ConfirmationQuestion(
+ 'Do you want to use the users login password to decrypt all files? (y/n) ',
+ false
+ );
+ $useLoginPassword = $this->questionHelper->ask($input, $output, $questionUseLoginPassword);
+ if ($useLoginPassword) {
+ $question = new Question('Please enter the users login password: ');
+ } else if ($this->util->isRecoveryEnabledForUser($user) === false) {
+ $output->writeln('No recovery key available for user ' . $user);
+ return false;
+ } else {
+ $user = $recoveryKeyId;
+ }
+ } else {
+ $user = $recoveryKeyId;
+ }
+
+ $question->setHidden(true);
+ $question->setHiddenFallback(false);
+ $password = $this->questionHelper->ask($input, $output, $question);
+ $privateKey = $this->getPrivateKey($user, $password);
+ if ($privateKey !== false) {
+ $this->updateSession($user, $privateKey);
+ return true;
+ } else {
+ $output->writeln('Could not decrypt private key, maybe you entered the wrong password?');
+ }
+
+
+ return false;
+ }
+
+ /**
+ * get the private key which will be used to decrypt all files
+ *
+ * @param string $user
+ * @param string $password
+ * @return bool|string
+ * @throws \OCA\Encryption\Exceptions\PrivateKeyMissingException
+ */
+ protected function getPrivateKey($user, $password) {
+ $recoveryKeyId = $this->keyManager->getRecoveryKeyId();
+ if ($user === $recoveryKeyId) {
+ $recoveryKey = $this->keyManager->getSystemPrivateKey($recoveryKeyId);
+ $privateKey = $this->crypt->decryptPrivateKey($recoveryKey, $password);
+ } else {
+ $userKey = $this->keyManager->getPrivateKey($user);
+ $privateKey = $this->crypt->decryptPrivateKey($userKey, $password, $user);
+ }
+
+ return $privateKey;
+ }
+
+ protected function updateSession($user, $privateKey) {
+ $this->session->prepareDecryptAll($user, $privateKey);
+ }
+}
diff --git a/apps/encryption/lib/crypto/encryption.php b/apps/encryption/lib/crypto/encryption.php
index c62afac83c1..fde4a2c4a9c 100644
--- a/apps/encryption/lib/crypto/encryption.php
+++ b/apps/encryption/lib/crypto/encryption.php
@@ -30,6 +30,7 @@ namespace OCA\Encryption\Crypto;
use OC\Encryption\Exceptions\DecryptionFailedException;
use OCA\Encryption\Exceptions\PublicKeyMissingException;
+use OCA\Encryption\Session;
use OCA\Encryption\Util;
use OCP\Encryption\IEncryptionModule;
use OCA\Encryption\KeyManager;
@@ -75,6 +76,9 @@ class Encryption implements IEncryptionModule {
/** @var Util */
private $util;
+ /** @var Session */
+ private $session;
+
/** @var ILogger */
private $logger;
@@ -87,25 +91,34 @@ class Encryption implements IEncryptionModule {
/** @var bool */
private $useMasterPassword;
+ /** @var DecryptAll */
+ private $decryptAll;
+
/**
*
* @param Crypt $crypt
* @param KeyManager $keyManager
* @param Util $util
+ * @param Session $session
* @param EncryptAll $encryptAll
+ * @param DecryptAll $decryptAll
* @param ILogger $logger
* @param IL10N $il10n
*/
public function __construct(Crypt $crypt,
KeyManager $keyManager,
Util $util,
+ Session $session,
EncryptAll $encryptAll,
+ DecryptAll $decryptAll,
ILogger $logger,
IL10N $il10n) {
$this->crypt = $crypt;
$this->keyManager = $keyManager;
$this->util = $util;
+ $this->session = $session;
$this->encryptAll = $encryptAll;
+ $this->decryptAll = $decryptAll;
$this->logger = $logger;
$this->l = $il10n;
$this->useMasterPassword = $util->isMasterKeyEnabled();
@@ -150,7 +163,15 @@ class Encryption implements IEncryptionModule {
$this->isWriteOperation = false;
$this->writeCache = '';
- $this->fileKey = $this->keyManager->getFileKey($this->path, $this->user);
+ if ($this->session->decryptAllModeActivated()) {
+ $encryptedFileKey = $this->keyManager->getEncryptedFileKey($this->path);
+ $shareKey = $this->keyManager->getShareKey($this->path, $this->session->getDecryptAllUid());
+ $this->fileKey = $this->crypt->multiKeyDecrypt($encryptedFileKey,
+ $shareKey,
+ $this->session->getDecryptAllKey());
+ } else {
+ $this->fileKey = $this->keyManager->getFileKey($this->path, $this->user);
+ }
if (
$mode === 'w'
@@ -427,6 +448,19 @@ class Encryption implements IEncryptionModule {
}
/**
+ * prepare module to perform decrypt all operation
+ *
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ * @param string $user
+ * @return bool
+ */
+ public function prepareDecryptAll(InputInterface $input, OutputInterface $output, $user = '') {
+ return $this->decryptAll->prepare($input, $output, $user);
+ }
+
+
+ /**
* @param string $path
* @return string
*/
diff --git a/apps/encryption/lib/session.php b/apps/encryption/lib/session.php
index c3759c3fc56..1d0c3711487 100644
--- a/apps/encryption/lib/session.php
+++ b/apps/encryption/lib/session.php
@@ -25,6 +25,7 @@
namespace OCA\Encryption;
+use OCA\Encryption\Exceptions\PrivateKeyMissingException;
use \OCP\ISession;
class Session {
@@ -106,6 +107,61 @@ class Session {
$this->session->set('privateKey', $key);
}
+ /**
+ * store data needed for the decrypt all operation in the session
+ *
+ * @param string $user
+ * @param string $key
+ */
+ public function prepareDecryptAll($user, $key) {
+ $this->session->set('decryptAll', true);
+ $this->session->set('decryptAllKey', $key);
+ $this->session->set('decryptAllUid', $user);
+ }
+
+ /**
+ * check if we are in decrypt all mode
+ *
+ * @return bool
+ */
+ public function decryptAllModeActivated() {
+ $decryptAll = $this->session->get('decryptAll');
+ return ($decryptAll === true);
+ }
+
+ /**
+ * get uid used for decrypt all operation
+ *
+ * @return string
+ * @throws \Exception
+ */
+ public function getDecryptAllUid() {
+ $uid = $this->session->get('decryptAllUid');
+ if (is_null($uid) && $this->decryptAllModeActivated()) {
+ throw new \Exception('No uid found while in decrypt all mode');
+ } elseif (is_null($uid)) {
+ throw new \Exception('Please activate decrypt all mode first');
+ }
+
+ return $uid;
+ }
+
+ /**
+ * get private key for decrypt all operation
+ *
+ * @return string
+ * @throws PrivateKeyMissingException
+ */
+ public function getDecryptAllKey() {
+ $privateKey = $this->session->get('decryptAllKey');
+ if (is_null($privateKey) && $this->decryptAllModeActivated()) {
+ throw new PrivateKeyMissingException('No private key found while in decrypt all mode');
+ } elseif (is_null($privateKey)) {
+ throw new PrivateKeyMissingException('Please activate decrypt all mode first');
+ }
+
+ return $privateKey;
+ }
/**
* remove keys from session
@@ -114,7 +170,9 @@ class Session {
$this->session->remove('publicSharePrivateKey');
$this->session->remove('privateKey');
$this->session->remove('encryptionInitialized');
-
+ $this->session->remove('decryptAll');
+ $this->session->remove('decryptAllKey');
+ $this->session->remove('decryptAllUid');
}
}
diff --git a/apps/encryption/tests/lib/SessionTest.php b/apps/encryption/tests/lib/SessionTest.php
index e036c439939..0fa48666d70 100644
--- a/apps/encryption/tests/lib/SessionTest.php
+++ b/apps/encryption/tests/lib/SessionTest.php
@@ -56,6 +56,7 @@ class SessionTest extends TestCase {
* @depends testSetAndGetPrivateKey
*/
public function testIsPrivateKeySet() {
+ $this->instance->setPrivateKey('dummyPrivateKey');
$this->assertTrue($this->instance->isPrivateKeySet());
unset(self::$tempStorage['privateKey']);
@@ -65,6 +66,51 @@ class SessionTest extends TestCase {
self::$tempStorage['privateKey'] = 'dummyPrivateKey';
}
+ public function testDecryptAllModeActivated() {
+ $this->instance->prepareDecryptAll('user1', 'usersKey');
+ $this->assertTrue($this->instance->decryptAllModeActivated());
+ $this->assertSame('user1', $this->instance->getDecryptAllUid());
+ $this->assertSame('usersKey', $this->instance->getDecryptAllKey());
+ }
+
+ public function testDecryptAllModeDeactivated() {
+ $this->assertFalse($this->instance->decryptAllModeActivated());
+ }
+
+ /**
+ * @expectedException \Exception
+ * @expectExceptionMessage 'Please activate decrypt all mode first'
+ */
+ public function testGetDecryptAllUidException() {
+ $this->instance->getDecryptAllUid();
+ }
+
+ /**
+ * @expectedException \Exception
+ * @expectExceptionMessage 'No uid found while in decrypt all mode'
+ */
+ public function testGetDecryptAllUidException2() {
+ $this->instance->prepareDecryptAll(null, 'key');
+ $this->instance->getDecryptAllUid();
+ }
+
+ /**
+ * @expectedException \OCA\Encryption\Exceptions\PrivateKeyMissingException
+ * @expectExceptionMessage 'Please activate decrypt all mode first'
+ */
+ public function testGetDecryptAllKeyException() {
+ $this->instance->getDecryptAllKey();
+ }
+
+ /**
+ * @expectedException \OCA\Encryption\Exceptions\PrivateKeyMissingException
+ * @expectExceptionMessage 'No key found while in decrypt all mode'
+ */
+ public function testGetDecryptAllKeyException2() {
+ $this->instance->prepareDecryptAll('user', null);
+ $this->instance->getDecryptAllKey();
+ }
+
/**
*
*/
@@ -112,6 +158,10 @@ class SessionTest extends TestCase {
*
*/
public function testClearWillRemoveValues() {
+ $this->instance->setPrivateKey('privateKey');
+ $this->instance->setStatus('initStatus');
+ $this->instance->prepareDecryptAll('user', 'key');
+ $this->assertNotEmpty(self::$tempStorage);
$this->instance->clear();
$this->assertEmpty(self::$tempStorage);
}
@@ -138,4 +188,9 @@ class SessionTest extends TestCase {
$this->instance = new Session($this->sessionMock);
}
+
+ protected function tearDown() {
+ self::$tempStorage = [];
+ parent::tearDown();
+ }
}
diff --git a/apps/encryption/tests/lib/crypto/decryptalltest.php b/apps/encryption/tests/lib/crypto/decryptalltest.php
new file mode 100644
index 00000000000..d6a52fe97c0
--- /dev/null
+++ b/apps/encryption/tests/lib/crypto/decryptalltest.php
@@ -0,0 +1,125 @@
+<?php
+/**
+ * @author Björn Schießle <schiessle@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+
+namespace OCA\Encryption\Tests\lib\Crypto;
+
+
+use OCA\Encryption\Crypto\Crypt;
+use OCA\Encryption\Crypto\DecryptAll;
+use OCA\Encryption\KeyManager;
+use OCA\Encryption\Session;
+use OCA\Encryption\Util;
+use Symfony\Component\Console\Helper\QuestionHelper;
+use Test\TestCase;
+
+class DecryptAllTest extends TestCase {
+
+ /** @var DecryptAll */
+ protected $instance;
+
+ /** @var Util | \PHPUnit_Framework_MockObject_MockObject */
+ protected $util;
+
+ /** @var KeyManager | \PHPUnit_Framework_MockObject_MockObject */
+ protected $keyManager;
+
+ /** @var Crypt | \PHPUnit_Framework_MockObject_MockObject */
+ protected $crypt;
+
+ /** @var Session | \PHPUnit_Framework_MockObject_MockObject */
+ protected $session;
+
+ /** @var QuestionHelper | \PHPUnit_Framework_MockObject_MockObject */
+ protected $questionHelper;
+
+ public function setUp() {
+ parent::setUp();
+
+ $this->util = $this->getMockBuilder('OCA\Encryption\Util')
+ ->disableOriginalConstructor()->getMock();
+ $this->keyManager = $this->getMockBuilder('OCA\Encryption\KeyManager')
+ ->disableOriginalConstructor()->getMock();
+ $this->crypt = $this->getMockBuilder('OCA\Encryption\Crypto\Crypt')
+ ->disableOriginalConstructor()->getMock();
+ $this->session = $this->getMockBuilder('OCA\Encryption\Session')
+ ->disableOriginalConstructor()->getMock();
+ $this->questionHelper = $this->getMockBuilder('Symfony\Component\Console\Helper\QuestionHelper')
+ ->disableOriginalConstructor()->getMock();
+
+ $this->instance = new DecryptAll(
+ $this->util,
+ $this->keyManager,
+ $this->crypt,
+ $this->session,
+ $this->questionHelper
+ );
+ }
+
+ public function testUpdateSession() {
+ $this->session->expects($this->once())->method('prepareDecryptAll')
+ ->with('user1', 'key1');
+
+ $this->invokePrivate($this->instance, 'updateSession', ['user1', 'key1']);
+ }
+
+ /**
+ * @dataProvider dataTestGetPrivateKey
+ *
+ * @param string $user
+ * @param string $recoveryKeyId
+ */
+ public function testGetPrivateKey($user, $recoveryKeyId) {
+ $password = 'passwd';
+ $recoveryKey = 'recoveryKey';
+ $userKey = 'userKey';
+ $unencryptedKey = 'unencryptedKey';
+
+ $this->keyManager->expects($this->any())->method('getRecoveryKeyId')
+ ->willReturn($recoveryKeyId);
+
+ if ($user === $recoveryKeyId) {
+ $this->keyManager->expects($this->once())->method('getSystemPrivateKey')
+ ->with($recoveryKeyId)->willReturn($recoveryKey);
+ $this->keyManager->expects($this->never())->method('getPrivateKey');
+ $this->crypt->expects($this->once())->method('decryptPrivateKey')
+ ->with($recoveryKey, $password)->willReturn($unencryptedKey);
+ } else {
+ $this->keyManager->expects($this->never())->method('getSystemPrivateKey');
+ $this->keyManager->expects($this->once())->method('getPrivateKey')
+ ->with($user)->willReturn($userKey);
+ $this->crypt->expects($this->once())->method('decryptPrivateKey')
+ ->with($userKey, $password, $user)->willReturn($unencryptedKey);
+ }
+
+ $this->assertSame($unencryptedKey,
+ $this->invokePrivate($this->instance, 'getPrivateKey', [$user, $password])
+ );
+ }
+
+ public function dataTestGetPrivateKey() {
+ return [
+ ['user1', 'recoveryKey'],
+ ['recoveryKeyId', 'recoveryKeyId']
+ ];
+ }
+
+}
diff --git a/apps/encryption/tests/lib/crypto/encryptionTest.php b/apps/encryption/tests/lib/crypto/encryptionTest.php
index f58aa5d3ccb..9e0cb2f09d1 100644
--- a/apps/encryption/tests/lib/crypto/encryptionTest.php
+++ b/apps/encryption/tests/lib/crypto/encryptionTest.php
@@ -40,6 +40,12 @@ class EncryptionTest extends TestCase {
private $encryptAllMock;
/** @var \PHPUnit_Framework_MockObject_MockObject */
+ private $decryptAllMock;
+
+ /** @var \PHPUnit_Framework_MockObject_MockObject */
+ private $sessionMock;
+
+ /** @var \PHPUnit_Framework_MockObject_MockObject */
private $cryptMock;
/** @var \PHPUnit_Framework_MockObject_MockObject */
@@ -63,9 +69,15 @@ class EncryptionTest extends TestCase {
$this->keyManagerMock = $this->getMockBuilder('OCA\Encryption\KeyManager')
->disableOriginalConstructor()
->getMock();
+ $this->sessionMock = $this->getMockBuilder('OCA\Encryption\Session')
+ ->disableOriginalConstructor()
+ ->getMock();
$this->encryptAllMock = $this->getMockBuilder('OCA\Encryption\Crypto\EncryptAll')
->disableOriginalConstructor()
->getMock();
+ $this->decryptAllMock = $this->getMockBuilder('OCA\Encryption\Crypto\DecryptAll')
+ ->disableOriginalConstructor()
+ ->getMock();
$this->loggerMock = $this->getMockBuilder('OCP\ILogger')
->disableOriginalConstructor()
->getMock();
@@ -81,7 +93,9 @@ class EncryptionTest extends TestCase {
$this->cryptMock,
$this->keyManagerMock,
$this->utilMock,
+ $this->sessionMock,
$this->encryptAllMock,
+ $this->decryptAllMock,
$this->loggerMock,
$this->l10nMock
);
@@ -170,6 +184,16 @@ class EncryptionTest extends TestCase {
*/
public function testBegin($mode, $header, $legacyCipher, $defaultCipher, $fileKey, $expected) {
+ $this->sessionMock->expects($this->once())
+ ->method('decryptAllModeActivated')
+ ->willReturn(false);
+
+ $this->sessionMock->expects($this->never())->method('getDecryptAllUid');
+ $this->sessionMock->expects($this->never())->method('getDecryptAllKey');
+ $this->keyManagerMock->expects($this->never())->method('getEncryptedFileKey');
+ $this->keyManagerMock->expects($this->never())->method('getShareKey');
+ $this->cryptMock->expects($this->never())->method('multiKeyDecrypt');
+
$this->cryptMock->expects($this->any())
->method('getCipher')
->willReturn($defaultCipher);
@@ -209,6 +233,49 @@ class EncryptionTest extends TestCase {
);
}
+
+ /**
+ * test begin() if decryptAll mode was activated
+ */
+ public function testBeginDecryptAll() {
+
+ $path = '/user/files/foo.txt';
+ $recoveryKeyId = 'recoveryKeyId';
+ $recoveryShareKey = 'recoveryShareKey';
+ $decryptAllKey = 'decryptAllKey';
+ $fileKey = 'fileKey';
+
+ $this->sessionMock->expects($this->once())
+ ->method('decryptAllModeActivated')
+ ->willReturn(true);
+ $this->sessionMock->expects($this->once())
+ ->method('getDecryptAllUid')
+ ->willReturn($recoveryKeyId);
+ $this->sessionMock->expects($this->once())
+ ->method('getDecryptAllKey')
+ ->willReturn($decryptAllKey);
+
+ $this->keyManagerMock->expects($this->once())
+ ->method('getEncryptedFileKey')
+ ->willReturn('encryptedFileKey');
+ $this->keyManagerMock->expects($this->once())
+ ->method('getShareKey')
+ ->with($path, $recoveryKeyId)
+ ->willReturn($recoveryShareKey);
+ $this->cryptMock->expects($this->once())
+ ->method('multiKeyDecrypt')
+ ->with('encryptedFileKey', $recoveryShareKey, $decryptAllKey)
+ ->willReturn($fileKey);
+
+ $this->keyManagerMock->expects($this->never())->method('getFileKey');
+
+ $this->instance->begin($path, 'user', 'r', [], []);
+
+ $this->assertSame($fileKey,
+ $this->invokePrivate($this->instance, 'fileKey')
+ );
+ }
+
/**
* @dataProvider dataTestUpdate
*
@@ -273,4 +340,15 @@ class EncryptionTest extends TestCase {
public function testDecrypt() {
$this->instance->decrypt('abc');
}
+
+ public function testPrepareDecryptAll() {
+ $input = $this->getMock('Symfony\Component\Console\Input\InputInterface');
+ $output = $this->getMock('Symfony\Component\Console\Output\OutputInterface');
+
+ $this->decryptAllMock->expects($this->once())->method('prepare')
+ ->with($input, $output, 'user');
+
+ $this->instance->prepareDecryptAll($input, $output, 'user');
+ }
+
}
diff --git a/apps/files/appinfo/remote.php b/apps/files/appinfo/remote.php
index 36479ae13d0..4d0d8b3e2ec 100644
--- a/apps/files/appinfo/remote.php
+++ b/apps/files/appinfo/remote.php
@@ -39,7 +39,8 @@ $serverFactory = new \OC\Connector\Sabre\ServerFactory(
\OC::$server->getDatabaseConnection(),
\OC::$server->getUserSession(),
\OC::$server->getMountManager(),
- \OC::$server->getTagManager()
+ \OC::$server->getTagManager(),
+ \OC::$server->getEventDispatcher()
);
// Backends
diff --git a/apps/files/css/detailsView.css b/apps/files/css/detailsView.css
index 8eded7acda1..ea9d48b470c 100644
--- a/apps/files/css/detailsView.css
+++ b/apps/files/css/detailsView.css
@@ -25,18 +25,26 @@
margin-top: -15px;
}
+#app-sidebar .thumbnailContainer.image.portrait {
+ margin: 0; /* if we dont fit the image anyway we give it back the margin */
+}
+
#app-sidebar .image .thumbnail {
width:100%;
display:block;
height: 250px;
background-repeat: no-repeat;
- background-position: 50% top;
+ background-position: center;
background-size: 100%;
float: none;
margin: 0;
}
#app-sidebar .image.portrait .thumbnail {
+ background-position: 50% top;
+}
+
+#app-sidebar .image.portrait .thumbnail {
background-size: contain;
}
@@ -64,10 +72,13 @@
#app-sidebar .fileName h3 {
max-width: 300px;
float:left;
+ padding: 5px 0;
+ margin: -5px 0;
}
#app-sidebar .file-details {
margin-top: 3px;
+ margin-bottom: 15px;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
opacity: .5;
float:left;
diff --git a/apps/files/css/files.css b/apps/files/css/files.css
index 05033dc2fed..df23f415129 100644
--- a/apps/files/css/files.css
+++ b/apps/files/css/files.css
@@ -110,10 +110,6 @@
cursor: pointer;
}
-#app-navigation .nav-files a {
- display: inline-block;
-}
-
#app-navigation .nav-files a.new.hidden {
display: none;
}
@@ -420,25 +416,20 @@ table td.filename .uploadtext {
}
/* File checkboxes */
-#fileList tr td.filename>.selectCheckBox {
- -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
- filter: alpha(opacity=0);
+#fileList tr td.filename>.selectCheckBox + label:before {
opacity: 0;
- float: left;
- top: 0;
- margin: 32px 0 4px 32px; /* bigger clickable area doesn’t work in FF width:2.8em; height:2.4em;*/
+ position: absolute;
+ bottom: 4px;
+ right: 0;
+ z-index: 10;
}
+
/* Show checkbox when hovering, checked, or selected */
-#fileList tr:hover td.filename>.selectCheckBox,
-#fileList tr:focus td.filename>.selectCheckBox,
-#fileList tr td.filename>.selectCheckBox:checked,
-#fileList tr.selected td.filename>.selectCheckBox {
+#fileList tr:hover td.filename>.selectCheckBox + label:before,
+#fileList tr:focus td.filename>.selectCheckBox + label:before,
+#fileList tr td.filename>.selectCheckBox:checked + label:before,
+#fileList tr.selected td.filename>.selectCheckBox + label:before {
opacity: 1;
-}
-.lte9 #fileList tr:hover td.filename>.selectCheckBox,
-.lte9 #fileList tr:focus td.filename>.selectCheckBox,
-.lte9 #fileList tr td.filename>.selectCheckBox[checked=checked],
-.lte9 #fileList tr.selected td.filename>.selectCheckBox {
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
filter: alpha(opacity=100);
}
@@ -446,6 +437,7 @@ table td.filename .uploadtext {
/* Use label to have bigger clickable size for checkbox */
#fileList tr td.filename>.selectCheckBox + label,
.select-all + label {
+ background-position: 30px 30px;
height: 50px;
position: absolute;
width: 50px;
@@ -460,7 +452,7 @@ table td.filename .uploadtext {
.select-all + label {
top: 0;
}
-.select-all {
+.select-all + label:before {
position: absolute;
top: 18px;
left: 18px;
@@ -737,6 +729,7 @@ table.dragshadow td.size {
width: 140px;
margin-left: -56px;
margin-top: 25px;
+ z-index: 1001;
}
.newFileMenu .menuitem {
diff --git a/apps/files/js/fileinfomodel.js b/apps/files/js/fileinfomodel.js
index 22b1ca9ff0c..de1b143a160 100644
--- a/apps/files/js/fileinfomodel.js
+++ b/apps/files/js/fileinfomodel.js
@@ -57,7 +57,13 @@
* @return {boolean} true if this is an image, false otherwise
*/
isImage: function() {
- return this.has('mimetype') ? this.get('mimetype').substr(0, 6) === 'image/' : false;
+ if (!this.has('mimetype')) {
+ return false;
+ }
+ return this.get('mimetype').substr(0, 6) === 'image/'
+ || this.get('mimetype') === 'application/postscript'
+ || this.get('mimetype') === 'application/illustrator'
+ || this.get('mimetype') === 'application/x-photoshop';
},
/**
diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js
index 3e12573c046..2af5be73d96 100644
--- a/apps/files/js/filelist.js
+++ b/apps/files/js/filelist.js
@@ -10,7 +10,7 @@
(function() {
- var TEMPLATE_ADDBUTTON = '<a href="#" class="button new" title="{{addText}}"><img src="{{iconUrl}}"></img></a>';
+ var TEMPLATE_ADDBUTTON = '<a href="#" class="button new"><img src="{{iconUrl}}" alt="{{addText}}"></img></a>';
/**
* @class OCA.Files.FileList
@@ -301,6 +301,7 @@
this.fileActions.registerAction({
name: 'Details',
mime: 'all',
+ icon: OC.imagePath('core', 'actions/details'),
permissions: OC.PERMISSION_READ,
actionHandler: function(fileName, context) {
self._updateDetailsView(fileName);
@@ -346,7 +347,7 @@
// and contain existing models that can be used.
// This method would in the future simply retrieve the matching model from the collection.
var model = new OCA.Files.FileInfoModel(this.elementToFile($tr));
- if (!model.has('path')) {
+ if (!model.get('path')) {
model.set('path', this.getCurrentDirectory(), {silent: true});
}
@@ -368,6 +369,21 @@
},
/**
+ * Displays the details view for the given file and
+ * selects the given tab
+ *
+ * @param {string} fileName file name for which to show details
+ * @param {string} [tabId] optional tab id to select
+ */
+ showDetailsView: function(fileName, tabId) {
+ this._updateDetailsView(fileName);
+ if (tabId) {
+ this._detailsView.selectTab(tabId);
+ }
+ OC.Apps.showAppSidebar();
+ },
+
+ /**
* Update the details view to display the given file
*
* @param {string} fileName file name from the current list
diff --git a/apps/files/js/mainfileinfodetailview.js b/apps/files/js/mainfileinfodetailview.js
index efdbb5e2ad1..830f074f3f1 100644
--- a/apps/files/js/mainfileinfodetailview.js
+++ b/apps/files/js/mainfileinfodetailview.js
@@ -124,52 +124,10 @@
// TODO: we really need OC.Previews
var $iconDiv = this.$el.find('.thumbnail');
- $iconDiv.addClass('icon-loading icon-32');
- $container = this.$el.find('.thumbnailContainer');
+ var $container = this.$el.find('.thumbnailContainer');
if (!this.model.isDirectory()) {
- this._fileList.lazyLoadPreview({
- path: this.model.getFullPath(),
- mime: this.model.get('mimetype'),
- etag: this.model.get('etag'),
- y: this.model.isImage() ? 250: 75,
- x: this.model.isImage() ? 99999 /* only limit on y */ : 75,
- a: this.model.isImage() ? 1 : null,
- callback: function(previewUrl, img) {
- $iconDiv.previewImg = previewUrl;
- if (img) {
- $iconDiv.removeClass('icon-loading icon-32');
- if(img.height > img.width) {
- $container.addClass('portrait');
- }
- }
- if (this.model.isImage() && img) {
- $iconDiv.parent().addClass('image');
- var targetHeight = img.height / window.devicePixelRatio;
- if (targetHeight <= 75) {
- $container.removeClass('image'); // small enough to fit in normaly
- targetHeight = 75;
- }
- } else {
- targetHeight = 75;
- }
-
- // only set background when we have an actual preview
- // when we dont have a preview we show the mime icon in the error handler
- if (img) {
- $iconDiv.css({
- 'background-image': 'url("' + previewUrl + '")',
- 'height': targetHeight
- });
- }
- }.bind(this),
- error: function() {
- $iconDiv.removeClass('icon-loading icon-32');
- this.$el.find('.thumbnailContainer').removeClass('image'); //fall back to regular view
- $iconDiv.css({
- 'background-image': 'url("' + $iconDiv.previewImg + '")'
- });
- }.bind(this)
- });
+ $iconDiv.addClass('icon-loading icon-32');
+ this.loadPreview(this.model.getFullPath(), this.model.get('mimetype'), this.model.get('etag'), $iconDiv, $container, this.model.isImage());
} else {
// TODO: special icons / shared / external
$iconDiv.css('background-image', 'url("' + OC.MimeType.getIconUrl('dir') + '")');
@@ -179,6 +137,66 @@
this.$el.empty();
}
this.delegateEvents();
+ },
+
+ loadPreview: function(path, mime, etag, $iconDiv, $container, isImage) {
+ var maxImageHeight = ($container.parent().width() + 50) / (16/9); // 30px for negative margin
+ var smallPreviewSize = 75;
+
+ var isLandscape = function(img) {
+ return img.width > (img.height * 1.2);
+ };
+
+ var getTargetHeight = function(img) {
+ if(isImage) {
+ var targetHeight = img.height / window.devicePixelRatio;
+ if (targetHeight <= smallPreviewSize) {
+ targetHeight = smallPreviewSize;
+ }
+ return targetHeight;
+ }else{
+ return smallPreviewSize;
+ }
+ };
+
+ this._fileList.lazyLoadPreview({
+ path: path,
+ mime: mime,
+ etag: etag,
+ y: isImage ? maxImageHeight : smallPreviewSize,
+ x: isImage ? 99999 /* only limit on y */ : smallPreviewSize,
+ a: isImage ? 1 : null,
+ callback: function (previewUrl, img) {
+ $iconDiv.previewImg = previewUrl;
+
+ // as long as we only have the mimetype icon, we only save it in case there is no preview
+ if (!img) {
+ return;
+ }
+ $iconDiv.removeClass('icon-loading icon-32');
+ var targetHeight = getTargetHeight(img);
+ if (this.model.isImage() && targetHeight > smallPreviewSize) {
+ if (!isLandscape(img)) {
+ $container.addClass('portrait');
+ }
+ $container.addClass('image');
+ }
+
+ // only set background when we have an actual preview
+ // when we dont have a preview we show the mime icon in the error handler
+ $iconDiv.css({
+ 'background-image': 'url("' + previewUrl + '")',
+ 'height': targetHeight
+ });
+ }.bind(this),
+ error: function () {
+ $iconDiv.removeClass('icon-loading icon-32');
+ this.$el.find('.thumbnailContainer').removeClass('image'); //fall back to regular view
+ $iconDiv.css({
+ 'background-image': 'url("' + $iconDiv.previewImg + '")'
+ });
+ }.bind(this)
+ });
}
});
diff --git a/apps/files/l10n/da.js b/apps/files/l10n/da.js
index 7235176c166..cc7aac18351 100644
--- a/apps/files/l10n/da.js
+++ b/apps/files/l10n/da.js
@@ -99,7 +99,7 @@ OC.L10N.register(
"File handling" : "Filhåndtering",
"Maximum upload size" : "Maksimal upload-størrelse",
"max. possible: " : "max. mulige: ",
- "With PHP-FPM this value may take up to 5 minutes to take effect after saving." : "Med PHP-FPM kan denne værdi, kan der gå op til 5 minutter før virkningen indtræffer, efter at der gemmes.",
+ "With PHP-FPM this value may take up to 5 minutes to take effect after saving." : "Med denne PHP-FPM værdi, kan der gå op til 5 minutter før virkningen indtræffer, efter at der gemmes.",
"Save" : "Gem",
"Can not be edited from here due to insufficient permissions." : "Kan ikke redigeres herfra på grund af utilstrækkelige rettigheder.",
"Settings" : "Indstillinger",
diff --git a/apps/files/l10n/da.json b/apps/files/l10n/da.json
index adead6621a2..b77937420f4 100644
--- a/apps/files/l10n/da.json
+++ b/apps/files/l10n/da.json
@@ -97,7 +97,7 @@
"File handling" : "Filhåndtering",
"Maximum upload size" : "Maksimal upload-størrelse",
"max. possible: " : "max. mulige: ",
- "With PHP-FPM this value may take up to 5 minutes to take effect after saving." : "Med PHP-FPM kan denne værdi, kan der gå op til 5 minutter før virkningen indtræffer, efter at der gemmes.",
+ "With PHP-FPM this value may take up to 5 minutes to take effect after saving." : "Med denne PHP-FPM værdi, kan der gå op til 5 minutter før virkningen indtræffer, efter at der gemmes.",
"Save" : "Gem",
"Can not be edited from here due to insufficient permissions." : "Kan ikke redigeres herfra på grund af utilstrækkelige rettigheder.",
"Settings" : "Indstillinger",
diff --git a/apps/files/l10n/pt_PT.js b/apps/files/l10n/pt_PT.js
index 32f7dee7d43..92ce9bd6d10 100644
--- a/apps/files/l10n/pt_PT.js
+++ b/apps/files/l10n/pt_PT.js
@@ -41,6 +41,8 @@ OC.L10N.register(
"Select" : "Selecionar",
"Pending" : "Pendente",
"Unable to determine date" : "Impossível determinar a data",
+ "This operation is forbidden" : "Esta operação é proibida",
+ "This directory is unavailable, please check the logs or contact the administrator" : "Esta diretoria está indisponível, por favor, verifique os registos ou contacte o administrador",
"Error moving file." : "Erro a mover o ficheiro.",
"Error moving file" : "Erro ao mover o ficheiro",
"Error" : "Erro",
@@ -61,13 +63,19 @@ OC.L10N.register(
"New" : "Novo",
"\"{name}\" is an invalid file name." : "\"{name}\" é um nome de ficheiro inválido.",
"File name cannot be empty." : "O nome do ficheiro não pode estar em branco.",
+ "Storage of {owner} is full, files can not be updated or synced anymore!" : "O armazenamento de {owner} está cheiro. Os ficheiros já não podem ser atualizados ou sincronizados!",
"Your storage is full, files can not be updated or synced anymore!" : "O seu armazenamento está cheio, os ficheiros já não podem ser atualizados ou sincronizados.",
+ "Storage of {owner} is almost full ({usedSpacePercent}%)" : "O armazenamento de {owner} está quase cheio ({usedSpacePercent}%)",
"Your storage is almost full ({usedSpacePercent}%)" : "O seu armazenamento está quase cheiro ({usedSpacePercent}%)",
"_matches '{filter}'_::_match '{filter}'_" : ["corresponde a '{filter}'","correspondem a '{filter}'"],
+ "Path" : "Caminho",
+ "_%n byte_::_%n bytes_" : ["%n byte","%n bytes"],
"Favorited" : "Assinalado como Favorito",
"Favorite" : "Favorito",
+ "{newname} already exists" : "{newname} já existe",
"Upload" : "Enviar",
"Text file" : "Ficheiro de Texto",
+ "New text file.txt" : "Novo texto ficheiro.txt",
"Folder" : "Pasta",
"New folder" : "Nova Pasta",
"An error occurred while trying to update the tags" : "Ocorreu um erro ao tentar atualizar as tags",
@@ -91,6 +99,7 @@ OC.L10N.register(
"File handling" : "Manuseamento do ficheiro",
"Maximum upload size" : "Tamanho máximo de envio",
"max. possible: " : "Máx. possível: ",
+ "With PHP-FPM this value may take up to 5 minutes to take effect after saving." : "Com PHP-FPM este valor poderá demorar até 5 minutos para ser aplicado depois de guardar.",
"Save" : "Guardar",
"Can not be edited from here due to insufficient permissions." : "Não pode ser editado a partir daqui devido a permissões insuficientes.",
"Settings" : "Definições",
diff --git a/apps/files/l10n/pt_PT.json b/apps/files/l10n/pt_PT.json
index 5c6a8aececa..99718047020 100644
--- a/apps/files/l10n/pt_PT.json
+++ b/apps/files/l10n/pt_PT.json
@@ -39,6 +39,8 @@
"Select" : "Selecionar",
"Pending" : "Pendente",
"Unable to determine date" : "Impossível determinar a data",
+ "This operation is forbidden" : "Esta operação é proibida",
+ "This directory is unavailable, please check the logs or contact the administrator" : "Esta diretoria está indisponível, por favor, verifique os registos ou contacte o administrador",
"Error moving file." : "Erro a mover o ficheiro.",
"Error moving file" : "Erro ao mover o ficheiro",
"Error" : "Erro",
@@ -59,13 +61,19 @@
"New" : "Novo",
"\"{name}\" is an invalid file name." : "\"{name}\" é um nome de ficheiro inválido.",
"File name cannot be empty." : "O nome do ficheiro não pode estar em branco.",
+ "Storage of {owner} is full, files can not be updated or synced anymore!" : "O armazenamento de {owner} está cheiro. Os ficheiros já não podem ser atualizados ou sincronizados!",
"Your storage is full, files can not be updated or synced anymore!" : "O seu armazenamento está cheio, os ficheiros já não podem ser atualizados ou sincronizados.",
+ "Storage of {owner} is almost full ({usedSpacePercent}%)" : "O armazenamento de {owner} está quase cheio ({usedSpacePercent}%)",
"Your storage is almost full ({usedSpacePercent}%)" : "O seu armazenamento está quase cheiro ({usedSpacePercent}%)",
"_matches '{filter}'_::_match '{filter}'_" : ["corresponde a '{filter}'","correspondem a '{filter}'"],
+ "Path" : "Caminho",
+ "_%n byte_::_%n bytes_" : ["%n byte","%n bytes"],
"Favorited" : "Assinalado como Favorito",
"Favorite" : "Favorito",
+ "{newname} already exists" : "{newname} já existe",
"Upload" : "Enviar",
"Text file" : "Ficheiro de Texto",
+ "New text file.txt" : "Novo texto ficheiro.txt",
"Folder" : "Pasta",
"New folder" : "Nova Pasta",
"An error occurred while trying to update the tags" : "Ocorreu um erro ao tentar atualizar as tags",
@@ -89,6 +97,7 @@
"File handling" : "Manuseamento do ficheiro",
"Maximum upload size" : "Tamanho máximo de envio",
"max. possible: " : "Máx. possível: ",
+ "With PHP-FPM this value may take up to 5 minutes to take effect after saving." : "Com PHP-FPM este valor poderá demorar até 5 minutos para ser aplicado depois de guardar.",
"Save" : "Guardar",
"Can not be edited from here due to insufficient permissions." : "Não pode ser editado a partir daqui devido a permissões insuficientes.",
"Settings" : "Definições",
diff --git a/apps/files_external/l10n/da.js b/apps/files_external/l10n/da.js
index b1f058efbb3..435884aa11d 100644
--- a/apps/files_external/l10n/da.js
+++ b/apps/files_external/l10n/da.js
@@ -12,6 +12,8 @@ OC.L10N.register(
"Invalid mount point" : "Fokert monteringspunkt",
"Objectstore forbidden" : "Objectstore er forbudt",
"Invalid storage backend \"%s\"" : "Forkert lager til backend \"%s\"en",
+ "Not permitted to use backend \"%s\"" : "Ikke tilladt at bruge backend \"%s\"",
+ "Not permitted to use authentication mechanism \"%s\"" : "Ikke tilladt at bruge autorisation mekanismen \"%s\"",
"Unsatisfied backend parameters" : "Utilfredsstillede backend-parametre",
"Unsatisfied authentication mechanism parameters" : "Utilfredsstillede parametre for godkendelsesmekanisme",
"Personal" : "Personligt",
@@ -41,11 +43,16 @@ OC.L10N.register(
"OAuth2" : "OAuth2",
"Client ID" : "Klient-ID",
"Client secret" : "Klient hemmelighed",
+ "OpenStack" : "OpenStack",
"Username" : "Brugernavn",
"Password" : "Kodeord",
+ "Tenant name" : "Lejernavn",
+ "Identity endpoint URL" : "Identificer afslutnings URL",
+ "Rackspace" : "Hyldeplads",
"API key" : "API nøgle",
"Username and password" : "Brugernavn og kodeord",
"Session credentials" : "Brugeroplysninger for session",
+ "RSA public key" : "RSA offentlig nøgle",
"Public key" : "Offentlig nøgle",
"Amazon S3" : "Amazon S3",
"Bucket" : "Bucket",
@@ -68,10 +75,15 @@ OC.L10N.register(
"ownCloud" : "ownCloud",
"SFTP" : "SFTP",
"Root" : "Root",
+ "SFTP with secret key login [DEPRECATED]" : "SFTP med det hemmelige nøgle login [DEPRECATED]",
"SMB / CIFS" : "SMB / CIFS",
"Share" : "Del",
+ "Domain" : "Domæne",
+ "SMB / CIFS using OC login [DEPRECATED]" : "SMB / CIFS der bruger OC login [DEPRECATED]",
"Username as share" : "Brugernavn som deling",
"OpenStack Object Storage" : "OpenStack Object Storage",
+ "Service name" : "Tjenestenavn",
+ "Request timeout (seconds)" : "Anmodning timeout (sekunder)",
"<b>Note:</b> " : "<b>Note:</b> ",
"<b>Note:</b> The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>Bemærk:</b> cURL-understøttelsen i PHP er enten ikke aktiveret eller installeret. Monteringen af %s er ikke mulig. Anmod din systemadministrator om at installere det.",
"<b>Note:</b> The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>Bemærk:</b> FTP understøttelsen i PHP er enten ikke aktiveret eller installeret. Montering af %s er ikke muligt. Anmod din systemadministrator om at installere det.",
diff --git a/apps/files_external/l10n/da.json b/apps/files_external/l10n/da.json
index 811de509421..631fb196624 100644
--- a/apps/files_external/l10n/da.json
+++ b/apps/files_external/l10n/da.json
@@ -10,6 +10,8 @@
"Invalid mount point" : "Fokert monteringspunkt",
"Objectstore forbidden" : "Objectstore er forbudt",
"Invalid storage backend \"%s\"" : "Forkert lager til backend \"%s\"en",
+ "Not permitted to use backend \"%s\"" : "Ikke tilladt at bruge backend \"%s\"",
+ "Not permitted to use authentication mechanism \"%s\"" : "Ikke tilladt at bruge autorisation mekanismen \"%s\"",
"Unsatisfied backend parameters" : "Utilfredsstillede backend-parametre",
"Unsatisfied authentication mechanism parameters" : "Utilfredsstillede parametre for godkendelsesmekanisme",
"Personal" : "Personligt",
@@ -39,11 +41,16 @@
"OAuth2" : "OAuth2",
"Client ID" : "Klient-ID",
"Client secret" : "Klient hemmelighed",
+ "OpenStack" : "OpenStack",
"Username" : "Brugernavn",
"Password" : "Kodeord",
+ "Tenant name" : "Lejernavn",
+ "Identity endpoint URL" : "Identificer afslutnings URL",
+ "Rackspace" : "Hyldeplads",
"API key" : "API nøgle",
"Username and password" : "Brugernavn og kodeord",
"Session credentials" : "Brugeroplysninger for session",
+ "RSA public key" : "RSA offentlig nøgle",
"Public key" : "Offentlig nøgle",
"Amazon S3" : "Amazon S3",
"Bucket" : "Bucket",
@@ -66,10 +73,15 @@
"ownCloud" : "ownCloud",
"SFTP" : "SFTP",
"Root" : "Root",
+ "SFTP with secret key login [DEPRECATED]" : "SFTP med det hemmelige nøgle login [DEPRECATED]",
"SMB / CIFS" : "SMB / CIFS",
"Share" : "Del",
+ "Domain" : "Domæne",
+ "SMB / CIFS using OC login [DEPRECATED]" : "SMB / CIFS der bruger OC login [DEPRECATED]",
"Username as share" : "Brugernavn som deling",
"OpenStack Object Storage" : "OpenStack Object Storage",
+ "Service name" : "Tjenestenavn",
+ "Request timeout (seconds)" : "Anmodning timeout (sekunder)",
"<b>Note:</b> " : "<b>Note:</b> ",
"<b>Note:</b> The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>Bemærk:</b> cURL-understøttelsen i PHP er enten ikke aktiveret eller installeret. Monteringen af %s er ikke mulig. Anmod din systemadministrator om at installere det.",
"<b>Note:</b> The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>Bemærk:</b> FTP understøttelsen i PHP er enten ikke aktiveret eller installeret. Montering af %s er ikke muligt. Anmod din systemadministrator om at installere det.",
diff --git a/apps/files_external/l10n/fi_FI.js b/apps/files_external/l10n/fi_FI.js
index 2243f5f5526..92e93d9ed3a 100644
--- a/apps/files_external/l10n/fi_FI.js
+++ b/apps/files_external/l10n/fi_FI.js
@@ -23,6 +23,7 @@ OC.L10N.register(
"All users. Type to select user or group." : "Kaikki käyttäjät. Kirjoita valitaksesi käyttäjän tai ryhmän.",
"(group)" : "(ryhmä)",
"Saved" : "Tallennettu",
+ "Builtin" : "Sisäänrakennettu",
"None" : "Ei mitään",
"OAuth1" : "OAuth1",
"App key" : "Sovellusavain",
@@ -33,6 +34,7 @@ OC.L10N.register(
"OpenStack" : "OpenStack",
"Username" : "Käyttäjätunnus",
"Password" : "Salasana",
+ "Rackspace" : "Rackspace",
"API key" : "API-avain",
"Username and password" : "Käyttäjätunnus ja salasana",
"RSA public key" : "Julkinen RSA-avain",
diff --git a/apps/files_external/l10n/fi_FI.json b/apps/files_external/l10n/fi_FI.json
index b629fad87c6..6459b33a126 100644
--- a/apps/files_external/l10n/fi_FI.json
+++ b/apps/files_external/l10n/fi_FI.json
@@ -21,6 +21,7 @@
"All users. Type to select user or group." : "Kaikki käyttäjät. Kirjoita valitaksesi käyttäjän tai ryhmän.",
"(group)" : "(ryhmä)",
"Saved" : "Tallennettu",
+ "Builtin" : "Sisäänrakennettu",
"None" : "Ei mitään",
"OAuth1" : "OAuth1",
"App key" : "Sovellusavain",
@@ -31,6 +32,7 @@
"OpenStack" : "OpenStack",
"Username" : "Käyttäjätunnus",
"Password" : "Salasana",
+ "Rackspace" : "Rackspace",
"API key" : "API-avain",
"Username and password" : "Käyttäjätunnus ja salasana",
"RSA public key" : "Julkinen RSA-avain",
diff --git a/apps/files_external/l10n/it.js b/apps/files_external/l10n/it.js
index 9c49d95fc31..368ff49195e 100644
--- a/apps/files_external/l10n/it.js
+++ b/apps/files_external/l10n/it.js
@@ -12,6 +12,8 @@ OC.L10N.register(
"Invalid mount point" : "Punto di mount non valido",
"Objectstore forbidden" : "Objectstore vietato",
"Invalid storage backend \"%s\"" : "Motore di archiviazione \"%s\" non valido",
+ "Not permitted to use backend \"%s\"" : "Utilizzo del motore \"%s\" non permesso",
+ "Not permitted to use authentication mechanism \"%s\"" : "Utilizzo del meccanismo di autenticazione \"%s\" non permesso",
"Unsatisfied backend parameters" : "Parametri del motore non soddisfatti",
"Unsatisfied authentication mechanism parameters" : "Parametri del meccanismo di autenticazione non soddisfatti",
"Personal" : "Personale",
@@ -72,11 +74,15 @@ OC.L10N.register(
"ownCloud" : "ownCloud",
"SFTP" : "SFTP",
"Root" : "Radice",
+ "SFTP with secret key login [DEPRECATED]" : "SFTP con accesso a chiave segreta [DEPRECATO]",
"SMB / CIFS" : "SMB / CIFS",
"Share" : "Condividi",
+ "Domain" : "Dominio",
+ "SMB / CIFS using OC login [DEPRECATED]" : "SMB / CIFS utilizzando le credenziali di OC [DEPRECATO]",
"Username as share" : "Nome utente come condivisione",
"OpenStack Object Storage" : "OpenStack Object Storage",
"Service name" : "Nome servizio",
+ "Request timeout (seconds)" : "Tempo massimo della richiesta (secondi)",
"<b>Note:</b> " : "<b>Nota:</b>",
"<b>Note:</b> The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>Nota:</b> il supporto a cURL di PHP non è abilitato o installato. Impossibile montare %s. Chiedi al tuo amministratore di sistema di installarlo.",
"<b>Note:</b> The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>Nota:</b> il supporto a FTP in PHP non è abilitato o installato. Impossibile montare %s. Chiedi al tuo amministratore di sistema di installarlo.",
diff --git a/apps/files_external/l10n/it.json b/apps/files_external/l10n/it.json
index 3f6020708d2..4da556760f6 100644
--- a/apps/files_external/l10n/it.json
+++ b/apps/files_external/l10n/it.json
@@ -10,6 +10,8 @@
"Invalid mount point" : "Punto di mount non valido",
"Objectstore forbidden" : "Objectstore vietato",
"Invalid storage backend \"%s\"" : "Motore di archiviazione \"%s\" non valido",
+ "Not permitted to use backend \"%s\"" : "Utilizzo del motore \"%s\" non permesso",
+ "Not permitted to use authentication mechanism \"%s\"" : "Utilizzo del meccanismo di autenticazione \"%s\" non permesso",
"Unsatisfied backend parameters" : "Parametri del motore non soddisfatti",
"Unsatisfied authentication mechanism parameters" : "Parametri del meccanismo di autenticazione non soddisfatti",
"Personal" : "Personale",
@@ -70,11 +72,15 @@
"ownCloud" : "ownCloud",
"SFTP" : "SFTP",
"Root" : "Radice",
+ "SFTP with secret key login [DEPRECATED]" : "SFTP con accesso a chiave segreta [DEPRECATO]",
"SMB / CIFS" : "SMB / CIFS",
"Share" : "Condividi",
+ "Domain" : "Dominio",
+ "SMB / CIFS using OC login [DEPRECATED]" : "SMB / CIFS utilizzando le credenziali di OC [DEPRECATO]",
"Username as share" : "Nome utente come condivisione",
"OpenStack Object Storage" : "OpenStack Object Storage",
"Service name" : "Nome servizio",
+ "Request timeout (seconds)" : "Tempo massimo della richiesta (secondi)",
"<b>Note:</b> " : "<b>Nota:</b>",
"<b>Note:</b> The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>Nota:</b> il supporto a cURL di PHP non è abilitato o installato. Impossibile montare %s. Chiedi al tuo amministratore di sistema di installarlo.",
"<b>Note:</b> The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>Nota:</b> il supporto a FTP in PHP non è abilitato o installato. Impossibile montare %s. Chiedi al tuo amministratore di sistema di installarlo.",
diff --git a/apps/files_external/l10n/nb_NO.js b/apps/files_external/l10n/nb_NO.js
index 1401bbe7012..0089d42288d 100644
--- a/apps/files_external/l10n/nb_NO.js
+++ b/apps/files_external/l10n/nb_NO.js
@@ -12,6 +12,8 @@ OC.L10N.register(
"Invalid mount point" : "Ugyldig oppkoblingspunkt",
"Objectstore forbidden" : "Objektlager forbudt",
"Invalid storage backend \"%s\"" : "Ugyldig lagringsserver \"%s\"",
+ "Not permitted to use backend \"%s\"" : "Ikke tillatt å bruke server \"%s\"",
+ "Not permitted to use authentication mechanism \"%s\"" : "Ikke tillatt å bruke autentiseringsmekanisme \"%s\"",
"Unsatisfied backend parameters" : "Noen server-parameter mangler",
"Unsatisfied authentication mechanism parameters" : "Noen parametre for autentiseringsmekanisme mangler",
"Personal" : "Personlig",
@@ -41,11 +43,16 @@ OC.L10N.register(
"OAuth2" : "OAuth2",
"Client ID" : "Client ID",
"Client secret" : "Client secret",
+ "OpenStack" : "OpenStack",
"Username" : "Brukernavn",
"Password" : "Passord",
+ "Tenant name" : "Prosjektnavn",
+ "Identity endpoint URL" : "URL for identitets-endepunkt",
+ "Rackspace" : "Rackspace",
"API key" : "API-nøkkel",
"Username and password" : "Brukernavn og passord",
"Session credentials" : "Påloggingsdetaljer for økt",
+ "RSA public key" : "RSA offentlig nøkkel",
"Public key" : "Offentlig nøkkel",
"Amazon S3" : "Amazon S3",
"Bucket" : "Bucket",
@@ -68,10 +75,14 @@ OC.L10N.register(
"ownCloud" : "ownCloud",
"SFTP" : "SFTP",
"Root" : "Rot",
+ "SFTP with secret key login [DEPRECATED]" : "SFTP med hemmelig nøkkel for pålogging [FORELDET]",
"SMB / CIFS" : "SMB / CIFS",
"Share" : "Delt ressurs",
+ "SMB / CIFS using OC login [DEPRECATED]" : "SMB / CIFS med OC-pålogging [FORELDET]",
"Username as share" : "Brukernavn som share",
"OpenStack Object Storage" : "OpenStack Object Storage",
+ "Service name" : "Tjenestenavn",
+ "Request timeout (seconds)" : "Tidsavbrudd for forespørsel (sekunder)",
"<b>Note:</b> " : "<b>Merk:</b> ",
"<b>Note:</b> The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>Merk:</b> Støtte for cURL i PHP er ikke aktivert eller installert. Oppkobling av %s er ikke mulig. Be systemadministratoren om å installere det.",
"<b>Note:</b> The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>Merk:</b> FTP-støtte i PHP er ikke slått på eller installert. Kan ikke koble opp %s. Ta kontakt med systemadministratoren for å få dette installert.",
diff --git a/apps/files_external/l10n/nb_NO.json b/apps/files_external/l10n/nb_NO.json
index cf6c2d38f9d..8ee2713f329 100644
--- a/apps/files_external/l10n/nb_NO.json
+++ b/apps/files_external/l10n/nb_NO.json
@@ -10,6 +10,8 @@
"Invalid mount point" : "Ugyldig oppkoblingspunkt",
"Objectstore forbidden" : "Objektlager forbudt",
"Invalid storage backend \"%s\"" : "Ugyldig lagringsserver \"%s\"",
+ "Not permitted to use backend \"%s\"" : "Ikke tillatt å bruke server \"%s\"",
+ "Not permitted to use authentication mechanism \"%s\"" : "Ikke tillatt å bruke autentiseringsmekanisme \"%s\"",
"Unsatisfied backend parameters" : "Noen server-parameter mangler",
"Unsatisfied authentication mechanism parameters" : "Noen parametre for autentiseringsmekanisme mangler",
"Personal" : "Personlig",
@@ -39,11 +41,16 @@
"OAuth2" : "OAuth2",
"Client ID" : "Client ID",
"Client secret" : "Client secret",
+ "OpenStack" : "OpenStack",
"Username" : "Brukernavn",
"Password" : "Passord",
+ "Tenant name" : "Prosjektnavn",
+ "Identity endpoint URL" : "URL for identitets-endepunkt",
+ "Rackspace" : "Rackspace",
"API key" : "API-nøkkel",
"Username and password" : "Brukernavn og passord",
"Session credentials" : "Påloggingsdetaljer for økt",
+ "RSA public key" : "RSA offentlig nøkkel",
"Public key" : "Offentlig nøkkel",
"Amazon S3" : "Amazon S3",
"Bucket" : "Bucket",
@@ -66,10 +73,14 @@
"ownCloud" : "ownCloud",
"SFTP" : "SFTP",
"Root" : "Rot",
+ "SFTP with secret key login [DEPRECATED]" : "SFTP med hemmelig nøkkel for pålogging [FORELDET]",
"SMB / CIFS" : "SMB / CIFS",
"Share" : "Delt ressurs",
+ "SMB / CIFS using OC login [DEPRECATED]" : "SMB / CIFS med OC-pålogging [FORELDET]",
"Username as share" : "Brukernavn som share",
"OpenStack Object Storage" : "OpenStack Object Storage",
+ "Service name" : "Tjenestenavn",
+ "Request timeout (seconds)" : "Tidsavbrudd for forespørsel (sekunder)",
"<b>Note:</b> " : "<b>Merk:</b> ",
"<b>Note:</b> The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>Merk:</b> Støtte for cURL i PHP er ikke aktivert eller installert. Oppkobling av %s er ikke mulig. Be systemadministratoren om å installere det.",
"<b>Note:</b> The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>Merk:</b> FTP-støtte i PHP er ikke slått på eller installert. Kan ikke koble opp %s. Ta kontakt med systemadministratoren for å få dette installert.",
diff --git a/apps/files_external/l10n/nl.js b/apps/files_external/l10n/nl.js
index 1f0c219c51e..a40b2afa7e8 100644
--- a/apps/files_external/l10n/nl.js
+++ b/apps/files_external/l10n/nl.js
@@ -12,6 +12,8 @@ OC.L10N.register(
"Invalid mount point" : "Ongeldig aankoppelpunt",
"Objectstore forbidden" : "Objectopslag verboden",
"Invalid storage backend \"%s\"" : "Ongeldig opslagsysteem \"%s\"",
+ "Not permitted to use backend \"%s\"" : "Niet toegestaan om \"%s\" te gebruiken",
+ "Not permitted to use authentication mechanism \"%s\"" : "Niet toegestaan om authenticatiemechanisme \"%s\" te gebruiken",
"Unsatisfied backend parameters" : "Onvoldoende backend parameters",
"Unsatisfied authentication mechanism parameters" : "Onvoldoende authenticatiemechanisme parameters",
"Personal" : "Persoonlijk",
@@ -41,11 +43,16 @@ OC.L10N.register(
"OAuth2" : "OAuth2",
"Client ID" : "Client ID",
"Client secret" : "Client secret",
+ "OpenStack" : "OpenStack",
"Username" : "Gebruikersnaam",
"Password" : "Wachtwoord",
+ "Tenant name" : "Naam tenant",
+ "Identity endpoint URL" : "Identiteiten endpoint URL",
+ "Rackspace" : "Rackspace",
"API key" : "API sleutel",
"Username and password" : "Gebruikersnaam en wachtwoord",
"Session credentials" : "Sessie inloggegevens",
+ "RSA public key" : "RSA publieke sleutel",
"Public key" : "Publieke sleutel",
"Amazon S3" : "Amazon S3",
"Bucket" : "Bucket",
@@ -68,10 +75,15 @@ OC.L10N.register(
"ownCloud" : "ownCloud",
"SFTP" : "SFTP",
"Root" : "Root",
+ "SFTP with secret key login [DEPRECATED]" : "SFTP inlog met geheime sleutel [VEROUDERD]",
"SMB / CIFS" : "SMB / CIFS",
"Share" : "Share",
+ "Domain" : "Domein",
+ "SMB / CIFS using OC login [DEPRECATED]" : "SMB / CIFS login met OC [VEROUDERD]",
"Username as share" : "Gebruikersnaam als share",
"OpenStack Object Storage" : "OpenStack Object Storage",
+ "Service name" : "Servicenaam",
+ "Request timeout (seconds)" : "Aanvraag time-out (seconds)",
"<b>Note:</b> " : "<b>Let op:</b> ",
"<b>Note:</b> The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>Let op:</b> Curl ondersteuning in PHP is niet geactiveerd of geïnstalleerd. Mounten van %s is niet mogelijk. Vraag uw systeembeheerder dit te installeren.",
"<b>Note:</b> The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>Let op:</b> FTP ondersteuning in PHP is niet geactiveerd of geïnstalleerd. Mounten van %s is niet mogelijk. Vraag uw beheerder dit te installeren.",
diff --git a/apps/files_external/l10n/nl.json b/apps/files_external/l10n/nl.json
index 948845cfa82..52507dc4744 100644
--- a/apps/files_external/l10n/nl.json
+++ b/apps/files_external/l10n/nl.json
@@ -10,6 +10,8 @@
"Invalid mount point" : "Ongeldig aankoppelpunt",
"Objectstore forbidden" : "Objectopslag verboden",
"Invalid storage backend \"%s\"" : "Ongeldig opslagsysteem \"%s\"",
+ "Not permitted to use backend \"%s\"" : "Niet toegestaan om \"%s\" te gebruiken",
+ "Not permitted to use authentication mechanism \"%s\"" : "Niet toegestaan om authenticatiemechanisme \"%s\" te gebruiken",
"Unsatisfied backend parameters" : "Onvoldoende backend parameters",
"Unsatisfied authentication mechanism parameters" : "Onvoldoende authenticatiemechanisme parameters",
"Personal" : "Persoonlijk",
@@ -39,11 +41,16 @@
"OAuth2" : "OAuth2",
"Client ID" : "Client ID",
"Client secret" : "Client secret",
+ "OpenStack" : "OpenStack",
"Username" : "Gebruikersnaam",
"Password" : "Wachtwoord",
+ "Tenant name" : "Naam tenant",
+ "Identity endpoint URL" : "Identiteiten endpoint URL",
+ "Rackspace" : "Rackspace",
"API key" : "API sleutel",
"Username and password" : "Gebruikersnaam en wachtwoord",
"Session credentials" : "Sessie inloggegevens",
+ "RSA public key" : "RSA publieke sleutel",
"Public key" : "Publieke sleutel",
"Amazon S3" : "Amazon S3",
"Bucket" : "Bucket",
@@ -66,10 +73,15 @@
"ownCloud" : "ownCloud",
"SFTP" : "SFTP",
"Root" : "Root",
+ "SFTP with secret key login [DEPRECATED]" : "SFTP inlog met geheime sleutel [VEROUDERD]",
"SMB / CIFS" : "SMB / CIFS",
"Share" : "Share",
+ "Domain" : "Domein",
+ "SMB / CIFS using OC login [DEPRECATED]" : "SMB / CIFS login met OC [VEROUDERD]",
"Username as share" : "Gebruikersnaam als share",
"OpenStack Object Storage" : "OpenStack Object Storage",
+ "Service name" : "Servicenaam",
+ "Request timeout (seconds)" : "Aanvraag time-out (seconds)",
"<b>Note:</b> " : "<b>Let op:</b> ",
"<b>Note:</b> The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>Let op:</b> Curl ondersteuning in PHP is niet geactiveerd of geïnstalleerd. Mounten van %s is niet mogelijk. Vraag uw systeembeheerder dit te installeren.",
"<b>Note:</b> The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>Let op:</b> FTP ondersteuning in PHP is niet geactiveerd of geïnstalleerd. Mounten van %s is niet mogelijk. Vraag uw beheerder dit te installeren.",
diff --git a/apps/files_external/l10n/pt_BR.js b/apps/files_external/l10n/pt_BR.js
index fefe1e899f5..9b9d1c49a49 100644
--- a/apps/files_external/l10n/pt_BR.js
+++ b/apps/files_external/l10n/pt_BR.js
@@ -12,6 +12,8 @@ OC.L10N.register(
"Invalid mount point" : "Ponto de montagem inválido",
"Objectstore forbidden" : "Proibido armazenamento de objetos",
"Invalid storage backend \"%s\"" : "Armazenamento backend inválido \"%s\"",
+ "Not permitted to use backend \"%s\"" : "Não é permitido o uso de backend \"%s\"",
+ "Not permitted to use authentication mechanism \"%s\"" : "Não é permitido usar o mecanismo de autenticação \"%s\"",
"Unsatisfied backend parameters" : "Parâmetros de back-end não-atendidos",
"Unsatisfied authentication mechanism parameters" : "Parâmetros de mecanismos de autenticação não satisfeitos",
"Personal" : "Pessoal",
@@ -41,11 +43,16 @@ OC.L10N.register(
"OAuth2" : "OAuth2",
"Client ID" : "ID do Cliente",
"Client secret" : "Segredo do cliente",
+ "OpenStack" : "OpenStack",
"Username" : "Nome de Usuário",
"Password" : "Senha",
+ "Tenant name" : "Nome do inquilino",
+ "Identity endpoint URL" : "Identidade pontofinal URL",
+ "Rackspace" : "Espaço em rack",
"API key" : "Chave API",
"Username and password" : "Nome de Usuário e senha",
"Session credentials" : "Credenciais de Sessão",
+ "RSA public key" : "Chave pública RSA",
"Public key" : "Chave pública",
"Amazon S3" : "Amazon S3",
"Bucket" : "Cesta",
@@ -68,10 +75,14 @@ OC.L10N.register(
"ownCloud" : "ownCloud",
"SFTP" : "SFTP",
"Root" : "Raiz",
+ "SFTP with secret key login [DEPRECATED]" : "SFTP com chave secreta de login [DEPRECATED]",
"SMB / CIFS" : "SMB / CIFS",
"Share" : "Compartilhar",
+ "SMB / CIFS using OC login [DEPRECATED]" : "SMB / CIFS usando OC de login [DEPRECATED]",
"Username as share" : "Nome de usuário como compartilhado",
"OpenStack Object Storage" : "Armazenamento de Objetos OpenStack",
+ "Service name" : "Nome do serviço",
+ "Request timeout (seconds)" : "Tempo esgotado requerido (segundos)",
"<b>Note:</b> " : "<b>Nota:</b>",
"<b>Note:</b> The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>Nota:</b> O suporte cURL do PHP não está habilitado ou instalado. Montagem de %s não é possível. Por favor, solicite ao seu administrador do sistema para instalá-lo.",
"<b>Note:</b> The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>Nota:</b> O suporte FTP no PHP não está habilitado ou instalado. Montagem de %s não é possível. Por favor, solicite ao seu administrador do sistema para instalá-lo.",
diff --git a/apps/files_external/l10n/pt_BR.json b/apps/files_external/l10n/pt_BR.json
index f133b469f76..a863e6abffb 100644
--- a/apps/files_external/l10n/pt_BR.json
+++ b/apps/files_external/l10n/pt_BR.json
@@ -10,6 +10,8 @@
"Invalid mount point" : "Ponto de montagem inválido",
"Objectstore forbidden" : "Proibido armazenamento de objetos",
"Invalid storage backend \"%s\"" : "Armazenamento backend inválido \"%s\"",
+ "Not permitted to use backend \"%s\"" : "Não é permitido o uso de backend \"%s\"",
+ "Not permitted to use authentication mechanism \"%s\"" : "Não é permitido usar o mecanismo de autenticação \"%s\"",
"Unsatisfied backend parameters" : "Parâmetros de back-end não-atendidos",
"Unsatisfied authentication mechanism parameters" : "Parâmetros de mecanismos de autenticação não satisfeitos",
"Personal" : "Pessoal",
@@ -39,11 +41,16 @@
"OAuth2" : "OAuth2",
"Client ID" : "ID do Cliente",
"Client secret" : "Segredo do cliente",
+ "OpenStack" : "OpenStack",
"Username" : "Nome de Usuário",
"Password" : "Senha",
+ "Tenant name" : "Nome do inquilino",
+ "Identity endpoint URL" : "Identidade pontofinal URL",
+ "Rackspace" : "Espaço em rack",
"API key" : "Chave API",
"Username and password" : "Nome de Usuário e senha",
"Session credentials" : "Credenciais de Sessão",
+ "RSA public key" : "Chave pública RSA",
"Public key" : "Chave pública",
"Amazon S3" : "Amazon S3",
"Bucket" : "Cesta",
@@ -66,10 +73,14 @@
"ownCloud" : "ownCloud",
"SFTP" : "SFTP",
"Root" : "Raiz",
+ "SFTP with secret key login [DEPRECATED]" : "SFTP com chave secreta de login [DEPRECATED]",
"SMB / CIFS" : "SMB / CIFS",
"Share" : "Compartilhar",
+ "SMB / CIFS using OC login [DEPRECATED]" : "SMB / CIFS usando OC de login [DEPRECATED]",
"Username as share" : "Nome de usuário como compartilhado",
"OpenStack Object Storage" : "Armazenamento de Objetos OpenStack",
+ "Service name" : "Nome do serviço",
+ "Request timeout (seconds)" : "Tempo esgotado requerido (segundos)",
"<b>Note:</b> " : "<b>Nota:</b>",
"<b>Note:</b> The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>Nota:</b> O suporte cURL do PHP não está habilitado ou instalado. Montagem de %s não é possível. Por favor, solicite ao seu administrador do sistema para instalá-lo.",
"<b>Note:</b> The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>Nota:</b> O suporte FTP no PHP não está habilitado ou instalado. Montagem de %s não é possível. Por favor, solicite ao seu administrador do sistema para instalá-lo.",
diff --git a/apps/files_external/l10n/th_TH.js b/apps/files_external/l10n/th_TH.js
index 34c1f74ecf8..89308e5889c 100644
--- a/apps/files_external/l10n/th_TH.js
+++ b/apps/files_external/l10n/th_TH.js
@@ -78,6 +78,7 @@ OC.L10N.register(
"SFTP with secret key login [DEPRECATED]" : "SFTP กับรหัสลับเข้าสู่ระบบ [ยกเลิก]",
"SMB / CIFS" : "SMB / CIFS",
"Share" : "แชร์",
+ "Domain" : "โดเมน",
"SMB / CIFS using OC login [DEPRECATED]" : "SMB / CIFS กำลังใช้ OC เข้าสู่ระบบ [ยกเลิก]",
"Username as share" : "ชื่อผู้ใช้ที่แชร์",
"OpenStack Object Storage" : "OpenStack Object Storage",
diff --git a/apps/files_external/l10n/th_TH.json b/apps/files_external/l10n/th_TH.json
index cb18b221c4a..5b167001e4e 100644
--- a/apps/files_external/l10n/th_TH.json
+++ b/apps/files_external/l10n/th_TH.json
@@ -76,6 +76,7 @@
"SFTP with secret key login [DEPRECATED]" : "SFTP กับรหัสลับเข้าสู่ระบบ [ยกเลิก]",
"SMB / CIFS" : "SMB / CIFS",
"Share" : "แชร์",
+ "Domain" : "โดเมน",
"SMB / CIFS using OC login [DEPRECATED]" : "SMB / CIFS กำลังใช้ OC เข้าสู่ระบบ [ยกเลิก]",
"Username as share" : "ชื่อผู้ใช้ที่แชร์",
"OpenStack Object Storage" : "OpenStack Object Storage",
diff --git a/apps/files_external/lib/amazons3.php b/apps/files_external/lib/amazons3.php
index 7c6ac4cbdd5..34e8974a6d5 100644
--- a/apps/files_external/lib/amazons3.php
+++ b/apps/files_external/lib/amazons3.php
@@ -592,7 +592,10 @@ class AmazonS3 extends \OC\Files\Storage\Common {
'key' => $this->params['key'],
'secret' => $this->params['secret'],
'base_url' => $base_url,
- 'region' => $this->params['region']
+ 'region' => $this->params['region'],
+ S3Client::COMMAND_PARAMS => [
+ 'PathStyle' => $this->params['use_path_style'],
+ ],
));
if (!$this->connection->isValidBucketName($this->bucket)) {
diff --git a/apps/files_external/lib/backend/smb.php b/apps/files_external/lib/backend/smb.php
index 350eca1de34..7865b44d689 100644
--- a/apps/files_external/lib/backend/smb.php
+++ b/apps/files_external/lib/backend/smb.php
@@ -26,6 +26,7 @@ use \OCA\Files_External\Lib\Backend\Backend;
use \OCA\Files_External\Lib\DefinitionParameter;
use \OCA\Files_External\Lib\Auth\AuthMechanism;
use \OCA\Files_External\Service\BackendService;
+use \OCA\Files_External\Lib\StorageConfig;
use \OCA\Files_External\Lib\LegacyDependencyCheckPolyfill;
use \OCA\Files_External\Lib\Auth\Password\Password;
@@ -45,10 +46,22 @@ class SMB extends Backend {
(new DefinitionParameter('share', $l->t('Share'))),
(new DefinitionParameter('root', $l->t('Remote subfolder')))
->setFlag(DefinitionParameter::FLAG_OPTIONAL),
+ (new DefinitionParameter('domain', $l->t('Domain')))
+ ->setFlag(DefinitionParameter::FLAG_OPTIONAL),
])
->addAuthScheme(AuthMechanism::SCHEME_PASSWORD)
->setLegacyAuthMechanism($legacyAuth)
;
}
+ /**
+ * @param StorageConfig $storage
+ */
+ public function manipulateStorageConfig(StorageConfig &$storage) {
+ $user = $storage->getBackendOption('user');
+ if ($domain = $storage->getBackendOption('domain')) {
+ $storage->setBackendOption('user', $domain.'\\'.$user);
+ }
+ }
+
}
diff --git a/apps/files_external/lib/config/configadapter.php b/apps/files_external/lib/config/configadapter.php
index a255a7b3d25..cb8c2f24caa 100644
--- a/apps/files_external/lib/config/configadapter.php
+++ b/apps/files_external/lib/config/configadapter.php
@@ -114,7 +114,7 @@ class ConfigAdapter implements IMountProvider {
$this->userStoragesService->setUser($user);
$this->userGlobalStoragesService->setUser($user);
- foreach ($this->userGlobalStoragesService->getAllStorages() as $storage) {
+ foreach ($this->userGlobalStoragesService->getUniqueStorages() as $storage) {
try {
$this->prepareStorageConfig($storage, $user);
$impl = $this->constructStorage($storage);
diff --git a/apps/files_external/service/userglobalstoragesservice.php b/apps/files_external/service/userglobalstoragesservice.php
index c59652d057f..b60473f131e 100644
--- a/apps/files_external/service/userglobalstoragesservice.php
+++ b/apps/files_external/service/userglobalstoragesservice.php
@@ -26,6 +26,7 @@ use \OCA\Files_External\Service\BackendService;
use \OCP\IUserSession;
use \OCP\IGroupManager;
use \OCA\Files_External\Service\UserTrait;
+use \OCA\Files_External\Lib\StorageConfig;
/**
* Service class to read global storages applicable to the user
@@ -109,4 +110,60 @@ class UserGlobalStoragesService extends GlobalStoragesService {
throw new \DomainException('UserGlobalStoragesService writing disallowed');
}
+ /**
+ * Get unique storages, in case two are defined with the same mountpoint
+ * Higher priority storages take precedence
+ *
+ * @return StorageConfig[]
+ */
+ public function getUniqueStorages() {
+ $storages = $this->getAllStorages();
+
+ $storagesByMountpoint = [];
+ foreach ($storages as $storage) {
+ $storagesByMountpoint[$storage->getMountPoint()][] = $storage;
+ }
+
+ $result = [];
+ foreach ($storagesByMountpoint as $storageList) {
+ $storage = array_reduce($storageList, function($carry, $item) {
+ if (isset($carry)) {
+ $carryPriorityType = $this->getPriorityType($carry);
+ $itemPriorityType = $this->getPriorityType($item);
+ if ($carryPriorityType > $itemPriorityType) {
+ return $carry;
+ } elseif ($carryPriorityType === $itemPriorityType) {
+ if ($carry->getPriority() > $item->getPriority()) {
+ return $carry;
+ }
+ }
+ }
+ return $item;
+ });
+ $result[$storage->getID()] = $storage;
+ }
+
+ return $result;
+ }
+
+ /**
+ * Get a priority 'type', where a bigger number means higher priority
+ * user applicable > group applicable > 'all'
+ *
+ * @param StorageConfig $storage
+ * @return int
+ */
+ protected function getPriorityType(StorageConfig $storage) {
+ $applicableUsers = $storage->getApplicableUsers();
+ $applicableGroups = $storage->getApplicableGroups();
+
+ if ($applicableUsers && $applicableUsers[0] !== 'all') {
+ return 2;
+ }
+ if ($applicableGroups) {
+ return 1;
+ }
+ return 0;
+ }
+
}
diff --git a/apps/files_external/tests/backends/amazons3.php b/apps/files_external/tests/backends/amazons3.php
index 1923ddc30b1..7e88f3d0b74 100644
--- a/apps/files_external/tests/backends/amazons3.php
+++ b/apps/files_external/tests/backends/amazons3.php
@@ -32,11 +32,11 @@ class AmazonS3 extends Storage {
protected function setUp() {
parent::setUp();
- $this->config = include('files_external/tests/config.php');
- if ( ! is_array($this->config) or ! isset($this->config['amazons3']) or ! $this->config['amazons3']['run']) {
+ $this->config = include('files_external/tests/config.amazons3.php');
+ if ( ! is_array($this->config) or ! $this->config['run']) {
$this->markTestSkipped('AmazonS3 backend not configured');
}
- $this->instance = new \OC\Files\Storage\AmazonS3($this->config['amazons3']);
+ $this->instance = new \OC\Files\Storage\AmazonS3($this->config);
}
protected function tearDown() {
diff --git a/apps/files_external/tests/env/start-amazons3-ceph.sh b/apps/files_external/tests/env/start-amazons3-ceph.sh
new file mode 100755
index 00000000000..5f274f10ca2
--- /dev/null
+++ b/apps/files_external/tests/env/start-amazons3-ceph.sh
@@ -0,0 +1,81 @@
+#!/bin/bash
+#
+# ownCloud
+#
+# This script start a docker container to test the files_external tests
+# against. It will also change the files_external config to use the docker
+# container as testing environment. This is reverted in the stop step.W
+#
+# Set environment variable DEBUG to print config file
+#
+# @author Morris Jobke
+# @author Robin McCorkell
+# @copyright 2015 ownCloud
+
+if ! command -v docker >/dev/null 2>&1; then
+ echo "No docker executable found - skipped docker setup"
+ exit 0;
+fi
+
+echo "Docker executable found - setup docker"
+
+docker_image=xenopathic/ceph-keystone
+
+echo "Fetch recent ${docker_image} docker image"
+docker pull ${docker_image}
+
+# retrieve current folder to place the config in the parent folder
+thisFolder=`echo $0 | replace "env/start-amazons3-ceph.sh" ""`
+
+if [ -z "$thisFolder" ]; then
+ thisFolder="."
+fi;
+
+user=test
+accesskey=aaabbbccc
+secretkey=cccbbbaaa
+bucket=testbucket
+port=80
+
+container=`docker run -d \
+ -e RGW_CIVETWEB_PORT=$port \
+ ${docker_image}`
+
+host=`docker inspect $container | grep IPAddress | cut -d '"' -f 4`
+
+
+echo "${docker_image} container: $container"
+
+# put container IDs into a file to drop them after the test run (keep in mind that multiple tests run in parallel on the same host)
+echo $container >> $thisFolder/dockerContainerCeph.$EXECUTOR_NUMBER.amazons3
+
+# TODO find a way to determine the successful initialization inside the docker container
+echo "Waiting 20 seconds for ceph initialization ... "
+sleep 20
+
+echo "Create ceph user"
+docker exec $container radosgw-admin user create \
+ --uid="$user" --display-name="$user" \
+ --access-key="$accesskey" --secret="$secretkey" \
+ >/dev/null
+
+cat > $thisFolder/config.amazons3.php <<DELIM
+<?php
+
+return array(
+ 'run'=>true,
+ 'bucket'=>'$bucket',
+ 'hostname'=>'$host',
+ 'port'=>'$port',
+ 'key'=>'$accesskey',
+ 'secret'=>'$secretkey',
+ 'use_ssl'=>false,
+ 'use_path_style'=>true,
+);
+
+DELIM
+
+if [ -n "$DEBUG" ]; then
+ cat $thisFolder/config.amazons3.php
+ cat $thisFolder/dockerContainerCeph.$EXECUTOR_NUMBER.amazons3
+fi
diff --git a/apps/files_external/tests/env/stop-amazons3-ceph.sh b/apps/files_external/tests/env/stop-amazons3-ceph.sh
new file mode 100755
index 00000000000..01b39b4c680
--- /dev/null
+++ b/apps/files_external/tests/env/stop-amazons3-ceph.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+#
+# ownCloud
+#
+# This script stops the docker container the files_external tests were run
+# against. It will also revert the config changes done in start step.
+#
+# @author Morris Jobke
+# @author Robin McCorkell
+# @copyright 2015 ownCloud
+
+if ! command -v docker >/dev/null 2>&1; then
+ echo "No docker executable found - skipped docker stop"
+ exit 0;
+fi
+
+echo "Docker executable found - stop and remove docker containers"
+
+# retrieve current folder to remove the config from the parent folder
+thisFolder=`echo $0 | replace "env/stop-amazons3-ceph.sh" ""`
+
+if [ -z "$thisFolder" ]; then
+ thisFolder="."
+fi;
+
+# stopping and removing docker containers
+for container in `cat $thisFolder/dockerContainerCeph.$EXECUTOR_NUMBER.amazons3`; do
+ echo "Stopping and removing docker container $container"
+ # kills running container and removes it
+ docker rm -f $container
+done;
+
+# cleanup
+rm $thisFolder/config.amazons3.php
+rm $thisFolder/dockerContainerCeph.$EXECUTOR_NUMBER.amazons3
+
diff --git a/apps/files_external/tests/service/userglobalstoragesservicetest.php b/apps/files_external/tests/service/userglobalstoragesservicetest.php
index b9e2c08c932..867872f3683 100644
--- a/apps/files_external/tests/service/userglobalstoragesservicetest.php
+++ b/apps/files_external/tests/service/userglobalstoragesservicetest.php
@@ -35,6 +35,7 @@ class UserGlobalStoragesServiceTest extends GlobalStoragesServiceTest {
const USER_ID = 'test_user';
const GROUP_ID = 'test_group';
+ const GROUP_ID2 = 'test_group2';
public function setUp() {
parent::setUp();
@@ -51,8 +52,12 @@ class UserGlobalStoragesServiceTest extends GlobalStoragesServiceTest {
$this->groupManager = $this->getMock('\OCP\IGroupManager');
$this->groupManager->method('isInGroup')
->will($this->returnCallback(function($userId, $groupId) {
- if ($userId === self::USER_ID && $groupId === self::GROUP_ID) {
- return true;
+ if ($userId === self::USER_ID) {
+ switch ($groupId) {
+ case self::GROUP_ID:
+ case self::GROUP_ID2:
+ return true;
+ }
}
return false;
}));
@@ -167,6 +172,77 @@ class UserGlobalStoragesServiceTest extends GlobalStoragesServiceTest {
$this->service->removeStorage(1);
}
+ public function getUniqueStoragesProvider() {
+ return [
+ // 'all' vs group
+ [100, [], [], 100, [], [self::GROUP_ID], 2],
+ [100, [], [self::GROUP_ID], 100, [], [], 1],
+
+ // 'all' vs user
+ [100, [], [], 100, [self::USER_ID], [], 2],
+ [100, [self::USER_ID], [], 100, [], [], 1],
+
+ // group vs user
+ [100, [], [self::GROUP_ID], 100, [self::USER_ID], [], 2],
+ [100, [self::USER_ID], [], 100, [], [self::GROUP_ID], 1],
+
+ // group+user vs group
+ [100, [], [self::GROUP_ID2], 100, [self::USER_ID], [self::GROUP_ID], 2],
+ [100, [self::USER_ID], [self::GROUP_ID], 100, [], [self::GROUP_ID2], 1],
+
+ // user vs 'all' (higher priority)
+ [200, [], [], 100, [self::USER_ID], [], 2],
+ [100, [self::USER_ID], [], 200, [], [], 1],
+
+ // group vs group (higher priority)
+ [100, [], [self::GROUP_ID2], 200, [], [self::GROUP_ID], 2],
+ [200, [], [self::GROUP_ID], 100, [], [self::GROUP_ID2], 1],
+ ];
+ }
+
+ /**
+ * @dataProvider getUniqueStoragesProvider
+ */
+ public function testGetUniqueStorages(
+ $priority1, $applicableUsers1, $applicableGroups1,
+ $priority2, $applicableUsers2, $applicableGroups2,
+ $expectedPrecedence
+ ) {
+ $backend = $this->backendService->getBackend('identifier:\OCA\Files_External\Lib\Backend\SMB');
+ $authMechanism = $this->backendService->getAuthMechanism('identifier:\Auth\Mechanism');
+
+ $storage1 = new StorageConfig();
+ $storage1->setMountPoint('mountpoint');
+ $storage1->setBackend($backend);
+ $storage1->setAuthMechanism($authMechanism);
+ $storage1->setBackendOptions(['password' => 'testPassword']);
+ $storage1->setPriority($priority1);
+ $storage1->setApplicableUsers($applicableUsers1);
+ $storage1->setApplicableGroups($applicableGroups1);
+
+ $storage1 = $this->globalStoragesService->addStorage($storage1);
+
+ $storage2 = new StorageConfig();
+ $storage2->setMountPoint('mountpoint');
+ $storage2->setBackend($backend);
+ $storage2->setAuthMechanism($authMechanism);
+ $storage2->setBackendOptions(['password' => 'testPassword']);
+ $storage2->setPriority($priority2);
+ $storage2->setApplicableUsers($applicableUsers2);
+ $storage2->setApplicableGroups($applicableGroups2);
+
+ $storage2 = $this->globalStoragesService->addStorage($storage2);
+
+ $storages = $this->service->getUniqueStorages();
+ $this->assertCount(1, $storages);
+
+ if ($expectedPrecedence === 1) {
+ $this->assertArrayHasKey($storage1->getID(), $storages);
+ } elseif ($expectedPrecedence === 2) {
+ $this->assertArrayHasKey($storage2->getID(), $storages);
+ }
+ }
+
public function testHooksAddStorage($a = null, $b = null, $c = null) {
// we don't test this here
$this->assertTrue(true);
diff --git a/apps/files_sharing/api/server2server.php b/apps/files_sharing/api/server2server.php
index 6ecaea20535..7d8860ad6ff 100644
--- a/apps/files_sharing/api/server2server.php
+++ b/apps/files_sharing/api/server2server.php
@@ -83,6 +83,8 @@ class Server2Server {
Activity::FILES_SHARING_APP, Activity::SUBJECT_REMOTE_SHARE_RECEIVED, array($user, trim($name, '/')), '', array(),
'', '', $shareWith, Activity::TYPE_REMOTE_SHARE, Activity::PRIORITY_LOW);
+ /**
+ * FIXME
$urlGenerator = \OC::$server->getURLGenerator();
$notificationManager = \OC::$server->getNotificationManager();
@@ -93,17 +95,18 @@ class Server2Server {
->setObject('remote_share', $remoteId)
->setSubject('remote_share', [$user, trim($name, '/')]);
- $acceptAction = $notification->createAction();
- $acceptAction->setLabel('accept')
- ->setLink($urlGenerator->getAbsoluteURL('/ocs/v1.php/apps/files_sharing/api/v1/remote_shares/' . $remoteId), 'POST');
$declineAction = $notification->createAction();
$declineAction->setLabel('decline')
->setLink($urlGenerator->getAbsoluteURL('/ocs/v1.php/apps/files_sharing/api/v1/remote_shares/' . $remoteId), 'DELETE');
+ $notification->addAction($declineAction);
- $notification->addAction($acceptAction)
- ->addAction($declineAction);
+ $acceptAction = $notification->createAction();
+ $acceptAction->setLabel('accept')
+ ->setLink($urlGenerator->getAbsoluteURL('/ocs/v1.php/apps/files_sharing/api/v1/remote_shares/' . $remoteId), 'POST');
+ $notification->addAction($acceptAction);
$notificationManager->notify($notification);
+ */
return new \OC_OCS_Result();
} catch (\Exception $e) {
diff --git a/apps/files_sharing/api/sharees.php b/apps/files_sharing/api/sharees.php
index 924a9dd1cd7..9e324078dad 100644
--- a/apps/files_sharing/api/sharees.php
+++ b/apps/files_sharing/api/sharees.php
@@ -20,6 +20,7 @@
*/
namespace OCA\Files_Sharing\API;
+use OCP\AppFramework\Http;
use OCP\Contacts\IManager;
use OCP\IGroup;
use OCP\IGroupManager;
@@ -291,8 +292,15 @@ class Sharees {
public function search() {
$search = isset($_GET['search']) ? (string) $_GET['search'] : '';
$itemType = isset($_GET['itemType']) ? (string) $_GET['itemType'] : null;
- $page = !empty($_GET['page']) ? max(1, (int) $_GET['page']) : 1;
- $perPage = !empty($_GET['perPage']) ? max(1, (int) $_GET['perPage']) : 200;
+ $page = isset($_GET['page']) ? (int) $_GET['page'] : 1;
+ $perPage = isset($_GET['perPage']) ? (int) $_GET['perPage'] : 200;
+
+ if ($perPage <= 0) {
+ return new \OC_OCS_Result(null, Http::STATUS_BAD_REQUEST, 'Invalid perPage argument');
+ }
+ if ($page <= 0) {
+ return new \OC_OCS_Result(null, Http::STATUS_BAD_REQUEST, 'Invalid page');
+ }
$shareTypes = [
Share::SHARE_TYPE_USER,
@@ -348,7 +356,7 @@ class Sharees {
protected function searchSharees($search, $itemType, array $shareTypes, $page, $perPage) {
// Verify arguments
if ($itemType === null) {
- return new \OC_OCS_Result(null, 400, 'missing itemType');
+ return new \OC_OCS_Result(null, Http::STATUS_BAD_REQUEST, 'Missing itemType');
}
// Get users
diff --git a/apps/files_sharing/appinfo/app.php b/apps/files_sharing/appinfo/app.php
index 20f1b046d35..15c0b864b08 100644
--- a/apps/files_sharing/appinfo/app.php
+++ b/apps/files_sharing/appinfo/app.php
@@ -54,9 +54,18 @@ $application->setupPropagation();
\OCP\Share::registerBackend('file', 'OC_Share_Backend_File');
\OCP\Share::registerBackend('folder', 'OC_Share_Backend_Folder', 'file');
-\OCP\Util::addScript('files_sharing', 'share');
-\OCP\Util::addScript('files_sharing', 'external');
-\OCP\Util::addStyle('files_sharing', 'sharetabview');
+$eventDispatcher = \OC::$server->getEventDispatcher();
+$eventDispatcher->addListener(
+ 'OCA\Files::loadAdditionalScripts',
+ function() {
+ \OCP\Util::addScript('files_sharing', 'share');
+ \OCP\Util::addScript('files_sharing', 'sharetabview');
+ \OCP\Util::addScript('files_sharing', 'external');
+ \OCP\Util::addStyle('files_sharing', 'sharetabview');
+ }
+);
+
+// \OCP\Util::addStyle('files_sharing', 'sharetabview');
\OC::$server->getActivityManager()->registerExtension(function() {
return new \OCA\Files_Sharing\Activity(
@@ -104,9 +113,12 @@ if ($config->getAppValue('core', 'shareapi_enabled', 'yes') === 'yes') {
}
}
+/**
+ * FIXME
$manager = \OC::$server->getNotificationManager();
$manager->registerNotifier(function() {
return new \OCA\Files_Sharing\Notifier(
\OC::$server->getL10NFactory()
);
});
+ */
diff --git a/apps/files_sharing/css/sharetabview.css b/apps/files_sharing/css/sharetabview.css
index 42c9bee7173..fe7a1947502 100644
--- a/apps/files_sharing/css/sharetabview.css
+++ b/apps/files_sharing/css/sharetabview.css
@@ -1,3 +1,77 @@
.app-files .shareTabView {
min-height: 100px;
}
+
+.shareTabView .oneline { white-space: nowrap; }
+
+.shareTabView .shareWithLoading {
+ padding-left: 10px;
+ position: relative;
+ right: 30px;
+ top: 2px;
+}
+
+.shareTabView .shareWithRemoteInfo {
+ padding: 11px 20px;
+}
+
+.shareTabView label {
+ white-space: nowrap;
+}
+
+.shareTabView input[type="checkbox"] {
+ margin: 0 3px 0 8px;
+ vertical-align: middle;
+}
+
+.shareTabView input[type="text"],
+.shareTabView input[type="password"] {
+ width: 94%;
+ margin-left: 0;
+}
+.shareTabView #shareWith {
+ width: 80%;
+}
+
+.shareTabView form {
+ font-size: 100%;
+ margin-left: 0;
+ margin-right: 0;
+}
+
+#shareWithList {
+ list-style-type: none;
+ padding: 0 0 16px;
+}
+
+#shareWithList li {
+ padding-top: 5px;
+ padding-bottom: 5px;
+ font-weight: bold;
+ white-space: normal;
+}
+
+#shareWithList .unshare img, #shareWithList .showCruds img {
+ vertical-align:text-bottom; /* properly align icons */
+}
+
+#shareWithList label input[type=checkbox]{
+ margin-left: 0;
+ position: relative;
+}
+#shareWithList .username{
+ padding-right: 8px;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ max-width: 254px;
+ display: inline-block;
+ overflow: hidden;
+ vertical-align: middle;
+}
+#shareWithList li label{
+ margin-right: 8px;
+}
+
+.shareTabView .icon-loading-small {
+ margin-left: -30px;
+}
diff --git a/apps/files_sharing/js/share.js b/apps/files_sharing/js/share.js
index c124d390d04..5290dfbb7d1 100644
--- a/apps/files_sharing/js/share.js
+++ b/apps/files_sharing/js/share.js
@@ -79,7 +79,9 @@
$files = fileList.$fileList.find('tr');
}
_.each($files, function(file) {
- OCA.Sharing.Util.updateFileActionIcon($(file));
+ var $tr = $(file);
+ var shareStatus = OC.Share.statuses[$tr.data('id')];
+ OCA.Sharing.Util._updateFileActionIcon($tr, !!shareStatus, shareStatus && shareStatus.link);
});
}
@@ -104,71 +106,59 @@
permissions: OC.PERMISSION_SHARE,
icon: OC.imagePath('core', 'actions/share'),
type: OCA.Files.FileActions.TYPE_INLINE,
- actionHandler: function(filename, context) {
- var $tr = context.$file;
- var itemType = 'file';
- if ($tr.data('type') === 'dir') {
- itemType = 'folder';
- }
- var possiblePermissions = $tr.data('share-permissions');
- if (_.isUndefined(possiblePermissions)) {
- possiblePermissions = $tr.data('permissions');
- }
-
- var appendTo = $tr.find('td.filename');
- // Check if drop down is already visible for a different file
- if (OC.Share.droppedDown) {
- if ($tr.attr('data-id') !== $('#dropdown').attr('data-item-source')) {
- OC.Share.hideDropDown(function () {
- $tr.addClass('mouseOver');
- OC.Share.showDropDown(itemType, $tr.data('id'), appendTo, true, possiblePermissions, filename);
- });
- } else {
- OC.Share.hideDropDown();
- }
- } else {
- $tr.addClass('mouseOver');
- OC.Share.showDropDown(itemType, $tr.data('id'), appendTo, true, possiblePermissions, filename);
- }
- $('#dropdown').on('sharesChanged', function(ev) {
- // files app current cannot show recipients on load, so we don't update the
- // icon when changed for consistency
- if (context.fileList.$el.closest('#app-content-files').length) {
- return;
- }
- var recipients = _.pluck(ev.shares[OC.Share.SHARE_TYPE_USER], 'share_with_displayname');
- var groupRecipients = _.pluck(ev.shares[OC.Share.SHARE_TYPE_GROUP], 'share_with_displayname');
- recipients = recipients.concat(groupRecipients);
- // note: we only update the data attribute because updateIcon()
- // is called automatically after this event
- if (recipients.length) {
- $tr.attr('data-share-recipients', OCA.Sharing.Util.formatRecipients(recipients));
- }
- else {
- $tr.removeAttr('data-share-recipients');
- }
- });
+ actionHandler: function(fileName) {
+ fileList.showDetailsView(fileName, 'shareTabView');
}
});
- OC.addScript('files_sharing', 'sharetabview').done(function() {
- fileList.registerTabView(new OCA.Sharing.ShareTabView('shareTabView'));
+ var shareTab = new OCA.Sharing.ShareTabView('shareTabView');
+ // detect changes and change the matching list entry
+ shareTab.on('sharesChanged', function(shareModel) {
+ var fileInfoModel = shareModel.fileInfoModel;
+ var $tr = fileList.findFileEl(fileInfoModel.get('name'));
+ OCA.Sharing.Util._updateFileListDataAttributes(fileList, $tr, shareModel);
+ if (!OCA.Sharing.Util._updateFileActionIcon($tr, shareModel.hasUserShares(), shareModel.hasLinkShare())) {
+ // remove icon, if applicable
+ OC.Share.markFileAsShared($tr, false, false);
+ }
});
+ fileList.registerTabView(shareTab);
+ },
+
+ /**
+ * Update file list data attributes
+ */
+ _updateFileListDataAttributes: function(fileList, $tr, shareModel) {
+ // files app current cannot show recipients on load, so we don't update the
+ // icon when changed for consistency
+ if (fileList.id === 'files') {
+ return;
+ }
+ var recipients = _.pluck(shareModel.get('shares'), 'share_with_displayname');
+ // note: we only update the data attribute because updateIcon()
+ if (recipients.length) {
+ $tr.attr('data-share-recipients', OCA.Sharing.Util.formatRecipients(recipients));
+ }
+ else {
+ $tr.removeAttr('data-share-recipients');
+ }
},
/**
* Update the file action share icon for the given file
*
* @param $tr file element of the file to update
+ * @param {bool} hasUserShares true if a user share exists
+ * @param {bool} hasLinkShare true if a link share exists
+ *
+ * @return {bool} true if the icon was set, false otherwise
*/
- updateFileActionIcon: function($tr) {
+ _updateFileActionIcon: function($tr, hasUserShares, hasLinkShare) {
// if the statuses are loaded already, use them for the icon
// (needed when scrolling to the next page)
- var shareStatus = OC.Share.statuses[$tr.data('id')];
- if (shareStatus || $tr.attr('data-share-recipients') || $tr.attr('data-share-owner')) {
+ if (hasUserShares || hasLinkShare || $tr.attr('data-share-recipients') || $tr.attr('data-share-owner')) {
var permissions = $tr.data('permissions');
- var hasLink = !!(shareStatus && shareStatus.link);
- OC.Share.markFileAsShared($tr, true, hasLink);
+ OC.Share.markFileAsShared($tr, true, hasLinkShare);
if ((permissions & OC.PERMISSION_SHARE) === 0 && $tr.attr('data-share-owner')) {
// if no share action exists because the admin disabled sharing for this user
// we create a share notification action to inform the user about files
@@ -187,7 +177,9 @@
return $result;
});
}
+ return true;
}
+ return false;
},
/**
diff --git a/apps/files_sharing/js/sharetabview.js b/apps/files_sharing/js/sharetabview.js
index ee572b747ea..e24320604fb 100644
--- a/apps/files_sharing/js/sharetabview.js
+++ b/apps/files_sharing/js/sharetabview.js
@@ -10,7 +10,9 @@
(function() {
var TEMPLATE =
- '<div><ul>{{#if owner}}<li>Owner: {{owner}}</li>{{/if}}</ul></div>';
+ '<div>' +
+ '<div class="dialogContainer"></div>' +
+ '</div>';
/**
* @memberof OCA.Sharing
@@ -20,7 +22,12 @@
id: 'shareTabView',
className: 'tab shareTabView',
- _template: null,
+ template: function(params) {
+ if (!this._template) {
+ this._template = Handlebars.compile(TEMPLATE);
+ }
+ return this._template(params);
+ },
getLabel: function() {
return t('files_sharing', 'Sharing');
@@ -30,23 +37,40 @@
* Renders this details view
*/
render: function() {
- this.$el.empty();
-
- if (!this._template) {
- this._template = Handlebars.compile(TEMPLATE);
+ var self = this;
+ if (this._dialog) {
+ // remove/destroy older instance
+ this._dialog.model.off();
+ this._dialog.remove();
+ this._dialog = null;
}
if (this.model) {
- console.log(this.model);
- var owner = this.model.get('shareOwner');
- if (owner === OC.currentUser) {
- owner = null;
- }
- this.$el.append(this._template({
- owner: owner
- }));
+ this.$el.html(this.template());
+ // TODO: the model should read these directly off the passed fileInfoModel
+ var attributes = {
+ itemType: this.model.isDirectory() ? 'folder' : 'file',
+ itemSource: this.model.get('id'),
+ possiblePermissions: this.model.get('sharePermissions')
+ };
+ var configModel = new OC.Share.ShareConfigModel();
+ var shareModel = new OC.Share.ShareItemModel(attributes, {
+ configModel: configModel,
+ fileInfoModel: this.model
+ });
+ this._dialog = new OC.Share.ShareDialogView({
+ configModel: configModel,
+ model: shareModel
+ });
+ this.$el.find('.dialogContainer').append(this._dialog.$el);
+ this._dialog.render();
+ this._dialog.model.fetch();
+ this._dialog.model.on('change', function() {
+ self.trigger('sharesChanged', shareModel);
+ });
} else {
+ this.$el.empty();
// TODO: render placeholder text?
}
}
diff --git a/apps/files_sharing/l10n/cs_CZ.js b/apps/files_sharing/l10n/cs_CZ.js
index bb8480e2a35..f6b43cf4fa3 100644
--- a/apps/files_sharing/l10n/cs_CZ.js
+++ b/apps/files_sharing/l10n/cs_CZ.js
@@ -41,7 +41,6 @@ OC.L10N.register(
"%2$s shared %1$s with you" : "%2$s s vámi sdílí %1$s",
"You shared %1$s via link" : "Sdílíte %1$s přes odkaz",
"Shares" : "Sdílení",
- "You received %s as a remote share from %s" : "Obdrželi jste %s nově nasdílená vzdáleně od %s ",
"Accept" : "Přijmout",
"Decline" : "Zamítnout",
"Share with me through my #ownCloud Federated Cloud ID, see %s" : "Sdílej se mnou pomocí mého #ownCloud sdruženého cloud ID, více na %s",
diff --git a/apps/files_sharing/l10n/cs_CZ.json b/apps/files_sharing/l10n/cs_CZ.json
index 677e982b6b0..f5822c627ae 100644
--- a/apps/files_sharing/l10n/cs_CZ.json
+++ b/apps/files_sharing/l10n/cs_CZ.json
@@ -39,7 +39,6 @@
"%2$s shared %1$s with you" : "%2$s s vámi sdílí %1$s",
"You shared %1$s via link" : "Sdílíte %1$s přes odkaz",
"Shares" : "Sdílení",
- "You received %s as a remote share from %s" : "Obdrželi jste %s nově nasdílená vzdáleně od %s ",
"Accept" : "Přijmout",
"Decline" : "Zamítnout",
"Share with me through my #ownCloud Federated Cloud ID, see %s" : "Sdílej se mnou pomocí mého #ownCloud sdruženého cloud ID, více na %s",
diff --git a/apps/files_sharing/l10n/da.js b/apps/files_sharing/l10n/da.js
index 87595f6cc56..7b54b361d8d 100644
--- a/apps/files_sharing/l10n/da.js
+++ b/apps/files_sharing/l10n/da.js
@@ -41,7 +41,7 @@ OC.L10N.register(
"%2$s shared %1$s with you" : "%2$s delt %1$s med dig",
"You shared %1$s via link" : "Du delte %1$s via link",
"Shares" : "Delt",
- "You received %s as a remote share from %s" : "Du modtog %s som et ekstern deling fra %s",
+ "You received %2$s as a remote share from %1$s" : "Du modtog %2$s som en ekstern deling fra %1$s",
"Accept" : "Acceptér",
"Decline" : "Afvis",
"Share with me through my #ownCloud Federated Cloud ID, see %s" : "Del med mig gennem min #ownCloud Federated Cloud ID, se %s",
diff --git a/apps/files_sharing/l10n/da.json b/apps/files_sharing/l10n/da.json
index c9ac959da2e..f430935e8bc 100644
--- a/apps/files_sharing/l10n/da.json
+++ b/apps/files_sharing/l10n/da.json
@@ -39,7 +39,7 @@
"%2$s shared %1$s with you" : "%2$s delt %1$s med dig",
"You shared %1$s via link" : "Du delte %1$s via link",
"Shares" : "Delt",
- "You received %s as a remote share from %s" : "Du modtog %s som et ekstern deling fra %s",
+ "You received %2$s as a remote share from %1$s" : "Du modtog %2$s som en ekstern deling fra %1$s",
"Accept" : "Acceptér",
"Decline" : "Afvis",
"Share with me through my #ownCloud Federated Cloud ID, see %s" : "Del med mig gennem min #ownCloud Federated Cloud ID, se %s",
diff --git a/apps/files_sharing/l10n/el.js b/apps/files_sharing/l10n/el.js
index ef688424777..18ba9bd0d31 100644
--- a/apps/files_sharing/l10n/el.js
+++ b/apps/files_sharing/l10n/el.js
@@ -41,7 +41,6 @@ OC.L10N.register(
"%2$s shared %1$s with you" : "Ο %2$s διαμοιράστηκε το %1$s με εσάς",
"You shared %1$s via link" : "Μοιραστήκατε το %1$s μέσω συνδέσμου",
"Shares" : "Κοινόχρηστοι φάκελοι",
- "You received %s as a remote share from %s" : "Λάβατε το %s ως απομακρυσμένο διαμοιρασμό από %s",
"Accept" : "Αποδοχή",
"Decline" : "Απόρριψη",
"Share with me through my #ownCloud Federated Cloud ID, see %s" : "Διαμοιρασμός με εμένα μέσω του #ownCloud Federated Cloud ID μου, δείτε %s",
diff --git a/apps/files_sharing/l10n/el.json b/apps/files_sharing/l10n/el.json
index 829ff61ceaa..f8e42195d0d 100644
--- a/apps/files_sharing/l10n/el.json
+++ b/apps/files_sharing/l10n/el.json
@@ -39,7 +39,6 @@
"%2$s shared %1$s with you" : "Ο %2$s διαμοιράστηκε το %1$s με εσάς",
"You shared %1$s via link" : "Μοιραστήκατε το %1$s μέσω συνδέσμου",
"Shares" : "Κοινόχρηστοι φάκελοι",
- "You received %s as a remote share from %s" : "Λάβατε το %s ως απομακρυσμένο διαμοιρασμό από %s",
"Accept" : "Αποδοχή",
"Decline" : "Απόρριψη",
"Share with me through my #ownCloud Federated Cloud ID, see %s" : "Διαμοιρασμός με εμένα μέσω του #ownCloud Federated Cloud ID μου, δείτε %s",
diff --git a/apps/files_sharing/l10n/fi_FI.js b/apps/files_sharing/l10n/fi_FI.js
index 396c4785537..060efce51dd 100644
--- a/apps/files_sharing/l10n/fi_FI.js
+++ b/apps/files_sharing/l10n/fi_FI.js
@@ -41,7 +41,7 @@ OC.L10N.register(
"%2$s shared %1$s with you" : "%2$s jakoi kohteen %1$s kanssasi",
"You shared %1$s via link" : "Jaoit kohteen %1$s linkin kautta",
"Shares" : "Jaot",
- "You received %s as a remote share from %s" : "Sait etäjaon %s käyttäjältä %s",
+ "You received %2$s as a remote share from %1$s" : "Sait kohteen %2$s etäjakona käyttäjältä %1$s",
"Accept" : "Hyväksy",
"Decline" : "Kieltäydy",
"Share with me through my #ownCloud Federated Cloud ID, see %s" : "Jaa kanssani käyttäen #ownCloud ja federoitua pilvitunnistetta, katso %s",
diff --git a/apps/files_sharing/l10n/fi_FI.json b/apps/files_sharing/l10n/fi_FI.json
index 56d64c0e841..091f7aec81f 100644
--- a/apps/files_sharing/l10n/fi_FI.json
+++ b/apps/files_sharing/l10n/fi_FI.json
@@ -39,7 +39,7 @@
"%2$s shared %1$s with you" : "%2$s jakoi kohteen %1$s kanssasi",
"You shared %1$s via link" : "Jaoit kohteen %1$s linkin kautta",
"Shares" : "Jaot",
- "You received %s as a remote share from %s" : "Sait etäjaon %s käyttäjältä %s",
+ "You received %2$s as a remote share from %1$s" : "Sait kohteen %2$s etäjakona käyttäjältä %1$s",
"Accept" : "Hyväksy",
"Decline" : "Kieltäydy",
"Share with me through my #ownCloud Federated Cloud ID, see %s" : "Jaa kanssani käyttäen #ownCloud ja federoitua pilvitunnistetta, katso %s",
diff --git a/apps/files_sharing/l10n/fr.js b/apps/files_sharing/l10n/fr.js
index a59409e008a..3942d18de03 100644
--- a/apps/files_sharing/l10n/fr.js
+++ b/apps/files_sharing/l10n/fr.js
@@ -42,6 +42,7 @@ OC.L10N.register(
"You shared %1$s via link" : "Vous avez partagé %1$s par lien public",
"Shares" : "Partages",
"Accept" : "Accepter",
+ "Decline" : "Refuser",
"Share with me through my #ownCloud Federated Cloud ID, see %s" : "Partagez avec moi grâce à mon identifiant Federated Cloud #owncloud %s",
"Share with me through my #ownCloud Federated Cloud ID" : "Partagez avec moi grâce à mon identifiant Federated Cloud #owncloud",
"This share is password-protected" : "Ce partage est protégé par un mot de passe",
diff --git a/apps/files_sharing/l10n/fr.json b/apps/files_sharing/l10n/fr.json
index 0bb6f2b1b9e..75b645ef259 100644
--- a/apps/files_sharing/l10n/fr.json
+++ b/apps/files_sharing/l10n/fr.json
@@ -40,6 +40,7 @@
"You shared %1$s via link" : "Vous avez partagé %1$s par lien public",
"Shares" : "Partages",
"Accept" : "Accepter",
+ "Decline" : "Refuser",
"Share with me through my #ownCloud Federated Cloud ID, see %s" : "Partagez avec moi grâce à mon identifiant Federated Cloud #owncloud %s",
"Share with me through my #ownCloud Federated Cloud ID" : "Partagez avec moi grâce à mon identifiant Federated Cloud #owncloud",
"This share is password-protected" : "Ce partage est protégé par un mot de passe",
diff --git a/apps/files_sharing/l10n/hu_HU.js b/apps/files_sharing/l10n/hu_HU.js
index c78bdce652d..3895a028be8 100644
--- a/apps/files_sharing/l10n/hu_HU.js
+++ b/apps/files_sharing/l10n/hu_HU.js
@@ -42,6 +42,7 @@ OC.L10N.register(
"You shared %1$s via link" : "Megosztottam link segítségével: %1$s",
"Shares" : "Megosztások",
"Accept" : "Elfogadás",
+ "Decline" : "Elutasítás",
"Share with me through my #ownCloud Federated Cloud ID, see %s" : "Ossza meg velem az #ownCloud Egyesített Felhő Azonosító segítségével, lásd %s",
"Share with me through my #ownCloud Federated Cloud ID" : "Ossza meg velem az #ownCloud Egyesített Felhő Azonosító segítségével ",
"This share is password-protected" : "Ez egy jelszóval védett megosztás",
diff --git a/apps/files_sharing/l10n/hu_HU.json b/apps/files_sharing/l10n/hu_HU.json
index 22cc1422eb7..e9037d232b0 100644
--- a/apps/files_sharing/l10n/hu_HU.json
+++ b/apps/files_sharing/l10n/hu_HU.json
@@ -40,6 +40,7 @@
"You shared %1$s via link" : "Megosztottam link segítségével: %1$s",
"Shares" : "Megosztások",
"Accept" : "Elfogadás",
+ "Decline" : "Elutasítás",
"Share with me through my #ownCloud Federated Cloud ID, see %s" : "Ossza meg velem az #ownCloud Egyesített Felhő Azonosító segítségével, lásd %s",
"Share with me through my #ownCloud Federated Cloud ID" : "Ossza meg velem az #ownCloud Egyesített Felhő Azonosító segítségével ",
"This share is password-protected" : "Ez egy jelszóval védett megosztás",
diff --git a/apps/files_sharing/l10n/id.js b/apps/files_sharing/l10n/id.js
index f0d9fc2aecb..d39d9e763f1 100644
--- a/apps/files_sharing/l10n/id.js
+++ b/apps/files_sharing/l10n/id.js
@@ -41,7 +41,6 @@ OC.L10N.register(
"%2$s shared %1$s with you" : "%2$s membagikan %1$s dengan Anda",
"You shared %1$s via link" : "Anda membagikan %1$s via tautan",
"Shares" : "Dibagikan",
- "You received %s as a remote share from %s" : "Anda menerima %s sebagai berbagi remote dari %s",
"Accept" : "Terima",
"Decline" : "Tolak",
"Share with me through my #ownCloud Federated Cloud ID, see %s" : "Dibagikan pada saya melalui #ownCloud Federated Cloud ID saya, lihat %s",
diff --git a/apps/files_sharing/l10n/id.json b/apps/files_sharing/l10n/id.json
index b14f4c43789..35b22b53346 100644
--- a/apps/files_sharing/l10n/id.json
+++ b/apps/files_sharing/l10n/id.json
@@ -39,7 +39,6 @@
"%2$s shared %1$s with you" : "%2$s membagikan %1$s dengan Anda",
"You shared %1$s via link" : "Anda membagikan %1$s via tautan",
"Shares" : "Dibagikan",
- "You received %s as a remote share from %s" : "Anda menerima %s sebagai berbagi remote dari %s",
"Accept" : "Terima",
"Decline" : "Tolak",
"Share with me through my #ownCloud Federated Cloud ID, see %s" : "Dibagikan pada saya melalui #ownCloud Federated Cloud ID saya, lihat %s",
diff --git a/apps/files_sharing/l10n/it.js b/apps/files_sharing/l10n/it.js
index 9ddf9b5f385..0167ef4625d 100644
--- a/apps/files_sharing/l10n/it.js
+++ b/apps/files_sharing/l10n/it.js
@@ -41,7 +41,7 @@ OC.L10N.register(
"%2$s shared %1$s with you" : "%2$s ha condiviso %1$s con te",
"You shared %1$s via link" : "Hai condiviso %1$s tramite collegamento",
"Shares" : "Condivisioni",
- "You received %s as a remote share from %s" : "Hai ricevuto %s come condivisione remota da %s",
+ "You received %2$s as a remote share from %1$s" : "Hai ricevuto %2$s come condivisione remota da %1$s",
"Accept" : "Accetta",
"Decline" : "Rifiuta",
"Share with me through my #ownCloud Federated Cloud ID, see %s" : "Condividi con me attraverso il mio ID di cloud federata #ownCloud, vedi %s",
diff --git a/apps/files_sharing/l10n/it.json b/apps/files_sharing/l10n/it.json
index 2ff7f2d13b5..ae26579572a 100644
--- a/apps/files_sharing/l10n/it.json
+++ b/apps/files_sharing/l10n/it.json
@@ -39,7 +39,7 @@
"%2$s shared %1$s with you" : "%2$s ha condiviso %1$s con te",
"You shared %1$s via link" : "Hai condiviso %1$s tramite collegamento",
"Shares" : "Condivisioni",
- "You received %s as a remote share from %s" : "Hai ricevuto %s come condivisione remota da %s",
+ "You received %2$s as a remote share from %1$s" : "Hai ricevuto %2$s come condivisione remota da %1$s",
"Accept" : "Accetta",
"Decline" : "Rifiuta",
"Share with me through my #ownCloud Federated Cloud ID, see %s" : "Condividi con me attraverso il mio ID di cloud federata #ownCloud, vedi %s",
diff --git a/apps/files_sharing/l10n/ko.js b/apps/files_sharing/l10n/ko.js
index d750f827797..e4b86b528f3 100644
--- a/apps/files_sharing/l10n/ko.js
+++ b/apps/files_sharing/l10n/ko.js
@@ -41,7 +41,6 @@ OC.L10N.register(
"%2$s shared %1$s with you" : "%2$s 님이 내게 %1$s을(를) 공유함",
"You shared %1$s via link" : "내가 %1$s을(를) 링크로 공유함",
"Shares" : "공유",
- "You received %s as a remote share from %s" : "%1$s의 원격 공유로 %2$s을(를) 받았습니다",
"Accept" : "수락",
"Decline" : "거절",
"Share with me through my #ownCloud Federated Cloud ID, see %s" : "내 #ownCloud 연합 클라우드 ID를 통해서 공유됨, 더 알아보기: %s",
diff --git a/apps/files_sharing/l10n/ko.json b/apps/files_sharing/l10n/ko.json
index e9a169be4f7..383e5038f3c 100644
--- a/apps/files_sharing/l10n/ko.json
+++ b/apps/files_sharing/l10n/ko.json
@@ -39,7 +39,6 @@
"%2$s shared %1$s with you" : "%2$s 님이 내게 %1$s을(를) 공유함",
"You shared %1$s via link" : "내가 %1$s을(를) 링크로 공유함",
"Shares" : "공유",
- "You received %s as a remote share from %s" : "%1$s의 원격 공유로 %2$s을(를) 받았습니다",
"Accept" : "수락",
"Decline" : "거절",
"Share with me through my #ownCloud Federated Cloud ID, see %s" : "내 #ownCloud 연합 클라우드 ID를 통해서 공유됨, 더 알아보기: %s",
diff --git a/apps/files_sharing/l10n/nb_NO.js b/apps/files_sharing/l10n/nb_NO.js
index a83ce84d26d..b8b6c634959 100644
--- a/apps/files_sharing/l10n/nb_NO.js
+++ b/apps/files_sharing/l10n/nb_NO.js
@@ -41,7 +41,6 @@ OC.L10N.register(
"%2$s shared %1$s with you" : "%2$s delte %1$s med deg",
"You shared %1$s via link" : "Du delte %1$s via lenke",
"Shares" : "Delinger",
- "You received %s as a remote share from %s" : "Du mottok %s som en ekstern deling fra %s",
"Accept" : "Aksepter",
"Decline" : "Avslå",
"Share with me through my #ownCloud Federated Cloud ID, see %s" : "Del med meg gjennom min #ownCloud ID for sammenknyttet sky, se %s",
diff --git a/apps/files_sharing/l10n/nb_NO.json b/apps/files_sharing/l10n/nb_NO.json
index 6eedd895f4f..9382119e5c4 100644
--- a/apps/files_sharing/l10n/nb_NO.json
+++ b/apps/files_sharing/l10n/nb_NO.json
@@ -39,7 +39,6 @@
"%2$s shared %1$s with you" : "%2$s delte %1$s med deg",
"You shared %1$s via link" : "Du delte %1$s via lenke",
"Shares" : "Delinger",
- "You received %s as a remote share from %s" : "Du mottok %s som en ekstern deling fra %s",
"Accept" : "Aksepter",
"Decline" : "Avslå",
"Share with me through my #ownCloud Federated Cloud ID, see %s" : "Del med meg gjennom min #ownCloud ID for sammenknyttet sky, se %s",
diff --git a/apps/files_sharing/l10n/nl.js b/apps/files_sharing/l10n/nl.js
index 7468819fda7..2ccddb5d9a7 100644
--- a/apps/files_sharing/l10n/nl.js
+++ b/apps/files_sharing/l10n/nl.js
@@ -41,7 +41,9 @@ OC.L10N.register(
"%2$s shared %1$s with you" : "%2$s deelde %1$s met u",
"You shared %1$s via link" : "U deelde %1$s via link",
"Shares" : "Gedeeld",
+ "You received %2$s as a remote share from %1$s" : "U ontving %2$s als een externe share van %1$s",
"Accept" : "Accepteren",
+ "Decline" : "Afwijzen",
"Share with me through my #ownCloud Federated Cloud ID, see %s" : "Deel met mij via mijn #ownCloud federated Cloud ID, zie %s",
"Share with me through my #ownCloud Federated Cloud ID" : "Deel met mij via mijn #ownCloud federated Cloud ID",
"This share is password-protected" : "Deze share is met een wachtwoord beveiligd",
diff --git a/apps/files_sharing/l10n/nl.json b/apps/files_sharing/l10n/nl.json
index 57df2d5c155..53cd8954898 100644
--- a/apps/files_sharing/l10n/nl.json
+++ b/apps/files_sharing/l10n/nl.json
@@ -39,7 +39,9 @@
"%2$s shared %1$s with you" : "%2$s deelde %1$s met u",
"You shared %1$s via link" : "U deelde %1$s via link",
"Shares" : "Gedeeld",
+ "You received %2$s as a remote share from %1$s" : "U ontving %2$s als een externe share van %1$s",
"Accept" : "Accepteren",
+ "Decline" : "Afwijzen",
"Share with me through my #ownCloud Federated Cloud ID, see %s" : "Deel met mij via mijn #ownCloud federated Cloud ID, zie %s",
"Share with me through my #ownCloud Federated Cloud ID" : "Deel met mij via mijn #ownCloud federated Cloud ID",
"This share is password-protected" : "Deze share is met een wachtwoord beveiligd",
diff --git a/apps/files_sharing/l10n/pt_BR.js b/apps/files_sharing/l10n/pt_BR.js
index 35c9f970000..bb455487186 100644
--- a/apps/files_sharing/l10n/pt_BR.js
+++ b/apps/files_sharing/l10n/pt_BR.js
@@ -41,7 +41,7 @@ OC.L10N.register(
"%2$s shared %1$s with you" : "%2$s compartilhou %1$s com você",
"You shared %1$s via link" : "Você compartilhou %1$s via link",
"Shares" : "Compartilhamentos",
- "You received %s as a remote share from %s" : "Você recebeu %s como um compartilhamento remoto de %s",
+ "You received %2$s as a remote share from %1$s" : "Você recebeu %2$s como um compartilhamento remoto de %1$s",
"Accept" : "Aceitar",
"Decline" : "Rejeitar",
"Share with me through my #ownCloud Federated Cloud ID, see %s" : "Compartilhe comigo através do meu #ownCloud Nuvem Federados ID, veja %s",
diff --git a/apps/files_sharing/l10n/pt_BR.json b/apps/files_sharing/l10n/pt_BR.json
index ebb2a5a4cce..7db2b1f0494 100644
--- a/apps/files_sharing/l10n/pt_BR.json
+++ b/apps/files_sharing/l10n/pt_BR.json
@@ -39,7 +39,7 @@
"%2$s shared %1$s with you" : "%2$s compartilhou %1$s com você",
"You shared %1$s via link" : "Você compartilhou %1$s via link",
"Shares" : "Compartilhamentos",
- "You received %s as a remote share from %s" : "Você recebeu %s como um compartilhamento remoto de %s",
+ "You received %2$s as a remote share from %1$s" : "Você recebeu %2$s como um compartilhamento remoto de %1$s",
"Accept" : "Aceitar",
"Decline" : "Rejeitar",
"Share with me through my #ownCloud Federated Cloud ID, see %s" : "Compartilhe comigo através do meu #ownCloud Nuvem Federados ID, veja %s",
diff --git a/apps/files_sharing/l10n/sk_SK.js b/apps/files_sharing/l10n/sk_SK.js
index 677b4f24e21..4d596987963 100644
--- a/apps/files_sharing/l10n/sk_SK.js
+++ b/apps/files_sharing/l10n/sk_SK.js
@@ -42,6 +42,7 @@ OC.L10N.register(
"You shared %1$s via link" : "Zdieľate %1$s prostredníctvom odkazu",
"Shares" : "Zdieľanie",
"Accept" : "Schváliť",
+ "Decline" : "Odmietnuť",
"Share with me through my #ownCloud Federated Cloud ID, see %s" : "Zdieľajte so mnou pomocou môjho #ownCloud Federated Cloud ID, viac n %s",
"Share with me through my #ownCloud Federated Cloud ID" : "Zdieľajte so mnou pomocou môjho #ownCloud Federated Cloud ID",
"This share is password-protected" : "Toto zdieľanie je chránené heslom",
@@ -64,8 +65,10 @@ OC.L10N.register(
"Open documentation" : "Otvoriť dokumentáciu",
"Allow users on this server to send shares to other servers" : "Povoliť používateľom z tohoto servera posielať zdieľania na iné servery",
"Allow users on this server to receive shares from other servers" : "Povoliť používateľom z tohoto servera prijímať zdieľania z iných serverov",
+ "Federated Cloud" : "Združený Cloud",
"Your Federated Cloud ID:" : "Vaše združené Cloud ID",
"Share it:" : "Zdieľať:",
+ "Add to your website" : "Pridať na svoju webstránku",
"Share with me via ownCloud" : "Zdieľané so mnou cez ownCloud",
"HTML Code:" : "HTML kód:"
},
diff --git a/apps/files_sharing/l10n/sk_SK.json b/apps/files_sharing/l10n/sk_SK.json
index f4f6cc3798b..e8468d1500e 100644
--- a/apps/files_sharing/l10n/sk_SK.json
+++ b/apps/files_sharing/l10n/sk_SK.json
@@ -40,6 +40,7 @@
"You shared %1$s via link" : "Zdieľate %1$s prostredníctvom odkazu",
"Shares" : "Zdieľanie",
"Accept" : "Schváliť",
+ "Decline" : "Odmietnuť",
"Share with me through my #ownCloud Federated Cloud ID, see %s" : "Zdieľajte so mnou pomocou môjho #ownCloud Federated Cloud ID, viac n %s",
"Share with me through my #ownCloud Federated Cloud ID" : "Zdieľajte so mnou pomocou môjho #ownCloud Federated Cloud ID",
"This share is password-protected" : "Toto zdieľanie je chránené heslom",
@@ -62,8 +63,10 @@
"Open documentation" : "Otvoriť dokumentáciu",
"Allow users on this server to send shares to other servers" : "Povoliť používateľom z tohoto servera posielať zdieľania na iné servery",
"Allow users on this server to receive shares from other servers" : "Povoliť používateľom z tohoto servera prijímať zdieľania z iných serverov",
+ "Federated Cloud" : "Združený Cloud",
"Your Federated Cloud ID:" : "Vaše združené Cloud ID",
"Share it:" : "Zdieľať:",
+ "Add to your website" : "Pridať na svoju webstránku",
"Share with me via ownCloud" : "Zdieľané so mnou cez ownCloud",
"HTML Code:" : "HTML kód:"
},"pluralForm" :"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"
diff --git a/apps/files_sharing/l10n/th_TH.js b/apps/files_sharing/l10n/th_TH.js
index 9db7c600102..07aa56dfe18 100644
--- a/apps/files_sharing/l10n/th_TH.js
+++ b/apps/files_sharing/l10n/th_TH.js
@@ -41,7 +41,7 @@ OC.L10N.register(
"%2$s shared %1$s with you" : "%2$s ถูกแชร์ %1$s กับคุณ",
"You shared %1$s via link" : "คุณแชร์ %1$s ผ่านลิงค์",
"Shares" : "แชร์",
- "You received %s as a remote share from %s" : "คุณได้รับ %s โดยรีโมทแชร์จาก %s",
+ "You received %2$s as a remote share from %1$s" : "คุณได้รับรีโมทแชร์ %2$s จาก %1$s",
"Accept" : "ยอมรับ",
"Decline" : "ลดลง",
"Share with me through my #ownCloud Federated Cloud ID, see %s" : "แชร์ร่วมกับฉันผ่าน #ownCloud ด้วยไอดีคลาวด์ในเครือ สามารถดูได้ที่ %s",
diff --git a/apps/files_sharing/l10n/th_TH.json b/apps/files_sharing/l10n/th_TH.json
index f630c062643..3edd0d18ab1 100644
--- a/apps/files_sharing/l10n/th_TH.json
+++ b/apps/files_sharing/l10n/th_TH.json
@@ -39,7 +39,7 @@
"%2$s shared %1$s with you" : "%2$s ถูกแชร์ %1$s กับคุณ",
"You shared %1$s via link" : "คุณแชร์ %1$s ผ่านลิงค์",
"Shares" : "แชร์",
- "You received %s as a remote share from %s" : "คุณได้รับ %s โดยรีโมทแชร์จาก %s",
+ "You received %2$s as a remote share from %1$s" : "คุณได้รับรีโมทแชร์ %2$s จาก %1$s",
"Accept" : "ยอมรับ",
"Decline" : "ลดลง",
"Share with me through my #ownCloud Federated Cloud ID, see %s" : "แชร์ร่วมกับฉันผ่าน #ownCloud ด้วยไอดีคลาวด์ในเครือ สามารถดูได้ที่ %s",
diff --git a/apps/files_sharing/lib/capabilities.php b/apps/files_sharing/lib/capabilities.php
index ea71c47a05c..b24eb8d61f0 100644
--- a/apps/files_sharing/lib/capabilities.php
+++ b/apps/files_sharing/lib/capabilities.php
@@ -67,6 +67,13 @@ class Capabilities implements ICapability {
$res['resharing'] = $this->config->getAppValue('core', 'shareapi_allow_resharing', 'yes') === 'yes';
+
+ //Federated sharing
+ $res['federation'] = [
+ 'outgoing' => $this->config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes') === 'yes',
+ 'incoming' => $this->config->getAppValue('files_sharing', 'incoming_server2server_share_enabled', 'yes') === 'yes'
+ ];
+
return [
'files_sharing' => $res,
];
diff --git a/apps/files_sharing/lib/external/manager.php b/apps/files_sharing/lib/external/manager.php
index 17142e95099..8552b2fbd34 100644
--- a/apps/files_sharing/lib/external/manager.php
+++ b/apps/files_sharing/lib/external/manager.php
@@ -214,7 +214,7 @@ class Manager {
$acceptShare->execute(array(1, $mountPoint, $hash, $id, $this->uid));
$this->sendFeedbackToRemote($share['remote'], $share['share_token'], $share['remote_id'], 'accept');
- $this->scrapNotification($share['remote_id']);
+ //FIXME $this->scrapNotification($share['remote_id']);
return true;
}
@@ -237,7 +237,7 @@ class Manager {
$removeShare->execute(array($id, $this->uid));
$this->sendFeedbackToRemote($share['remote'], $share['share_token'], $share['remote_id'], 'decline');
- $this->scrapNotification($share['remote_id']);
+ //FIXME $this->scrapNotification($share['remote_id']);
return true;
}
diff --git a/apps/files_sharing/lib/notifier.php b/apps/files_sharing/lib/notifier.php
index cc2deb3f439..02765fcfd1c 100644
--- a/apps/files_sharing/lib/notifier.php
+++ b/apps/files_sharing/lib/notifier.php
@@ -55,7 +55,7 @@ class Notifier implements INotifier {
case 'remote_share':
$params = $notification->getSubjectParameters();
$notification->setParsedSubject(
- (string) $l->t('You received %s as a remote share from %s', $params)
+ (string) $l->t('You received %2$s as a remote share from %1$s', $params)
);
// Deal with the actions for a known subject
diff --git a/apps/files_sharing/publicwebdav.php b/apps/files_sharing/publicwebdav.php
index eec158dd4b6..773a15c888e 100644
--- a/apps/files_sharing/publicwebdav.php
+++ b/apps/files_sharing/publicwebdav.php
@@ -39,7 +39,8 @@ $serverFactory = new \OC\Connector\Sabre\ServerFactory(
\OC::$server->getDatabaseConnection(),
\OC::$server->getUserSession(),
\OC::$server->getMountManager(),
- \OC::$server->getTagManager()
+ \OC::$server->getTagManager(),
+ \OC::$server->getEventDispatcher()
);
$requestUri = \OC::$server->getRequest()->getRequestUri();
diff --git a/apps/files_sharing/tests/api/shareestest.php b/apps/files_sharing/tests/api/shareestest.php
index 1e28cb8ed5a..5c5d5b0d309 100644
--- a/apps/files_sharing/tests/api/shareestest.php
+++ b/apps/files_sharing/tests/api/shareestest.php
@@ -21,10 +21,9 @@
namespace OCA\Files_Sharing\Tests\API;
-use Doctrine\DBAL\Connection;
-use OC\Share\Constants;
use OCA\Files_Sharing\API\Sharees;
use OCA\Files_sharing\Tests\TestCase;
+use OCP\AppFramework\Http;
use OCP\Share;
class ShareesTest extends TestCase {
@@ -653,15 +652,6 @@ class ShareesTest extends TestCase {
// Test pagination
[[
- 'page' => 0,
- ], '', true, '', null, $allTypes, 1, 200, false],
- [[
- 'page' => '0',
- ], '', true, '', null, $allTypes, 1, 200, false],
- [[
- 'page' => -1,
- ], '', true, '', null, $allTypes, 1, 200, false],
- [[
'page' => 1,
], '', true, '', null, $allTypes, 1, 200, false],
[[
@@ -670,15 +660,6 @@ class ShareesTest extends TestCase {
// Test perPage
[[
- 'perPage' => 0,
- ], '', true, '', null, $allTypes, 1, 200, false],
- [[
- 'perPage' => '0',
- ], '', true, '', null, $allTypes, 1, 200, false],
- [[
- 'perPage' => -1,
- ], '', true, '', null, $allTypes, 1, 1, false],
- [[
'perPage' => 1,
], '', true, '', null, $allTypes, 1, 1, false],
[[
@@ -758,6 +739,75 @@ class ShareesTest extends TestCase {
$_GET = $oldGet;
}
+ public function dataSearchInvalid() {
+ return [
+ // Test invalid pagination
+ [[
+ 'page' => 0,
+ ], 'Invalid page'],
+ [[
+ 'page' => '0',
+ ], 'Invalid page'],
+ [[
+ 'page' => -1,
+ ], 'Invalid page'],
+
+ // Test invalid perPage
+ [[
+ 'perPage' => 0,
+ ], 'Invalid perPage argument'],
+ [[
+ 'perPage' => '0',
+ ], 'Invalid perPage argument'],
+ [[
+ 'perPage' => -1,
+ ], 'Invalid perPage argument'],
+ ];
+ }
+
+ /**
+ * @dataProvider dataSearchInvalid
+ *
+ * @param array $getData
+ * @param string $message
+ */
+ public function testSearchInvalid($getData, $message) {
+ $oldGet = $_GET;
+ $_GET = $getData;
+
+ $config = $this->getMockBuilder('OCP\IConfig')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $config->expects($this->never())
+ ->method('getAppValue');
+
+ $sharees = $this->getMockBuilder('\OCA\Files_Sharing\API\Sharees')
+ ->setConstructorArgs([
+ $this->groupManager,
+ $this->userManager,
+ $this->contactsManager,
+ $config,
+ $this->session,
+ $this->getMockBuilder('OCP\IURLGenerator')->disableOriginalConstructor()->getMock(),
+ $this->getMockBuilder('OCP\IRequest')->disableOriginalConstructor()->getMock(),
+ $this->getMockBuilder('OCP\ILogger')->disableOriginalConstructor()->getMock()
+ ])
+ ->setMethods(array('searchSharees', 'isRemoteSharingAllowed'))
+ ->getMock();
+ $sharees->expects($this->never())
+ ->method('searchSharees');
+ $sharees->expects($this->never())
+ ->method('isRemoteSharingAllowed');
+
+ /** @var \PHPUnit_Framework_MockObject_MockObject|\OCA\Files_Sharing\API\Sharees $sharees */
+ $ocs = $sharees->search();
+ $this->assertInstanceOf('\OC_OCS_Result', $ocs);
+
+ $this->assertOCSError($ocs, $message);
+
+ $_GET = $oldGet;
+ }
+
public function dataIsRemoteSharingAllowed() {
return [
['file', true],
@@ -940,13 +990,7 @@ class ShareesTest extends TestCase {
$ocs = $this->invokePrivate($this->sharees, 'searchSharees', ['', null, [], [], 0, 0, false]);
$this->assertInstanceOf('\OC_OCS_Result', $ocs);
- $this->assertSame(400, $ocs->getStatusCode(), 'Expected status code 400');
- $this->assertSame([], $ocs->getData(), 'Expected that no data is send');
-
- $meta = $ocs->getMeta();
- $this->assertNotEmpty($meta);
- $this->assertArrayHasKey('message', $meta);
- $this->assertSame('missing itemType', $meta['message']);
+ $this->assertOCSError($ocs, 'Missing itemType');
}
public function dataGetPaginationLink() {
@@ -992,4 +1036,18 @@ class ShareesTest extends TestCase {
$this->assertEquals($expected, $this->invokePrivate($this->sharees, 'isV2'));
}
+
+ /**
+ * @param \OC_OCS_Result $ocs
+ * @param string $message
+ */
+ protected function assertOCSError(\OC_OCS_Result $ocs, $message) {
+ $this->assertSame(Http::STATUS_BAD_REQUEST, $ocs->getStatusCode(), 'Expected status code 400');
+ $this->assertSame([], $ocs->getData(), 'Expected that no data is send');
+
+ $meta = $ocs->getMeta();
+ $this->assertNotEmpty($meta);
+ $this->assertArrayHasKey('message', $meta);
+ $this->assertSame($message, $meta['message']);
+ }
}
diff --git a/apps/files_sharing/tests/capabilities.php b/apps/files_sharing/tests/capabilities.php
index 5b9789ce324..f1a9626db9b 100644
--- a/apps/files_sharing/tests/capabilities.php
+++ b/apps/files_sharing/tests/capabilities.php
@@ -202,5 +202,40 @@ class FilesSharingCapabilitiesTest extends \Test\TestCase {
$this->assertFalse($result['public']['upload']);
}
+ public function testFederatedSharingIncomming() {
+ $map = [
+ ['files_sharing', 'incoming_server2server_share_enabled', 'yes', 'yes'],
+ ];
+ $result = $this->getResults($map);
+ $this->assertArrayHasKey('federation', $result);
+ $this->assertTrue($result['federation']['incoming']);
+ }
+
+ public function testFederatedSharingNoIncomming() {
+ $map = [
+ ['files_sharing', 'incoming_server2server_share_enabled', 'yes', 'no'],
+ ];
+ $result = $this->getResults($map);
+ $this->assertArrayHasKey('federation', $result);
+ $this->assertFalse($result['federation']['incoming']);
+ }
+
+ public function testFederatedSharingOutgoing() {
+ $map = [
+ ['files_sharing', 'outgoing_server2server_share_enabled', 'yes', 'yes'],
+ ];
+ $result = $this->getResults($map);
+ $this->assertArrayHasKey('federation', $result);
+ $this->assertTrue($result['federation']['outgoing']);
+ }
+
+ public function testFederatedSharingNoOutgoing() {
+ $map = [
+ ['files_sharing', 'outgoing_server2server_share_enabled', 'yes', 'no'],
+ ];
+ $result = $this->getResults($map);
+ $this->assertArrayHasKey('federation', $result);
+ $this->assertFalse($result['federation']['outgoing']);
+ }
}
diff --git a/apps/files_sharing/tests/js/shareSpec.js b/apps/files_sharing/tests/js/shareSpec.js
index b6368b901ee..96a96f1b814 100644
--- a/apps/files_sharing/tests/js/shareSpec.js
+++ b/apps/files_sharing/tests/js/shareSpec.js
@@ -97,7 +97,6 @@ describe('OCA.Sharing.Util tests', function() {
}]);
$tr = fileList.$el.find('tbody tr:first');
$action = $tr.find('.action-share');
- expect($action.hasClass('permanent')).toEqual(true);
expect(OC.basename($action.find('img').attr('src'))).toEqual('share.svg');
expect(OC.basename(getImageUrl($tr.find('.filename .thumbnail')))).toEqual('folder.svg');
expect($action.find('img').length).toEqual(1);
@@ -116,7 +115,6 @@ describe('OCA.Sharing.Util tests', function() {
}]);
$tr = fileList.$el.find('tbody tr:first');
$action = $tr.find('.action-share');
- expect($action.hasClass('permanent')).toEqual(true);
expect($action.find('>span').text().trim()).toEqual('Shared');
expect(OC.basename($action.find('img').attr('src'))).toEqual('share.svg');
expect(OC.basename(getImageUrl($tr.find('.filename .thumbnail')))).toEqual('folder-shared.svg');
@@ -137,7 +135,6 @@ describe('OCA.Sharing.Util tests', function() {
}]);
$tr = fileList.$el.find('tbody tr:first');
$action = $tr.find('.action-share');
- expect($action.hasClass('permanent')).toEqual(true);
expect($action.find('>span').text().trim()).toEqual('Shared');
expect(OC.basename($action.find('img').attr('src'))).toEqual('public.svg');
expect(OC.basename(getImageUrl($tr.find('.filename .thumbnail')))).toEqual('folder-public.svg');
@@ -158,7 +155,6 @@ describe('OCA.Sharing.Util tests', function() {
}]);
$tr = fileList.$el.find('tbody tr:first');
$action = $tr.find('.action-share');
- expect($action.hasClass('permanent')).toEqual(true);
expect($action.find('>span').text().trim()).toEqual('User One');
expect(OC.basename($action.find('img').attr('src'))).toEqual('share.svg');
expect(OC.basename(getImageUrl($tr.find('.filename .thumbnail')))).toEqual('folder-shared.svg');
@@ -178,7 +174,6 @@ describe('OCA.Sharing.Util tests', function() {
}]);
$tr = fileList.$el.find('tbody tr:first');
$action = $tr.find('.action-share');
- expect($action.hasClass('permanent')).toEqual(true);
expect($action.find('>span').text().trim()).toEqual('Shared with User One, User Two');
expect(OC.basename($action.find('img').attr('src'))).toEqual('share.svg');
expect(OC.basename(getImageUrl($tr.find('.filename .thumbnail')))).toEqual('folder-shared.svg');
@@ -200,7 +195,6 @@ describe('OCA.Sharing.Util tests', function() {
$tr = fileList.$el.find('tbody tr:first');
expect($tr.find('.action-share').length).toEqual(0);
$action = $tr.find('.action-share-notification');
- expect($action.hasClass('permanent')).toEqual(true);
expect($action.find('>span').text().trim()).toEqual('User One');
expect(OC.basename($action.find('img').attr('src'))).toEqual('share.svg');
expect(OC.basename(getImageUrl($tr.find('.filename .thumbnail')))).toEqual('folder-shared.svg');
@@ -225,7 +219,7 @@ describe('OCA.Sharing.Util tests', function() {
});
});
describe('Share action', function() {
- var showDropDownStub;
+ var shareTab;
function makeDummyShareItem(displayName) {
return {
@@ -234,12 +228,35 @@ describe('OCA.Sharing.Util tests', function() {
}
beforeEach(function() {
- showDropDownStub = sinon.stub(OC.Share, 'showDropDown', function() {
- $('#testArea').append($('<div id="dropdown"></div>'));
- });
+ // make it look like not the "All files" list
+ fileList.id = 'test';
+ shareTab = fileList._detailsView._tabViews[0];
});
afterEach(function() {
- showDropDownStub.restore();
+ shareTab = null;
+ });
+ it('clicking share action opens sidebar and share tab', function() {
+ var showDetailsViewStub = sinon.stub(fileList, 'showDetailsView');
+
+ fileList.setFiles([{
+ id: 1,
+ type: 'file',
+ name: 'One.txt',
+ path: '/subdir',
+ mimetype: 'text/plain',
+ size: 12,
+ permissions: OC.PERMISSION_ALL,
+ etag: 'abc'
+ }]);
+
+ var $tr = fileList.$el.find('tr:first');
+ $tr.find('.action-share').click();
+
+ expect(showDetailsViewStub.calledOnce).toEqual(true);
+ expect(showDetailsViewStub.getCall(0).args[0]).toEqual('One.txt');
+ expect(showDetailsViewStub.getCall(0).args[1]).toEqual('shareTabView');
+
+ showDetailsViewStub.restore();
});
it('adds share icon after sharing a non-shared file', function() {
var $action, $tr;
@@ -257,24 +274,20 @@ describe('OCA.Sharing.Util tests', function() {
$action = fileList.$el.find('tbody tr:first .action-share');
$tr = fileList.$el.find('tr:first');
- expect($action.hasClass('permanent')).toEqual(true);
-
$tr.find('.action-share').click();
- expect(showDropDownStub.calledOnce).toEqual(true);
-
- // simulate what the dropdown does
- var shares = {};
- OC.Share.itemShares[OC.Share.SHARE_TYPE_USER] = ['user1', 'user2'];
- OC.Share.itemShares[OC.Share.SHARE_TYPE_GROUP] = ['group1', 'group2'];
- shares[OC.Share.SHARE_TYPE_USER] = _.map(['User One', 'User Two'], makeDummyShareItem);
- shares[OC.Share.SHARE_TYPE_GROUP] = _.map(['Group One', 'Group Two'], makeDummyShareItem);
- $('#dropdown').trigger(new $.Event('sharesChanged', {shares: shares}));
+ // simulate updating shares
+ shareTab._dialog.model.set({
+ shares: [
+ {share_with_displayname: 'User One'},
+ {share_with_displayname: 'User Two'},
+ {share_with_displayname: 'Group One'},
+ {share_with_displayname: 'Group Two'}
+ ]
+ });
expect($tr.attr('data-share-recipients')).toEqual('Group One, Group Two, User One, User Two');
- OC.Share.updateIcon('file', 1);
- expect($action.hasClass('permanent')).toEqual(true);
expect($action.find('>span').text().trim()).toEqual('Shared with Group One, Group Two, User One, User Two');
expect(OC.basename($action.find('img').attr('src'))).toEqual('share.svg');
});
@@ -294,23 +307,19 @@ describe('OCA.Sharing.Util tests', function() {
$action = fileList.$el.find('tbody tr:first .action-share');
$tr = fileList.$el.find('tr:first');
- expect($action.hasClass('permanent')).toEqual(true);
-
$tr.find('.action-share').click();
- expect(showDropDownStub.calledOnce).toEqual(true);
-
- // simulate what the dropdown does
- var shares = {};
- OC.Share.itemShares[OC.Share.SHARE_TYPE_USER] = ['user1', 'user2', 'user3'];
- shares[OC.Share.SHARE_TYPE_USER] = _.map(['User One', 'User Two', 'User Three'], makeDummyShareItem);
- $('#dropdown').trigger(new $.Event('sharesChanged', {shares: shares}));
+ // simulate updating shares
+ shareTab._dialog.model.set({
+ shares: [
+ {share_with_displayname: 'User One'},
+ {share_with_displayname: 'User Two'},
+ {share_with_displayname: 'User Three'}
+ ]
+ });
expect($tr.attr('data-share-recipients')).toEqual('User One, User Three, User Two');
- OC.Share.updateIcon('file', 1);
-
- expect($action.hasClass('permanent')).toEqual(true);
expect($action.find('>span').text().trim()).toEqual('Shared with User One, User Three, User Two');
expect(OC.basename($action.find('img').attr('src'))).toEqual('share.svg');
});
@@ -331,20 +340,14 @@ describe('OCA.Sharing.Util tests', function() {
$action = fileList.$el.find('tbody tr:first .action-share');
$tr = fileList.$el.find('tr:first');
- expect($action.hasClass('permanent')).toEqual(true);
-
$tr.find('.action-share').click();
- expect(showDropDownStub.calledOnce).toEqual(true);
-
- // simulate what the dropdown does
- OC.Share.itemShares = {};
- $('#dropdown').trigger(new $.Event('sharesChanged', {shares: {}}));
+ // simulate updating shares
+ shareTab._dialog.model.set({
+ shares: []
+ });
expect($tr.attr('data-share-recipients')).not.toBeDefined();
-
- OC.Share.updateIcon('file', 1);
- expect($action.hasClass('permanent')).toEqual(true);
});
it('keep share text after updating reshare', function() {
var $action, $tr;
@@ -363,23 +366,15 @@ describe('OCA.Sharing.Util tests', function() {
$action = fileList.$el.find('tbody tr:first .action-share');
$tr = fileList.$el.find('tr:first');
- expect($action.hasClass('permanent')).toEqual(true);
-
$tr.find('.action-share').click();
- expect(showDropDownStub.calledOnce).toEqual(true);
-
- // simulate what the dropdown does
- var shares = {};
- OC.Share.itemShares[OC.Share.SHARE_TYPE_USER] = ['user2'];
- shares[OC.Share.SHARE_TYPE_USER] = _.map(['User Two'], makeDummyShareItem);
- $('#dropdown').trigger(new $.Event('sharesChanged', {shares: shares}));
+ // simulate updating shares
+ shareTab._dialog.model.set({
+ shares: [{share_with_displayname: 'User Two'}]
+ });
expect($tr.attr('data-share-recipients')).toEqual('User Two');
- OC.Share.updateIcon('file', 1);
-
- expect($action.hasClass('permanent')).toEqual(true);
expect($action.find('>span').text().trim()).toEqual('User One');
expect(OC.basename($action.find('img').attr('src'))).toEqual('share.svg');
});
@@ -401,21 +396,15 @@ describe('OCA.Sharing.Util tests', function() {
$action = fileList.$el.find('tbody tr:first .action-share');
$tr = fileList.$el.find('tr:first');
- expect($action.hasClass('permanent')).toEqual(true);
-
$tr.find('.action-share').click();
- expect(showDropDownStub.calledOnce).toEqual(true);
-
- // simulate what the dropdown does
- OC.Share.itemShares = {};
- $('#dropdown').trigger(new $.Event('sharesChanged', {shares: {}}));
+ // simulate updating shares
+ shareTab._dialog.model.set({
+ shares: []
+ });
expect($tr.attr('data-share-recipients')).not.toBeDefined();
- OC.Share.updateIcon('file', 1);
-
- expect($action.hasClass('permanent')).toEqual(true);
expect($action.find('>span').text().trim()).toEqual('User One');
expect(OC.basename($action.find('img').attr('src'))).toEqual('share.svg');
});
diff --git a/apps/files_versions/appinfo/app.php b/apps/files_versions/appinfo/app.php
index 967f2e73a34..eadc7c69a23 100644
--- a/apps/files_versions/appinfo/app.php
+++ b/apps/files_versions/appinfo/app.php
@@ -19,6 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
-OCP\Util::addStyle('files_versions', 'versions');
+
+\OCP\Util::addStyle('files_versions', 'versions');
\OCA\Files_Versions\Hooks::connectHooks();
diff --git a/apps/files_versions/appinfo/application.php b/apps/files_versions/appinfo/application.php
index bab36b48510..b61b03dab13 100644
--- a/apps/files_versions/appinfo/application.php
+++ b/apps/files_versions/appinfo/application.php
@@ -22,6 +22,7 @@
namespace OCA\Files_Versions\AppInfo;
use OCP\AppFramework\App;
+use OCA\Files_Versions\Expiration;
class Application extends App {
public function __construct(array $urlParams = array()) {
@@ -33,5 +34,15 @@ class Application extends App {
* Register capabilities
*/
$container->registerCapability('OCA\Files_Versions\Capabilities');
+
+ /*
+ * Register expiration
+ */
+ $container->registerService('Expiration', function($c) {
+ return new Expiration(
+ $c->query('ServerContainer')->getConfig(),
+ $c->query('OCP\AppFramework\Utility\ITimeFactory')
+ );
+ });
}
}
diff --git a/apps/files_versions/appinfo/install.php b/apps/files_versions/appinfo/install.php
new file mode 100644
index 00000000000..d72ba2f56e5
--- /dev/null
+++ b/apps/files_versions/appinfo/install.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * @author Victor Dubiniuk <dubiniuk@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+// Cron job for deleting expired trash items
+\OC::$server->getJobList()->add('OCA\Files_Versions\BackgroundJob\ExpireVersions');
diff --git a/apps/files_versions/appinfo/update.php b/apps/files_versions/appinfo/update.php
index 524f9bd153f..687e5d3b5d4 100644
--- a/apps/files_versions/appinfo/update.php
+++ b/apps/files_versions/appinfo/update.php
@@ -24,3 +24,6 @@ $installedVersion=OCP\Config::getAppValue('files_versions', 'installed_version')
if (version_compare($installedVersion, '1.0.4', '<')) {
\OC_DB::dropTable("files_versions");
}
+
+// Cron job for deleting expired trash items
+\OC::$server->getJobList()->add('OCA\Files_Versions\BackgroundJob\ExpireVersions');
diff --git a/apps/files_versions/css/versions.css b/apps/files_versions/css/versions.css
index ec0f0cc9896..b159de82ea3 100644
--- a/apps/files_versions/css/versions.css
+++ b/apps/files_versions/css/versions.css
@@ -13,9 +13,7 @@
}
.versionsTabView li > * {
- padding: 7px;
- float: left;
- vertical-align: top;
+ vertical-align: middle;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
filter: alpha(opacity=50);
opacity: .5;
@@ -23,7 +21,7 @@
.versionsTabView li > a,
.versionsTabView li > span {
- padding: 17px 7px;
+ padding: 15px 10px 11px;
}
.versionsTabView li > *:hover,
@@ -43,16 +41,13 @@
opacity: 1;
}
-.versionsTabView .versionDate {
+.versionsTabView .versiondate {
min-width: 100px;
- vertical-align: text-bottom;
+ vertical-align: super;
}
.versionsTabView .revertVersion {
cursor: pointer;
float: right;
- max-width: 130px;
- text-overflow: ellipsis;
- overflow: hidden;
+ margin-right: -10px;
}
-
diff --git a/apps/files_versions/js/versionstabview.js b/apps/files_versions/js/versionstabview.js
index 1f84428e616..f6a6f037988 100644
--- a/apps/files_versions/js/versionstabview.js
+++ b/apps/files_versions/js/versionstabview.js
@@ -15,7 +15,7 @@
'<a href="{{downloadUrl}}" class="downloadVersion"><img src="{{downloadIconUrl}}" />' +
'<span class="versiondate has-tooltip" title="{{formattedTimestamp}}">{{relativeTimestamp}}</span>' +
'</a>' +
- '<a href="#" class="revertVersion"><img src="{{revertIconUrl}}" />{{revertLabel}}</a>' +
+ '<a href="#" class="revertVersion" title="{{revertLabel}}"><img src="{{revertIconUrl}}" /></a>' +
'</li>';
var TEMPLATE =
@@ -195,4 +195,3 @@
OCA.Versions.VersionsTabView = VersionsTabView;
})();
-
diff --git a/apps/files_versions/l10n/ar.js b/apps/files_versions/l10n/ar.js
index 81390bc50a9..40afe40221c 100644
--- a/apps/files_versions/l10n/ar.js
+++ b/apps/files_versions/l10n/ar.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "غير قادر على الاستعادة : %s",
"Versions" : "الإصدارات",
"Failed to revert {file} to revision {timestamp}." : "فشل في استعادة {ملف} لنتقيح {الطابع الزمني}",
- "More versions..." : "المزيد من الإصدارات",
+ "Restore" : "استعادة ",
"No other versions available" : "لا توجد إصدارات أخرى متاحة",
- "Restore" : "استعادة "
+ "More versions..." : "المزيد من الإصدارات"
},
"nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;");
diff --git a/apps/files_versions/l10n/ar.json b/apps/files_versions/l10n/ar.json
index 683df8a7c0e..03c743f039b 100644
--- a/apps/files_versions/l10n/ar.json
+++ b/apps/files_versions/l10n/ar.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "غير قادر على الاستعادة : %s",
"Versions" : "الإصدارات",
"Failed to revert {file} to revision {timestamp}." : "فشل في استعادة {ملف} لنتقيح {الطابع الزمني}",
- "More versions..." : "المزيد من الإصدارات",
+ "Restore" : "استعادة ",
"No other versions available" : "لا توجد إصدارات أخرى متاحة",
- "Restore" : "استعادة "
+ "More versions..." : "المزيد من الإصدارات"
},"pluralForm" :"nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/ast.js b/apps/files_versions/l10n/ast.js
index 39f7ea7d58f..39c5fd98d42 100644
--- a/apps/files_versions/l10n/ast.js
+++ b/apps/files_versions/l10n/ast.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Nun pudo revertise: %s",
"Versions" : "Versiones",
"Failed to revert {file} to revision {timestamp}." : "Fallu al revertir {file} a la revisión {timestamp}.",
- "More versions..." : "Más versiones...",
+ "Restore" : "Restaurar",
"No other versions available" : "Nun hai otres versiones disponibles",
- "Restore" : "Restaurar"
+ "More versions..." : "Más versiones..."
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/files_versions/l10n/ast.json b/apps/files_versions/l10n/ast.json
index 720f02e6f63..6a545ffb94b 100644
--- a/apps/files_versions/l10n/ast.json
+++ b/apps/files_versions/l10n/ast.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Nun pudo revertise: %s",
"Versions" : "Versiones",
"Failed to revert {file} to revision {timestamp}." : "Fallu al revertir {file} a la revisión {timestamp}.",
- "More versions..." : "Más versiones...",
+ "Restore" : "Restaurar",
"No other versions available" : "Nun hai otres versiones disponibles",
- "Restore" : "Restaurar"
+ "More versions..." : "Más versiones..."
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/az.js b/apps/files_versions/l10n/az.js
index ee6e86ef111..171cb31ab1a 100644
--- a/apps/files_versions/l10n/az.js
+++ b/apps/files_versions/l10n/az.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Geri qaytarmaq olmur: %s",
"Versions" : "Versiyaları",
"Failed to revert {file} to revision {timestamp}." : "{timestamp} yenidən baxılması üçün {file} geri qaytarmaq mümkün olmadı.",
- "More versions..." : "Əlavə versiyalar",
+ "Restore" : "Geri qaytar",
"No other versions available" : "Başqa versiyalar mövcud deyil",
- "Restore" : "Geri qaytar"
+ "More versions..." : "Əlavə versiyalar"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/files_versions/l10n/az.json b/apps/files_versions/l10n/az.json
index 9b38c19fdba..3f4e0275dd5 100644
--- a/apps/files_versions/l10n/az.json
+++ b/apps/files_versions/l10n/az.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Geri qaytarmaq olmur: %s",
"Versions" : "Versiyaları",
"Failed to revert {file} to revision {timestamp}." : "{timestamp} yenidən baxılması üçün {file} geri qaytarmaq mümkün olmadı.",
- "More versions..." : "Əlavə versiyalar",
+ "Restore" : "Geri qaytar",
"No other versions available" : "Başqa versiyalar mövcud deyil",
- "Restore" : "Geri qaytar"
+ "More versions..." : "Əlavə versiyalar"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/bg_BG.js b/apps/files_versions/l10n/bg_BG.js
index 6ea5387eec2..cea297b6974 100644
--- a/apps/files_versions/l10n/bg_BG.js
+++ b/apps/files_versions/l10n/bg_BG.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Грешка при връщане: %s",
"Versions" : "Версии",
"Failed to revert {file} to revision {timestamp}." : "Грешка при връщане на {file} към версия {timestamp}.",
- "More versions..." : "Още версии...",
+ "Restore" : "Възтановяви",
"No other versions available" : "Няма други налични версии",
- "Restore" : "Възтановяви"
+ "More versions..." : "Още версии..."
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/files_versions/l10n/bg_BG.json b/apps/files_versions/l10n/bg_BG.json
index 3d8060a22f1..826c7136d1a 100644
--- a/apps/files_versions/l10n/bg_BG.json
+++ b/apps/files_versions/l10n/bg_BG.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Грешка при връщане: %s",
"Versions" : "Версии",
"Failed to revert {file} to revision {timestamp}." : "Грешка при връщане на {file} към версия {timestamp}.",
- "More versions..." : "Още версии...",
+ "Restore" : "Възтановяви",
"No other versions available" : "Няма други налични версии",
- "Restore" : "Възтановяви"
+ "More versions..." : "Още версии..."
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/bn_BD.js b/apps/files_versions/l10n/bn_BD.js
index 4e3f8be76bb..e92e84268c1 100644
--- a/apps/files_versions/l10n/bn_BD.js
+++ b/apps/files_versions/l10n/bn_BD.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "ফিরে যাওয়া গেলনা: %s",
"Versions" : "সংষ্করন",
"Failed to revert {file} to revision {timestamp}." : " {file} সংশোধিত {timestamp} এ ফিরে যেতে ব্যার্থ হলো।",
- "More versions..." : "আরো সংষ্করণ....",
+ "Restore" : "ফিরিয়ে দাও",
"No other versions available" : "আর কোন সংষ্করণ প্রাপ্তব্য নয়",
- "Restore" : "ফিরিয়ে দাও"
+ "More versions..." : "আরো সংষ্করণ...."
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/files_versions/l10n/bn_BD.json b/apps/files_versions/l10n/bn_BD.json
index 4ab5756e011..ec8aa74e18b 100644
--- a/apps/files_versions/l10n/bn_BD.json
+++ b/apps/files_versions/l10n/bn_BD.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "ফিরে যাওয়া গেলনা: %s",
"Versions" : "সংষ্করন",
"Failed to revert {file} to revision {timestamp}." : " {file} সংশোধিত {timestamp} এ ফিরে যেতে ব্যার্থ হলো।",
- "More versions..." : "আরো সংষ্করণ....",
+ "Restore" : "ফিরিয়ে দাও",
"No other versions available" : "আর কোন সংষ্করণ প্রাপ্তব্য নয়",
- "Restore" : "ফিরিয়ে দাও"
+ "More versions..." : "আরো সংষ্করণ...."
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/bn_IN.js b/apps/files_versions/l10n/bn_IN.js
index f2985aa4afb..34fce5d5662 100644
--- a/apps/files_versions/l10n/bn_IN.js
+++ b/apps/files_versions/l10n/bn_IN.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "প্রত্যাবর্তন করা যায়নি: %s",
"Versions" : "সংস্করণ",
"Failed to revert {file} to revision {timestamp}." : "{ফাইল} প্রত্যাবর্তন থেকে পুনর্বিবেচনা {টাইমস্ট্যাম্প} করতে ব্যর্থ।",
- "More versions..." : "আরো সংস্করণ...",
+ "Restore" : "পুনরুদ্ধার",
"No other versions available" : "আর কোন সংস্করণ পাওয়া যাচ্ছে না",
- "Restore" : "পুনরুদ্ধার"
+ "More versions..." : "আরো সংস্করণ..."
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/files_versions/l10n/bn_IN.json b/apps/files_versions/l10n/bn_IN.json
index e973e1f074e..34deb365a1e 100644
--- a/apps/files_versions/l10n/bn_IN.json
+++ b/apps/files_versions/l10n/bn_IN.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "প্রত্যাবর্তন করা যায়নি: %s",
"Versions" : "সংস্করণ",
"Failed to revert {file} to revision {timestamp}." : "{ফাইল} প্রত্যাবর্তন থেকে পুনর্বিবেচনা {টাইমস্ট্যাম্প} করতে ব্যর্থ।",
- "More versions..." : "আরো সংস্করণ...",
+ "Restore" : "পুনরুদ্ধার",
"No other versions available" : "আর কোন সংস্করণ পাওয়া যাচ্ছে না",
- "Restore" : "পুনরুদ্ধার"
+ "More versions..." : "আরো সংস্করণ..."
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/bs.js b/apps/files_versions/l10n/bs.js
index 21e9851b64c..fc207e1517c 100644
--- a/apps/files_versions/l10n/bs.js
+++ b/apps/files_versions/l10n/bs.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Nije moguće vratiti: %s",
"Versions" : "Verzije",
"Failed to revert {file} to revision {timestamp}." : "Nije uspelo vraćanje {file} na reviziju {timestamp}.",
- "More versions..." : "Više verzija...",
+ "Restore" : "Obnovi",
"No other versions available" : "Druge verzije su nedostupne",
- "Restore" : "Obnovi"
+ "More versions..." : "Više verzija..."
},
"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);");
diff --git a/apps/files_versions/l10n/bs.json b/apps/files_versions/l10n/bs.json
index 1bc885614ed..50d72404f2f 100644
--- a/apps/files_versions/l10n/bs.json
+++ b/apps/files_versions/l10n/bs.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Nije moguće vratiti: %s",
"Versions" : "Verzije",
"Failed to revert {file} to revision {timestamp}." : "Nije uspelo vraćanje {file} na reviziju {timestamp}.",
- "More versions..." : "Više verzija...",
+ "Restore" : "Obnovi",
"No other versions available" : "Druge verzije su nedostupne",
- "Restore" : "Obnovi"
+ "More versions..." : "Više verzija..."
},"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/ca.js b/apps/files_versions/l10n/ca.js
index da6bd06b98e..660db0d6f29 100644
--- a/apps/files_versions/l10n/ca.js
+++ b/apps/files_versions/l10n/ca.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "No s'ha pogut revertir: %s",
"Versions" : "Versions",
"Failed to revert {file} to revision {timestamp}." : "Ha fallat en retornar {file} a la revisió {timestamp}",
- "More versions..." : "Més versions...",
+ "Restore" : "Recupera",
"No other versions available" : "No hi ha altres versions disponibles",
- "Restore" : "Recupera"
+ "More versions..." : "Més versions..."
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/files_versions/l10n/ca.json b/apps/files_versions/l10n/ca.json
index 3638e7b6462..7cd2ddbcf51 100644
--- a/apps/files_versions/l10n/ca.json
+++ b/apps/files_versions/l10n/ca.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "No s'ha pogut revertir: %s",
"Versions" : "Versions",
"Failed to revert {file} to revision {timestamp}." : "Ha fallat en retornar {file} a la revisió {timestamp}",
- "More versions..." : "Més versions...",
+ "Restore" : "Recupera",
"No other versions available" : "No hi ha altres versions disponibles",
- "Restore" : "Recupera"
+ "More versions..." : "Més versions..."
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/cs_CZ.js b/apps/files_versions/l10n/cs_CZ.js
index 0ba87af547f..bd7488fc543 100644
--- a/apps/files_versions/l10n/cs_CZ.js
+++ b/apps/files_versions/l10n/cs_CZ.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Nelze vrátit: %s",
"Versions" : "Verze",
"Failed to revert {file} to revision {timestamp}." : "Selhalo vrácení souboru {file} na verzi {timestamp}.",
- "More versions..." : "Více verzí...",
+ "Restore" : "Obnovit",
"No other versions available" : "Žádné další verze nejsou dostupné",
- "Restore" : "Obnovit"
+ "More versions..." : "Více verzí..."
},
"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;");
diff --git a/apps/files_versions/l10n/cs_CZ.json b/apps/files_versions/l10n/cs_CZ.json
index dc47f0b4cc8..6af93e2bd5e 100644
--- a/apps/files_versions/l10n/cs_CZ.json
+++ b/apps/files_versions/l10n/cs_CZ.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Nelze vrátit: %s",
"Versions" : "Verze",
"Failed to revert {file} to revision {timestamp}." : "Selhalo vrácení souboru {file} na verzi {timestamp}.",
- "More versions..." : "Více verzí...",
+ "Restore" : "Obnovit",
"No other versions available" : "Žádné další verze nejsou dostupné",
- "Restore" : "Obnovit"
+ "More versions..." : "Více verzí..."
},"pluralForm" :"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/da.js b/apps/files_versions/l10n/da.js
index 22f7f66b45d..9d6748f5bdc 100644
--- a/apps/files_versions/l10n/da.js
+++ b/apps/files_versions/l10n/da.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Kunne ikke genskabe: %s",
"Versions" : "Versioner",
"Failed to revert {file} to revision {timestamp}." : "Kunne ikke tilbagerulle {file} til den tidligere udgave: {timestamp}.",
- "More versions..." : "Flere versioner...",
+ "Restore" : "Gendan",
"No other versions available" : "Ingen andre versioner tilgængelig",
- "Restore" : "Gendan"
+ "More versions..." : "Flere versioner..."
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/files_versions/l10n/da.json b/apps/files_versions/l10n/da.json
index 4dfa5dbeafa..5630e3aba82 100644
--- a/apps/files_versions/l10n/da.json
+++ b/apps/files_versions/l10n/da.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Kunne ikke genskabe: %s",
"Versions" : "Versioner",
"Failed to revert {file} to revision {timestamp}." : "Kunne ikke tilbagerulle {file} til den tidligere udgave: {timestamp}.",
- "More versions..." : "Flere versioner...",
+ "Restore" : "Gendan",
"No other versions available" : "Ingen andre versioner tilgængelig",
- "Restore" : "Gendan"
+ "More versions..." : "Flere versioner..."
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/de.js b/apps/files_versions/l10n/de.js
index 012167a7329..285e42517b3 100644
--- a/apps/files_versions/l10n/de.js
+++ b/apps/files_versions/l10n/de.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Konnte %s nicht zurücksetzen",
"Versions" : "Versionen",
"Failed to revert {file} to revision {timestamp}." : "Konnte {file} der Revision {timestamp} nicht rückgängig machen.",
- "More versions..." : "Weitere Versionen…",
+ "Restore" : "Wiederherstellen",
"No other versions available" : "Keine anderen Versionen verfügbar",
- "Restore" : "Wiederherstellen"
+ "More versions..." : "Weitere Versionen…"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/files_versions/l10n/de.json b/apps/files_versions/l10n/de.json
index 74d7f066df8..a1f3c12649f 100644
--- a/apps/files_versions/l10n/de.json
+++ b/apps/files_versions/l10n/de.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Konnte %s nicht zurücksetzen",
"Versions" : "Versionen",
"Failed to revert {file} to revision {timestamp}." : "Konnte {file} der Revision {timestamp} nicht rückgängig machen.",
- "More versions..." : "Weitere Versionen…",
+ "Restore" : "Wiederherstellen",
"No other versions available" : "Keine anderen Versionen verfügbar",
- "Restore" : "Wiederherstellen"
+ "More versions..." : "Weitere Versionen…"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/de_DE.js b/apps/files_versions/l10n/de_DE.js
index 012167a7329..285e42517b3 100644
--- a/apps/files_versions/l10n/de_DE.js
+++ b/apps/files_versions/l10n/de_DE.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Konnte %s nicht zurücksetzen",
"Versions" : "Versionen",
"Failed to revert {file} to revision {timestamp}." : "Konnte {file} der Revision {timestamp} nicht rückgängig machen.",
- "More versions..." : "Weitere Versionen…",
+ "Restore" : "Wiederherstellen",
"No other versions available" : "Keine anderen Versionen verfügbar",
- "Restore" : "Wiederherstellen"
+ "More versions..." : "Weitere Versionen…"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/files_versions/l10n/de_DE.json b/apps/files_versions/l10n/de_DE.json
index 74d7f066df8..a1f3c12649f 100644
--- a/apps/files_versions/l10n/de_DE.json
+++ b/apps/files_versions/l10n/de_DE.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Konnte %s nicht zurücksetzen",
"Versions" : "Versionen",
"Failed to revert {file} to revision {timestamp}." : "Konnte {file} der Revision {timestamp} nicht rückgängig machen.",
- "More versions..." : "Weitere Versionen…",
+ "Restore" : "Wiederherstellen",
"No other versions available" : "Keine anderen Versionen verfügbar",
- "Restore" : "Wiederherstellen"
+ "More versions..." : "Weitere Versionen…"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/el.js b/apps/files_versions/l10n/el.js
index a54655bcba0..ecfc322628e 100644
--- a/apps/files_versions/l10n/el.js
+++ b/apps/files_versions/l10n/el.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Αδυναμία επαναφοράς: %s",
"Versions" : "Εκδόσεις",
"Failed to revert {file} to revision {timestamp}." : "Αποτυχία επαναφοράς του {file} στην αναθεώρηση {timestamp}.",
- "More versions..." : "Περισσότερες εκδόσεις...",
+ "Restore" : "Επαναφορά",
"No other versions available" : "Δεν υπάρχουν άλλες εκδόσεις διαθέσιμες",
- "Restore" : "Επαναφορά"
+ "More versions..." : "Περισσότερες εκδόσεις..."
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/files_versions/l10n/el.json b/apps/files_versions/l10n/el.json
index 836fdce5535..88b2fc1b3f0 100644
--- a/apps/files_versions/l10n/el.json
+++ b/apps/files_versions/l10n/el.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Αδυναμία επαναφοράς: %s",
"Versions" : "Εκδόσεις",
"Failed to revert {file} to revision {timestamp}." : "Αποτυχία επαναφοράς του {file} στην αναθεώρηση {timestamp}.",
- "More versions..." : "Περισσότερες εκδόσεις...",
+ "Restore" : "Επαναφορά",
"No other versions available" : "Δεν υπάρχουν άλλες εκδόσεις διαθέσιμες",
- "Restore" : "Επαναφορά"
+ "More versions..." : "Περισσότερες εκδόσεις..."
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/en_GB.js b/apps/files_versions/l10n/en_GB.js
index a8ca3729752..837b745b5fb 100644
--- a/apps/files_versions/l10n/en_GB.js
+++ b/apps/files_versions/l10n/en_GB.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Could not revert: %s",
"Versions" : "Versions",
"Failed to revert {file} to revision {timestamp}." : "Failed to revert {file} to revision {timestamp}.",
- "More versions..." : "More versions...",
+ "Restore" : "Restore",
"No other versions available" : "No other versions available",
- "Restore" : "Restore"
+ "More versions..." : "More versions..."
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/files_versions/l10n/en_GB.json b/apps/files_versions/l10n/en_GB.json
index 8ae47df9fcb..84e55063f67 100644
--- a/apps/files_versions/l10n/en_GB.json
+++ b/apps/files_versions/l10n/en_GB.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Could not revert: %s",
"Versions" : "Versions",
"Failed to revert {file} to revision {timestamp}." : "Failed to revert {file} to revision {timestamp}.",
- "More versions..." : "More versions...",
+ "Restore" : "Restore",
"No other versions available" : "No other versions available",
- "Restore" : "Restore"
+ "More versions..." : "More versions..."
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/eo.js b/apps/files_versions/l10n/eo.js
index 1695a84dbad..665f69bbbda 100644
--- a/apps/files_versions/l10n/eo.js
+++ b/apps/files_versions/l10n/eo.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Ne eblas malfari: %s",
"Versions" : "Versioj",
"Failed to revert {file} to revision {timestamp}." : "Malsukcesis returnigo de {file} al la revizio {timestamp}.",
- "More versions..." : "Pli da versioj...",
+ "Restore" : "Restaŭri",
"No other versions available" : "Ne disponeblas aliaj versioj",
- "Restore" : "Restaŭri"
+ "More versions..." : "Pli da versioj..."
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/files_versions/l10n/eo.json b/apps/files_versions/l10n/eo.json
index 099bbf19365..db72c173bfc 100644
--- a/apps/files_versions/l10n/eo.json
+++ b/apps/files_versions/l10n/eo.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Ne eblas malfari: %s",
"Versions" : "Versioj",
"Failed to revert {file} to revision {timestamp}." : "Malsukcesis returnigo de {file} al la revizio {timestamp}.",
- "More versions..." : "Pli da versioj...",
+ "Restore" : "Restaŭri",
"No other versions available" : "Ne disponeblas aliaj versioj",
- "Restore" : "Restaŭri"
+ "More versions..." : "Pli da versioj..."
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/es.js b/apps/files_versions/l10n/es.js
index f3d980489b0..54662b493da 100644
--- a/apps/files_versions/l10n/es.js
+++ b/apps/files_versions/l10n/es.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "No se puede revertir: %s",
"Versions" : "Revisiones",
"Failed to revert {file} to revision {timestamp}." : "No se ha podido revertir {archivo} a revisión {timestamp}.",
- "More versions..." : "Más versiones...",
+ "Restore" : "Recuperar",
"No other versions available" : "No hay otras versiones disponibles",
- "Restore" : "Recuperar"
+ "More versions..." : "Más versiones..."
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/files_versions/l10n/es.json b/apps/files_versions/l10n/es.json
index 7c395cbbb2e..692f890a880 100644
--- a/apps/files_versions/l10n/es.json
+++ b/apps/files_versions/l10n/es.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "No se puede revertir: %s",
"Versions" : "Revisiones",
"Failed to revert {file} to revision {timestamp}." : "No se ha podido revertir {archivo} a revisión {timestamp}.",
- "More versions..." : "Más versiones...",
+ "Restore" : "Recuperar",
"No other versions available" : "No hay otras versiones disponibles",
- "Restore" : "Recuperar"
+ "More versions..." : "Más versiones..."
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/es_AR.js b/apps/files_versions/l10n/es_AR.js
index b471c76e1cc..49febb3dc6c 100644
--- a/apps/files_versions/l10n/es_AR.js
+++ b/apps/files_versions/l10n/es_AR.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "No se pudo revertir: %s ",
"Versions" : "Versiones",
"Failed to revert {file} to revision {timestamp}." : "Falló al revertir {file} a la revisión {timestamp}.",
- "More versions..." : "Más versiones...",
+ "Restore" : "Recuperar",
"No other versions available" : "No hay más versiones disponibles",
- "Restore" : "Recuperar"
+ "More versions..." : "Más versiones..."
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/files_versions/l10n/es_AR.json b/apps/files_versions/l10n/es_AR.json
index 806ecb2aa30..2177de87cb5 100644
--- a/apps/files_versions/l10n/es_AR.json
+++ b/apps/files_versions/l10n/es_AR.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "No se pudo revertir: %s ",
"Versions" : "Versiones",
"Failed to revert {file} to revision {timestamp}." : "Falló al revertir {file} a la revisión {timestamp}.",
- "More versions..." : "Más versiones...",
+ "Restore" : "Recuperar",
"No other versions available" : "No hay más versiones disponibles",
- "Restore" : "Recuperar"
+ "More versions..." : "Más versiones..."
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/es_MX.js b/apps/files_versions/l10n/es_MX.js
index f3d980489b0..54662b493da 100644
--- a/apps/files_versions/l10n/es_MX.js
+++ b/apps/files_versions/l10n/es_MX.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "No se puede revertir: %s",
"Versions" : "Revisiones",
"Failed to revert {file} to revision {timestamp}." : "No se ha podido revertir {archivo} a revisión {timestamp}.",
- "More versions..." : "Más versiones...",
+ "Restore" : "Recuperar",
"No other versions available" : "No hay otras versiones disponibles",
- "Restore" : "Recuperar"
+ "More versions..." : "Más versiones..."
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/files_versions/l10n/es_MX.json b/apps/files_versions/l10n/es_MX.json
index 7c395cbbb2e..692f890a880 100644
--- a/apps/files_versions/l10n/es_MX.json
+++ b/apps/files_versions/l10n/es_MX.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "No se puede revertir: %s",
"Versions" : "Revisiones",
"Failed to revert {file} to revision {timestamp}." : "No se ha podido revertir {archivo} a revisión {timestamp}.",
- "More versions..." : "Más versiones...",
+ "Restore" : "Recuperar",
"No other versions available" : "No hay otras versiones disponibles",
- "Restore" : "Recuperar"
+ "More versions..." : "Más versiones..."
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/et_EE.js b/apps/files_versions/l10n/et_EE.js
index 14a0dc1a095..fe0616deeec 100644
--- a/apps/files_versions/l10n/et_EE.js
+++ b/apps/files_versions/l10n/et_EE.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Ei suuda taastada faili: %s",
"Versions" : "Versioonid",
"Failed to revert {file} to revision {timestamp}." : "Ebaõnnestus faili {file} taastamine revisjonile {timestamp}",
- "More versions..." : "Rohkem versioone...",
+ "Restore" : "Taasta",
"No other versions available" : "Muid versioone pole saadaval",
- "Restore" : "Taasta"
+ "More versions..." : "Rohkem versioone..."
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/files_versions/l10n/et_EE.json b/apps/files_versions/l10n/et_EE.json
index a1762b7e15f..25f0b73c579 100644
--- a/apps/files_versions/l10n/et_EE.json
+++ b/apps/files_versions/l10n/et_EE.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Ei suuda taastada faili: %s",
"Versions" : "Versioonid",
"Failed to revert {file} to revision {timestamp}." : "Ebaõnnestus faili {file} taastamine revisjonile {timestamp}",
- "More versions..." : "Rohkem versioone...",
+ "Restore" : "Taasta",
"No other versions available" : "Muid versioone pole saadaval",
- "Restore" : "Taasta"
+ "More versions..." : "Rohkem versioone..."
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/eu.js b/apps/files_versions/l10n/eu.js
index 0c92f18594c..35d1861de2c 100644
--- a/apps/files_versions/l10n/eu.js
+++ b/apps/files_versions/l10n/eu.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Ezin izan da leheneratu: %s",
"Versions" : "Bertsioak",
"Failed to revert {file} to revision {timestamp}." : "Errore bat izan da {fitxategia} {timestamp} bertsiora leheneratzean.",
- "More versions..." : "Bertsio gehiago...",
+ "Restore" : "Berrezarri",
"No other versions available" : "Ez dago bertsio gehiago eskuragarri",
- "Restore" : "Berrezarri"
+ "More versions..." : "Bertsio gehiago..."
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/files_versions/l10n/eu.json b/apps/files_versions/l10n/eu.json
index acb9e78e7f7..3bd3c0dc7b7 100644
--- a/apps/files_versions/l10n/eu.json
+++ b/apps/files_versions/l10n/eu.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Ezin izan da leheneratu: %s",
"Versions" : "Bertsioak",
"Failed to revert {file} to revision {timestamp}." : "Errore bat izan da {fitxategia} {timestamp} bertsiora leheneratzean.",
- "More versions..." : "Bertsio gehiago...",
+ "Restore" : "Berrezarri",
"No other versions available" : "Ez dago bertsio gehiago eskuragarri",
- "Restore" : "Berrezarri"
+ "More versions..." : "Bertsio gehiago..."
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/fa.js b/apps/files_versions/l10n/fa.js
index fda05b61e5d..33ef48a870a 100644
--- a/apps/files_versions/l10n/fa.js
+++ b/apps/files_versions/l10n/fa.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "بازگردانی امکان ناپذیر است: %s",
"Versions" : "نسخه ها",
"Failed to revert {file} to revision {timestamp}." : "برگرداندن {file} به نسخه {timestamp} با شکست روبرو شد",
- "More versions..." : "نسخه های بیشتر",
+ "Restore" : "بازیابی",
"No other versions available" : "نسخه ی دیگری در دسترس نیست",
- "Restore" : "بازیابی"
+ "More versions..." : "نسخه های بیشتر"
},
"nplurals=1; plural=0;");
diff --git a/apps/files_versions/l10n/fa.json b/apps/files_versions/l10n/fa.json
index 56e04f8f5c7..3dbbde955a3 100644
--- a/apps/files_versions/l10n/fa.json
+++ b/apps/files_versions/l10n/fa.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "بازگردانی امکان ناپذیر است: %s",
"Versions" : "نسخه ها",
"Failed to revert {file} to revision {timestamp}." : "برگرداندن {file} به نسخه {timestamp} با شکست روبرو شد",
- "More versions..." : "نسخه های بیشتر",
+ "Restore" : "بازیابی",
"No other versions available" : "نسخه ی دیگری در دسترس نیست",
- "Restore" : "بازیابی"
+ "More versions..." : "نسخه های بیشتر"
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/fi_FI.js b/apps/files_versions/l10n/fi_FI.js
index 32e3e28f0cc..e8e3f210500 100644
--- a/apps/files_versions/l10n/fi_FI.js
+++ b/apps/files_versions/l10n/fi_FI.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Palautus epäonnistui: %s",
"Versions" : "Versiot",
"Failed to revert {file} to revision {timestamp}." : "Tiedoston {file} palautus versioon {timestamp} epäonnistui.",
- "More versions..." : "Lisää versioita...",
+ "Restore" : "Palauta",
"No other versions available" : "Ei muita versioita saatavilla",
- "Restore" : "Palauta"
+ "More versions..." : "Lisää versioita..."
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/files_versions/l10n/fi_FI.json b/apps/files_versions/l10n/fi_FI.json
index 57d552b196b..910a7606374 100644
--- a/apps/files_versions/l10n/fi_FI.json
+++ b/apps/files_versions/l10n/fi_FI.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Palautus epäonnistui: %s",
"Versions" : "Versiot",
"Failed to revert {file} to revision {timestamp}." : "Tiedoston {file} palautus versioon {timestamp} epäonnistui.",
- "More versions..." : "Lisää versioita...",
+ "Restore" : "Palauta",
"No other versions available" : "Ei muita versioita saatavilla",
- "Restore" : "Palauta"
+ "More versions..." : "Lisää versioita..."
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/fr.js b/apps/files_versions/l10n/fr.js
index be23bf846df..65a02256d79 100644
--- a/apps/files_versions/l10n/fr.js
+++ b/apps/files_versions/l10n/fr.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Impossible de restaurer %s",
"Versions" : "Versions",
"Failed to revert {file} to revision {timestamp}." : "Échec du retour du fichier {file} à la révision {timestamp}.",
- "More versions..." : "Plus de versions...",
+ "Restore" : "Restaurer",
"No other versions available" : "Aucune autre version n'est disponible",
- "Restore" : "Restaurer"
+ "More versions..." : "Plus de versions..."
},
"nplurals=2; plural=(n > 1);");
diff --git a/apps/files_versions/l10n/fr.json b/apps/files_versions/l10n/fr.json
index 22d39d84f5f..2c2664d01a0 100644
--- a/apps/files_versions/l10n/fr.json
+++ b/apps/files_versions/l10n/fr.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Impossible de restaurer %s",
"Versions" : "Versions",
"Failed to revert {file} to revision {timestamp}." : "Échec du retour du fichier {file} à la révision {timestamp}.",
- "More versions..." : "Plus de versions...",
+ "Restore" : "Restaurer",
"No other versions available" : "Aucune autre version n'est disponible",
- "Restore" : "Restaurer"
+ "More versions..." : "Plus de versions..."
},"pluralForm" :"nplurals=2; plural=(n > 1);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/gl.js b/apps/files_versions/l10n/gl.js
index e947351bd9d..673d3a91f14 100644
--- a/apps/files_versions/l10n/gl.js
+++ b/apps/files_versions/l10n/gl.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Non foi posíbel reverter: %s",
"Versions" : "Versións",
"Failed to revert {file} to revision {timestamp}." : "Non foi posíbel reverter {file} á revisión {timestamp}.",
- "More versions..." : "Máis versións...",
+ "Restore" : "Restabelecer",
"No other versions available" : "Non hai outras versións dispoñíbeis",
- "Restore" : "Restabelecer"
+ "More versions..." : "Máis versións..."
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/files_versions/l10n/gl.json b/apps/files_versions/l10n/gl.json
index 240c78d5fed..aaa6e528756 100644
--- a/apps/files_versions/l10n/gl.json
+++ b/apps/files_versions/l10n/gl.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Non foi posíbel reverter: %s",
"Versions" : "Versións",
"Failed to revert {file} to revision {timestamp}." : "Non foi posíbel reverter {file} á revisión {timestamp}.",
- "More versions..." : "Máis versións...",
+ "Restore" : "Restabelecer",
"No other versions available" : "Non hai outras versións dispoñíbeis",
- "Restore" : "Restabelecer"
+ "More versions..." : "Máis versións..."
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/hr.js b/apps/files_versions/l10n/hr.js
index 15851fc3b12..5e3bd4d90d9 100644
--- a/apps/files_versions/l10n/hr.js
+++ b/apps/files_versions/l10n/hr.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Nije moguće vratiti: %s",
"Versions" : "Verzije",
"Failed to revert {file} to revision {timestamp}." : "Nije uspelo vraćanje {file} na reviziju {timestamp}.",
- "More versions..." : "Više verzija...",
+ "Restore" : "Obnovite",
"No other versions available" : "Nikakve druge verzije nisu dostupne",
- "Restore" : "Obnovite"
+ "More versions..." : "Više verzija..."
},
"nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;");
diff --git a/apps/files_versions/l10n/hr.json b/apps/files_versions/l10n/hr.json
index 8197420150f..ada27dc792a 100644
--- a/apps/files_versions/l10n/hr.json
+++ b/apps/files_versions/l10n/hr.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Nije moguće vratiti: %s",
"Versions" : "Verzije",
"Failed to revert {file} to revision {timestamp}." : "Nije uspelo vraćanje {file} na reviziju {timestamp}.",
- "More versions..." : "Više verzija...",
+ "Restore" : "Obnovite",
"No other versions available" : "Nikakve druge verzije nisu dostupne",
- "Restore" : "Obnovite"
+ "More versions..." : "Više verzija..."
},"pluralForm" :"nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/hu_HU.js b/apps/files_versions/l10n/hu_HU.js
index 342e65d5faf..9eb8619375e 100644
--- a/apps/files_versions/l10n/hu_HU.js
+++ b/apps/files_versions/l10n/hu_HU.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Nem sikerült átállni a változatra: %s",
"Versions" : "Az állományok korábbi változatai",
"Failed to revert {file} to revision {timestamp}." : "Nem sikerült a(z) {file} állományt erre visszaállítani: {timestamp}.",
- "More versions..." : "További változatok...",
+ "Restore" : "Visszaállítás",
"No other versions available" : "Az állománynak nincs több változata",
- "Restore" : "Visszaállítás"
+ "More versions..." : "További változatok..."
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/files_versions/l10n/hu_HU.json b/apps/files_versions/l10n/hu_HU.json
index 2b2be0f444e..3fb9deecf42 100644
--- a/apps/files_versions/l10n/hu_HU.json
+++ b/apps/files_versions/l10n/hu_HU.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Nem sikerült átállni a változatra: %s",
"Versions" : "Az állományok korábbi változatai",
"Failed to revert {file} to revision {timestamp}." : "Nem sikerült a(z) {file} állományt erre visszaállítani: {timestamp}.",
- "More versions..." : "További változatok...",
+ "Restore" : "Visszaállítás",
"No other versions available" : "Az állománynak nincs több változata",
- "Restore" : "Visszaállítás"
+ "More versions..." : "További változatok..."
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/id.js b/apps/files_versions/l10n/id.js
index 0e1111cf890..5d3579c3e62 100644
--- a/apps/files_versions/l10n/id.js
+++ b/apps/files_versions/l10n/id.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Tidak dapat mengembalikan: %s",
"Versions" : "Versi",
"Failed to revert {file} to revision {timestamp}." : "Gagal mengembalikan {file} ke revisi {timestamp}.",
- "More versions..." : "Versi lebih...",
+ "Restore" : "Pulihkan",
"No other versions available" : "Tidak ada versi lain yang tersedia",
- "Restore" : "Pulihkan"
+ "More versions..." : "Versi lebih..."
},
"nplurals=1; plural=0;");
diff --git a/apps/files_versions/l10n/id.json b/apps/files_versions/l10n/id.json
index e0b7e17bcc5..7ab5a1638f2 100644
--- a/apps/files_versions/l10n/id.json
+++ b/apps/files_versions/l10n/id.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Tidak dapat mengembalikan: %s",
"Versions" : "Versi",
"Failed to revert {file} to revision {timestamp}." : "Gagal mengembalikan {file} ke revisi {timestamp}.",
- "More versions..." : "Versi lebih...",
+ "Restore" : "Pulihkan",
"No other versions available" : "Tidak ada versi lain yang tersedia",
- "Restore" : "Pulihkan"
+ "More versions..." : "Versi lebih..."
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/is.js b/apps/files_versions/l10n/is.js
index 69ce27ca3e2..ddd94c96c65 100644
--- a/apps/files_versions/l10n/is.js
+++ b/apps/files_versions/l10n/is.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Gat ekki endurheimt: %s",
"Versions" : "Útgáfur",
"Failed to revert {file} to revision {timestamp}." : "Mistókst að endurheimta {file} útgáfu {timestamp}.",
- "More versions..." : "Fleiri útgáfur ...",
+ "Restore" : "Endurheimta",
"No other versions available" : "Engar aðrar útgáfur í boði",
- "Restore" : "Endurheimta"
+ "More versions..." : "Fleiri útgáfur ..."
},
"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);");
diff --git a/apps/files_versions/l10n/is.json b/apps/files_versions/l10n/is.json
index 3059c07e1f8..bf83a2db4fe 100644
--- a/apps/files_versions/l10n/is.json
+++ b/apps/files_versions/l10n/is.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Gat ekki endurheimt: %s",
"Versions" : "Útgáfur",
"Failed to revert {file} to revision {timestamp}." : "Mistókst að endurheimta {file} útgáfu {timestamp}.",
- "More versions..." : "Fleiri útgáfur ...",
+ "Restore" : "Endurheimta",
"No other versions available" : "Engar aðrar útgáfur í boði",
- "Restore" : "Endurheimta"
+ "More versions..." : "Fleiri útgáfur ..."
},"pluralForm" :"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/it.js b/apps/files_versions/l10n/it.js
index 45256577289..cb6248c3f42 100644
--- a/apps/files_versions/l10n/it.js
+++ b/apps/files_versions/l10n/it.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Impossibile ripristinare: %s",
"Versions" : "Versioni",
"Failed to revert {file} to revision {timestamp}." : "Ripristino di {file} alla revisione {timestamp} non riuscito.",
- "More versions..." : "Altre versioni...",
+ "Restore" : "Ripristina",
"No other versions available" : "Non sono disponibili altre versioni",
- "Restore" : "Ripristina"
+ "More versions..." : "Altre versioni..."
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/files_versions/l10n/it.json b/apps/files_versions/l10n/it.json
index af5d7bbcaba..f1479e7c114 100644
--- a/apps/files_versions/l10n/it.json
+++ b/apps/files_versions/l10n/it.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Impossibile ripristinare: %s",
"Versions" : "Versioni",
"Failed to revert {file} to revision {timestamp}." : "Ripristino di {file} alla revisione {timestamp} non riuscito.",
- "More versions..." : "Altre versioni...",
+ "Restore" : "Ripristina",
"No other versions available" : "Non sono disponibili altre versioni",
- "Restore" : "Ripristina"
+ "More versions..." : "Altre versioni..."
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/ja.js b/apps/files_versions/l10n/ja.js
index 1e4f26edc39..01fe310df71 100644
--- a/apps/files_versions/l10n/ja.js
+++ b/apps/files_versions/l10n/ja.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "元に戻せませんでした: %s",
"Versions" : "バージョン",
"Failed to revert {file} to revision {timestamp}." : "{file} を {timestamp} のリビジョンに戻すことができません。",
- "More versions..." : "他のバージョン...",
+ "Restore" : "復元",
"No other versions available" : "利用可能なバージョンはありません",
- "Restore" : "復元"
+ "More versions..." : "他のバージョン..."
},
"nplurals=1; plural=0;");
diff --git a/apps/files_versions/l10n/ja.json b/apps/files_versions/l10n/ja.json
index 7ee6b4d2c0e..aa634ca6bea 100644
--- a/apps/files_versions/l10n/ja.json
+++ b/apps/files_versions/l10n/ja.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "元に戻せませんでした: %s",
"Versions" : "バージョン",
"Failed to revert {file} to revision {timestamp}." : "{file} を {timestamp} のリビジョンに戻すことができません。",
- "More versions..." : "他のバージョン...",
+ "Restore" : "復元",
"No other versions available" : "利用可能なバージョンはありません",
- "Restore" : "復元"
+ "More versions..." : "他のバージョン..."
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/km.js b/apps/files_versions/l10n/km.js
index b1edbcbb3cc..6b4f21e25ad 100644
--- a/apps/files_versions/l10n/km.js
+++ b/apps/files_versions/l10n/km.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "មិន​អាច​ត្រឡប់៖ %s",
"Versions" : "កំណែ",
"Failed to revert {file} to revision {timestamp}." : "មិន​អាច​ត្រឡប់ {file} ទៅ​កំណែ​សម្រួល {timestamp} បាន​ទេ។",
- "More versions..." : "កំណែ​ច្រើន​ទៀត...",
+ "Restore" : "ស្ដារ​មក​វិញ",
"No other versions available" : "មិន​មាន​កំណែ​ផ្សេង​ទៀត​ទេ",
- "Restore" : "ស្ដារ​មក​វិញ"
+ "More versions..." : "កំណែ​ច្រើន​ទៀត..."
},
"nplurals=1; plural=0;");
diff --git a/apps/files_versions/l10n/km.json b/apps/files_versions/l10n/km.json
index 830170a2234..020b9e81ce5 100644
--- a/apps/files_versions/l10n/km.json
+++ b/apps/files_versions/l10n/km.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "មិន​អាច​ត្រឡប់៖ %s",
"Versions" : "កំណែ",
"Failed to revert {file} to revision {timestamp}." : "មិន​អាច​ត្រឡប់ {file} ទៅ​កំណែ​សម្រួល {timestamp} បាន​ទេ។",
- "More versions..." : "កំណែ​ច្រើន​ទៀត...",
+ "Restore" : "ស្ដារ​មក​វិញ",
"No other versions available" : "មិន​មាន​កំណែ​ផ្សេង​ទៀត​ទេ",
- "Restore" : "ស្ដារ​មក​វិញ"
+ "More versions..." : "កំណែ​ច្រើន​ទៀត..."
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/kn.js b/apps/files_versions/l10n/kn.js
index b394094989a..c7c255f5480 100644
--- a/apps/files_versions/l10n/kn.js
+++ b/apps/files_versions/l10n/kn.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "ಹಿಂತಿರುಗಲಾಗಲಿಲ್ಲ: %s",
"Versions" : "ಆವೃತ್ತಿಗಳು",
"Failed to revert {file} to revision {timestamp}." : "{timestamp} ದ ಪರಿಷ್ಕರಣೆ ಇಂದ {file} ಕಡತವನ್ನು ಹಿಂದಿರುಗಿಸಲು ವಿಫಲವಾಗಿದೆ.",
- "More versions..." : "ಇನ್ನಷ್ಟು ಆವೃತ್ತಿಗಳು ...",
+ "Restore" : "ಮರುಸ್ಥಾಪಿಸು",
"No other versions available" : "ಇನ್ನಿತರೆ ಯಾವುದೇ ಆವೃತ್ತಿಗಳು ಲಭ್ಯವಿಲ್ಲ",
- "Restore" : "ಮರುಸ್ಥಾಪಿಸು"
+ "More versions..." : "ಇನ್ನಷ್ಟು ಆವೃತ್ತಿಗಳು ..."
},
"nplurals=1; plural=0;");
diff --git a/apps/files_versions/l10n/kn.json b/apps/files_versions/l10n/kn.json
index 17b61dd6bac..37f1d57c6bd 100644
--- a/apps/files_versions/l10n/kn.json
+++ b/apps/files_versions/l10n/kn.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "ಹಿಂತಿರುಗಲಾಗಲಿಲ್ಲ: %s",
"Versions" : "ಆವೃತ್ತಿಗಳು",
"Failed to revert {file} to revision {timestamp}." : "{timestamp} ದ ಪರಿಷ್ಕರಣೆ ಇಂದ {file} ಕಡತವನ್ನು ಹಿಂದಿರುಗಿಸಲು ವಿಫಲವಾಗಿದೆ.",
- "More versions..." : "ಇನ್ನಷ್ಟು ಆವೃತ್ತಿಗಳು ...",
+ "Restore" : "ಮರುಸ್ಥಾಪಿಸು",
"No other versions available" : "ಇನ್ನಿತರೆ ಯಾವುದೇ ಆವೃತ್ತಿಗಳು ಲಭ್ಯವಿಲ್ಲ",
- "Restore" : "ಮರುಸ್ಥಾಪಿಸು"
+ "More versions..." : "ಇನ್ನಷ್ಟು ಆವೃತ್ತಿಗಳು ..."
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/ko.js b/apps/files_versions/l10n/ko.js
index 9e125ec6bbf..dca7683d2da 100644
--- a/apps/files_versions/l10n/ko.js
+++ b/apps/files_versions/l10n/ko.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "되돌릴 수 없습니다: %s",
"Versions" : "버전",
"Failed to revert {file} to revision {timestamp}." : "{file}을(를) 리비전 {timestamp}으(로) 되돌리는 데 실패하였습니다.",
- "More versions..." : "더 많은 버전...",
+ "Restore" : "복원",
"No other versions available" : "다른 버전을 사용할 수 없습니다",
- "Restore" : "복원"
+ "More versions..." : "더 많은 버전..."
},
"nplurals=1; plural=0;");
diff --git a/apps/files_versions/l10n/ko.json b/apps/files_versions/l10n/ko.json
index 80ebb43912a..1665579ded1 100644
--- a/apps/files_versions/l10n/ko.json
+++ b/apps/files_versions/l10n/ko.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "되돌릴 수 없습니다: %s",
"Versions" : "버전",
"Failed to revert {file} to revision {timestamp}." : "{file}을(를) 리비전 {timestamp}으(로) 되돌리는 데 실패하였습니다.",
- "More versions..." : "더 많은 버전...",
+ "Restore" : "복원",
"No other versions available" : "다른 버전을 사용할 수 없습니다",
- "Restore" : "복원"
+ "More versions..." : "더 많은 버전..."
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/lb.js b/apps/files_versions/l10n/lb.js
index 1678cad569d..e2ef61b370f 100644
--- a/apps/files_versions/l10n/lb.js
+++ b/apps/files_versions/l10n/lb.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Konnt net zrécksetzen: %s",
"Versions" : "Versiounen",
"Failed to revert {file} to revision {timestamp}." : "Konnt {file} net op d'Versioun {timestamp} zrécksetzen.",
- "More versions..." : "Méi Versiounen...",
+ "Restore" : "Zrécksetzen",
"No other versions available" : "Keng aner Versiounen disponibel",
- "Restore" : "Zrécksetzen"
+ "More versions..." : "Méi Versiounen..."
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/files_versions/l10n/lb.json b/apps/files_versions/l10n/lb.json
index e5fbb6c220c..8265a6bb552 100644
--- a/apps/files_versions/l10n/lb.json
+++ b/apps/files_versions/l10n/lb.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Konnt net zrécksetzen: %s",
"Versions" : "Versiounen",
"Failed to revert {file} to revision {timestamp}." : "Konnt {file} net op d'Versioun {timestamp} zrécksetzen.",
- "More versions..." : "Méi Versiounen...",
+ "Restore" : "Zrécksetzen",
"No other versions available" : "Keng aner Versiounen disponibel",
- "Restore" : "Zrécksetzen"
+ "More versions..." : "Méi Versiounen..."
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/lt_LT.js b/apps/files_versions/l10n/lt_LT.js
index 987b914412a..25494614a96 100644
--- a/apps/files_versions/l10n/lt_LT.js
+++ b/apps/files_versions/l10n/lt_LT.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Nepavyko atstatyti: %s",
"Versions" : "Versijos",
"Failed to revert {file} to revision {timestamp}." : "Nepavyko atstatyti {file} į būseną {timestamp}.",
- "More versions..." : "Daugiau versijų...",
+ "Restore" : "Atstatyti",
"No other versions available" : "Nėra daugiau versijų",
- "Restore" : "Atstatyti"
+ "More versions..." : "Daugiau versijų..."
},
"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);");
diff --git a/apps/files_versions/l10n/lt_LT.json b/apps/files_versions/l10n/lt_LT.json
index 5e30612dd33..3b3a6feb0f5 100644
--- a/apps/files_versions/l10n/lt_LT.json
+++ b/apps/files_versions/l10n/lt_LT.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Nepavyko atstatyti: %s",
"Versions" : "Versijos",
"Failed to revert {file} to revision {timestamp}." : "Nepavyko atstatyti {file} į būseną {timestamp}.",
- "More versions..." : "Daugiau versijų...",
+ "Restore" : "Atstatyti",
"No other versions available" : "Nėra daugiau versijų",
- "Restore" : "Atstatyti"
+ "More versions..." : "Daugiau versijų..."
},"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/lv.js b/apps/files_versions/l10n/lv.js
index 5ac3fa1ad87..9db45fe7b4a 100644
--- a/apps/files_versions/l10n/lv.js
+++ b/apps/files_versions/l10n/lv.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Nevarēja atgriezt — %s",
"Versions" : "Versijas",
"Failed to revert {file} to revision {timestamp}." : "Neizdevās atjaunot {file} no rediģējuma {timestamp} ",
- "More versions..." : "Vairāk versiju...",
+ "Restore" : "Atjaunot",
"No other versions available" : "Citas versijas nav pieejamas",
- "Restore" : "Atjaunot"
+ "More versions..." : "Vairāk versiju..."
},
"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);");
diff --git a/apps/files_versions/l10n/lv.json b/apps/files_versions/l10n/lv.json
index f0912544887..f2d4c2fc316 100644
--- a/apps/files_versions/l10n/lv.json
+++ b/apps/files_versions/l10n/lv.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Nevarēja atgriezt — %s",
"Versions" : "Versijas",
"Failed to revert {file} to revision {timestamp}." : "Neizdevās atjaunot {file} no rediģējuma {timestamp} ",
- "More versions..." : "Vairāk versiju...",
+ "Restore" : "Atjaunot",
"No other versions available" : "Citas versijas nav pieejamas",
- "Restore" : "Atjaunot"
+ "More versions..." : "Vairāk versiju..."
},"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/mk.js b/apps/files_versions/l10n/mk.js
index fa295501320..32bd8ea5140 100644
--- a/apps/files_versions/l10n/mk.js
+++ b/apps/files_versions/l10n/mk.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Не можев да го вратам: %s",
"Versions" : "Верзии",
"Failed to revert {file} to revision {timestamp}." : "Не успеав да го вратам {file} на ревизијата {timestamp}.",
- "More versions..." : "Повеќе верзии...",
+ "Restore" : "Врати",
"No other versions available" : "Не постојат други верзии",
- "Restore" : "Врати"
+ "More versions..." : "Повеќе верзии..."
},
"nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;");
diff --git a/apps/files_versions/l10n/mk.json b/apps/files_versions/l10n/mk.json
index cdef37ecde3..2c7b148e89a 100644
--- a/apps/files_versions/l10n/mk.json
+++ b/apps/files_versions/l10n/mk.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Не можев да го вратам: %s",
"Versions" : "Верзии",
"Failed to revert {file} to revision {timestamp}." : "Не успеав да го вратам {file} на ревизијата {timestamp}.",
- "More versions..." : "Повеќе верзии...",
+ "Restore" : "Врати",
"No other versions available" : "Не постојат други верзии",
- "Restore" : "Врати"
+ "More versions..." : "Повеќе верзии..."
},"pluralForm" :"nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/ms_MY.js b/apps/files_versions/l10n/ms_MY.js
index f645a255caf..3edb05dd0ab 100644
--- a/apps/files_versions/l10n/ms_MY.js
+++ b/apps/files_versions/l10n/ms_MY.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Tidak dapat kembalikan: %s",
"Versions" : "Versi",
"Failed to revert {file} to revision {timestamp}." : "Gagal kembalikan {file} ke semakan {timestamp}.",
- "More versions..." : "Lagi versi...",
+ "Restore" : "Pulihkan",
"No other versions available" : "Tiada lagi versi lain",
- "Restore" : "Pulihkan"
+ "More versions..." : "Lagi versi..."
},
"nplurals=1; plural=0;");
diff --git a/apps/files_versions/l10n/ms_MY.json b/apps/files_versions/l10n/ms_MY.json
index 6ed0cd34131..3cd889353a9 100644
--- a/apps/files_versions/l10n/ms_MY.json
+++ b/apps/files_versions/l10n/ms_MY.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Tidak dapat kembalikan: %s",
"Versions" : "Versi",
"Failed to revert {file} to revision {timestamp}." : "Gagal kembalikan {file} ke semakan {timestamp}.",
- "More versions..." : "Lagi versi...",
+ "Restore" : "Pulihkan",
"No other versions available" : "Tiada lagi versi lain",
- "Restore" : "Pulihkan"
+ "More versions..." : "Lagi versi..."
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/nb_NO.js b/apps/files_versions/l10n/nb_NO.js
index e3279e61bf8..8fd1fbc8409 100644
--- a/apps/files_versions/l10n/nb_NO.js
+++ b/apps/files_versions/l10n/nb_NO.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Klarte ikke å tilbakeføre: %s",
"Versions" : "Versjoner",
"Failed to revert {file} to revision {timestamp}." : "Klarte ikke å tilbakeføre {file} til revisjon {timestamp}.",
- "More versions..." : "Flere versjoner",
+ "Restore" : "Gjenopprett",
"No other versions available" : "Det finnes ingen andre versjoner",
- "Restore" : "Gjenopprett"
+ "More versions..." : "Flere versjoner"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/files_versions/l10n/nb_NO.json b/apps/files_versions/l10n/nb_NO.json
index 18c520014d1..c68a10c8728 100644
--- a/apps/files_versions/l10n/nb_NO.json
+++ b/apps/files_versions/l10n/nb_NO.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Klarte ikke å tilbakeføre: %s",
"Versions" : "Versjoner",
"Failed to revert {file} to revision {timestamp}." : "Klarte ikke å tilbakeføre {file} til revisjon {timestamp}.",
- "More versions..." : "Flere versjoner",
+ "Restore" : "Gjenopprett",
"No other versions available" : "Det finnes ingen andre versjoner",
- "Restore" : "Gjenopprett"
+ "More versions..." : "Flere versjoner"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/nl.js b/apps/files_versions/l10n/nl.js
index 53de2706f35..14f7f06852a 100644
--- a/apps/files_versions/l10n/nl.js
+++ b/apps/files_versions/l10n/nl.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Kon niet terugdraaien: %s",
"Versions" : "Versies",
"Failed to revert {file} to revision {timestamp}." : "Kon {file} niet terugdraaien naar revisie {timestamp}.",
- "More versions..." : "Meer versies...",
+ "Restore" : "Herstellen",
"No other versions available" : "Geen andere versies beschikbaar",
- "Restore" : "Herstellen"
+ "More versions..." : "Meer versies..."
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/files_versions/l10n/nl.json b/apps/files_versions/l10n/nl.json
index b564b5e54b3..400b9d46730 100644
--- a/apps/files_versions/l10n/nl.json
+++ b/apps/files_versions/l10n/nl.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Kon niet terugdraaien: %s",
"Versions" : "Versies",
"Failed to revert {file} to revision {timestamp}." : "Kon {file} niet terugdraaien naar revisie {timestamp}.",
- "More versions..." : "Meer versies...",
+ "Restore" : "Herstellen",
"No other versions available" : "Geen andere versies beschikbaar",
- "Restore" : "Herstellen"
+ "More versions..." : "Meer versies..."
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/nn_NO.js b/apps/files_versions/l10n/nn_NO.js
index feedf5a9449..f83901dfb6b 100644
--- a/apps/files_versions/l10n/nn_NO.js
+++ b/apps/files_versions/l10n/nn_NO.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Klarte ikkje å tilbakestilla: %s",
"Versions" : "Utgåver",
"Failed to revert {file} to revision {timestamp}." : "Klarte ikkje å tilbakestilla {file} til utgåva {timestamp}.",
- "More versions..." : "Fleire utgåver …",
+ "Restore" : "Gjenopprett",
"No other versions available" : "Ingen andre utgåver tilgjengeleg",
- "Restore" : "Gjenopprett"
+ "More versions..." : "Fleire utgåver …"
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/files_versions/l10n/nn_NO.json b/apps/files_versions/l10n/nn_NO.json
index 96d410cfa04..7fb0b12986e 100644
--- a/apps/files_versions/l10n/nn_NO.json
+++ b/apps/files_versions/l10n/nn_NO.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Klarte ikkje å tilbakestilla: %s",
"Versions" : "Utgåver",
"Failed to revert {file} to revision {timestamp}." : "Klarte ikkje å tilbakestilla {file} til utgåva {timestamp}.",
- "More versions..." : "Fleire utgåver …",
+ "Restore" : "Gjenopprett",
"No other versions available" : "Ingen andre utgåver tilgjengeleg",
- "Restore" : "Gjenopprett"
+ "More versions..." : "Fleire utgåver …"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/oc.js b/apps/files_versions/l10n/oc.js
index dbb8fa894cb..7dbb7a243fd 100644
--- a/apps/files_versions/l10n/oc.js
+++ b/apps/files_versions/l10n/oc.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Impossible de restablir %s",
"Versions" : "Versions",
"Failed to revert {file} to revision {timestamp}." : "Fracàs del retorn del fichièr {file} a la revision {timestamp}.",
- "More versions..." : "Mai de versions...",
+ "Restore" : "Restablir",
"No other versions available" : "Cap d'autra version es pas disponibla",
- "Restore" : "Restablir"
+ "More versions..." : "Mai de versions..."
},
"nplurals=2; plural=(n > 1);");
diff --git a/apps/files_versions/l10n/oc.json b/apps/files_versions/l10n/oc.json
index cf3ddd95d33..a85d32b650a 100644
--- a/apps/files_versions/l10n/oc.json
+++ b/apps/files_versions/l10n/oc.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Impossible de restablir %s",
"Versions" : "Versions",
"Failed to revert {file} to revision {timestamp}." : "Fracàs del retorn del fichièr {file} a la revision {timestamp}.",
- "More versions..." : "Mai de versions...",
+ "Restore" : "Restablir",
"No other versions available" : "Cap d'autra version es pas disponibla",
- "Restore" : "Restablir"
+ "More versions..." : "Mai de versions..."
},"pluralForm" :"nplurals=2; plural=(n > 1);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/pl.js b/apps/files_versions/l10n/pl.js
index dce5f500ef6..f93cfc4845e 100644
--- a/apps/files_versions/l10n/pl.js
+++ b/apps/files_versions/l10n/pl.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Nie można było przywrócić: %s",
"Versions" : "Wersje",
"Failed to revert {file} to revision {timestamp}." : "Nie udało się przywrócić {file} do wersji z {timestamp}.",
- "More versions..." : "Więcej wersji...",
+ "Restore" : "Przywróć",
"No other versions available" : "Nie są dostępne żadne inne wersje",
- "Restore" : "Przywróć"
+ "More versions..." : "Więcej wersji..."
},
"nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);");
diff --git a/apps/files_versions/l10n/pl.json b/apps/files_versions/l10n/pl.json
index 68860dd115a..974ba809b0a 100644
--- a/apps/files_versions/l10n/pl.json
+++ b/apps/files_versions/l10n/pl.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Nie można było przywrócić: %s",
"Versions" : "Wersje",
"Failed to revert {file} to revision {timestamp}." : "Nie udało się przywrócić {file} do wersji z {timestamp}.",
- "More versions..." : "Więcej wersji...",
+ "Restore" : "Przywróć",
"No other versions available" : "Nie są dostępne żadne inne wersje",
- "Restore" : "Przywróć"
+ "More versions..." : "Więcej wersji..."
},"pluralForm" :"nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/pt_BR.js b/apps/files_versions/l10n/pt_BR.js
index 229d935be22..9c3bce45e9b 100644
--- a/apps/files_versions/l10n/pt_BR.js
+++ b/apps/files_versions/l10n/pt_BR.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Impossível reverter: %s",
"Versions" : "Versões",
"Failed to revert {file} to revision {timestamp}." : "Falha ao reverter {file} para a revisão {timestamp}.",
- "More versions..." : "Mais versões...",
+ "Restore" : "Restaurar",
"No other versions available" : "Nenhuma outra versão disponível",
- "Restore" : "Restaurar"
+ "More versions..." : "Mais versões..."
},
"nplurals=2; plural=(n > 1);");
diff --git a/apps/files_versions/l10n/pt_BR.json b/apps/files_versions/l10n/pt_BR.json
index 11225a32b9f..b54c27c6b46 100644
--- a/apps/files_versions/l10n/pt_BR.json
+++ b/apps/files_versions/l10n/pt_BR.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Impossível reverter: %s",
"Versions" : "Versões",
"Failed to revert {file} to revision {timestamp}." : "Falha ao reverter {file} para a revisão {timestamp}.",
- "More versions..." : "Mais versões...",
+ "Restore" : "Restaurar",
"No other versions available" : "Nenhuma outra versão disponível",
- "Restore" : "Restaurar"
+ "More versions..." : "Mais versões..."
},"pluralForm" :"nplurals=2; plural=(n > 1);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/pt_PT.js b/apps/files_versions/l10n/pt_PT.js
index 29ae6e3eef9..cb058c8b02e 100644
--- a/apps/files_versions/l10n/pt_PT.js
+++ b/apps/files_versions/l10n/pt_PT.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Não foi possível reverter: %s",
"Versions" : "Versões",
"Failed to revert {file} to revision {timestamp}." : "Falhou a recuperação do ficheiro {file} para a revisão {timestamp}.",
- "More versions..." : "Mais versões...",
+ "Restore" : "Restaurar",
"No other versions available" : "Não existem versões mais antigas",
- "Restore" : "Restaurar"
+ "More versions..." : "Mais versões..."
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/files_versions/l10n/pt_PT.json b/apps/files_versions/l10n/pt_PT.json
index 4ce27f4c748..7dc6828a72f 100644
--- a/apps/files_versions/l10n/pt_PT.json
+++ b/apps/files_versions/l10n/pt_PT.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Não foi possível reverter: %s",
"Versions" : "Versões",
"Failed to revert {file} to revision {timestamp}." : "Falhou a recuperação do ficheiro {file} para a revisão {timestamp}.",
- "More versions..." : "Mais versões...",
+ "Restore" : "Restaurar",
"No other versions available" : "Não existem versões mais antigas",
- "Restore" : "Restaurar"
+ "More versions..." : "Mais versões..."
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/ro.js b/apps/files_versions/l10n/ro.js
index 1c8d6382d9f..815c04e6519 100644
--- a/apps/files_versions/l10n/ro.js
+++ b/apps/files_versions/l10n/ro.js
@@ -3,8 +3,8 @@ OC.L10N.register(
{
"Could not revert: %s" : "Nu a putut reveni: %s",
"Versions" : "Versiuni",
- "More versions..." : "Mai multe versiuni...",
+ "Restore" : "Restabilire",
"No other versions available" : "Nu există alte versiuni disponibile",
- "Restore" : "Restabilire"
+ "More versions..." : "Mai multe versiuni..."
},
"nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));");
diff --git a/apps/files_versions/l10n/ro.json b/apps/files_versions/l10n/ro.json
index 3b2d0c795ab..78a4ecc4e7c 100644
--- a/apps/files_versions/l10n/ro.json
+++ b/apps/files_versions/l10n/ro.json
@@ -1,8 +1,8 @@
{ "translations": {
"Could not revert: %s" : "Nu a putut reveni: %s",
"Versions" : "Versiuni",
- "More versions..." : "Mai multe versiuni...",
+ "Restore" : "Restabilire",
"No other versions available" : "Nu există alte versiuni disponibile",
- "Restore" : "Restabilire"
+ "More versions..." : "Mai multe versiuni..."
},"pluralForm" :"nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/ru.js b/apps/files_versions/l10n/ru.js
index 25248b9de5f..7809e4f1190 100644
--- a/apps/files_versions/l10n/ru.js
+++ b/apps/files_versions/l10n/ru.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Невозможно откатить: %s",
"Versions" : "Версии",
"Failed to revert {file} to revision {timestamp}." : "Не удалось откатить {file} к ревизии {timestamp}.",
- "More versions..." : "Ещё версии...",
+ "Restore" : "Откатить",
"No other versions available" : "Других версий не доступно",
- "Restore" : "Откатить"
+ "More versions..." : "Ещё версии..."
},
"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);");
diff --git a/apps/files_versions/l10n/ru.json b/apps/files_versions/l10n/ru.json
index 738bb332d23..595d2504319 100644
--- a/apps/files_versions/l10n/ru.json
+++ b/apps/files_versions/l10n/ru.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Невозможно откатить: %s",
"Versions" : "Версии",
"Failed to revert {file} to revision {timestamp}." : "Не удалось откатить {file} к ревизии {timestamp}.",
- "More versions..." : "Ещё версии...",
+ "Restore" : "Откатить",
"No other versions available" : "Других версий не доступно",
- "Restore" : "Откатить"
+ "More versions..." : "Ещё версии..."
},"pluralForm" :"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/sk_SK.js b/apps/files_versions/l10n/sk_SK.js
index 1433f42f2b5..c4857784928 100644
--- a/apps/files_versions/l10n/sk_SK.js
+++ b/apps/files_versions/l10n/sk_SK.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Nemožno obnoviť: %s",
"Versions" : "Verzie",
"Failed to revert {file} to revision {timestamp}." : "Zlyhalo obnovenie súboru {file} na verziu {timestamp}.",
- "More versions..." : "Viac verzií...",
+ "Restore" : "Obnoviť",
"No other versions available" : "Žiadne ďalšie verzie nie sú dostupné",
- "Restore" : "Obnoviť"
+ "More versions..." : "Viac verzií..."
},
"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;");
diff --git a/apps/files_versions/l10n/sk_SK.json b/apps/files_versions/l10n/sk_SK.json
index da8a7b02ca9..5ac48397699 100644
--- a/apps/files_versions/l10n/sk_SK.json
+++ b/apps/files_versions/l10n/sk_SK.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Nemožno obnoviť: %s",
"Versions" : "Verzie",
"Failed to revert {file} to revision {timestamp}." : "Zlyhalo obnovenie súboru {file} na verziu {timestamp}.",
- "More versions..." : "Viac verzií...",
+ "Restore" : "Obnoviť",
"No other versions available" : "Žiadne ďalšie verzie nie sú dostupné",
- "Restore" : "Obnoviť"
+ "More versions..." : "Viac verzií..."
},"pluralForm" :"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/sl.js b/apps/files_versions/l10n/sl.js
index abbf4a803d8..e04e39a3c62 100644
--- a/apps/files_versions/l10n/sl.js
+++ b/apps/files_versions/l10n/sl.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Ni mogoče povrniti: %s",
"Versions" : "Različice",
"Failed to revert {file} to revision {timestamp}." : "Povrnitev datoteke {file} na objavo {timestamp} je spodletelo.",
- "More versions..." : "Več različic",
+ "Restore" : "Obnovi",
"No other versions available" : "Ni drugih različic",
- "Restore" : "Obnovi"
+ "More versions..." : "Več različic"
},
"nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);");
diff --git a/apps/files_versions/l10n/sl.json b/apps/files_versions/l10n/sl.json
index 581c9aab594..a66e94e425d 100644
--- a/apps/files_versions/l10n/sl.json
+++ b/apps/files_versions/l10n/sl.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Ni mogoče povrniti: %s",
"Versions" : "Različice",
"Failed to revert {file} to revision {timestamp}." : "Povrnitev datoteke {file} na objavo {timestamp} je spodletelo.",
- "More versions..." : "Več različic",
+ "Restore" : "Obnovi",
"No other versions available" : "Ni drugih različic",
- "Restore" : "Obnovi"
+ "More versions..." : "Več različic"
},"pluralForm" :"nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/sq.js b/apps/files_versions/l10n/sq.js
index 5330b36aad5..4c9f9487f28 100644
--- a/apps/files_versions/l10n/sq.js
+++ b/apps/files_versions/l10n/sq.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Nuk mund të ktheje: %s",
"Versions" : "Versioni",
"Failed to revert {file} to revision {timestamp}." : "Dështoi në ktheje {skedar} të rishikimit {kohëstampe}.",
- "More versions..." : "Versione m'shumë...",
+ "Restore" : "Rivendos",
"No other versions available" : "Nuk ka versione të tjera në dispozicion",
- "Restore" : "Rivendos"
+ "More versions..." : "Versione m'shumë..."
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/files_versions/l10n/sq.json b/apps/files_versions/l10n/sq.json
index 994772c8e3e..4e1c813d9bf 100644
--- a/apps/files_versions/l10n/sq.json
+++ b/apps/files_versions/l10n/sq.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Nuk mund të ktheje: %s",
"Versions" : "Versioni",
"Failed to revert {file} to revision {timestamp}." : "Dështoi në ktheje {skedar} të rishikimit {kohëstampe}.",
- "More versions..." : "Versione m'shumë...",
+ "Restore" : "Rivendos",
"No other versions available" : "Nuk ka versione të tjera në dispozicion",
- "Restore" : "Rivendos"
+ "More versions..." : "Versione m'shumë..."
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/sr.js b/apps/files_versions/l10n/sr.js
index 09b047a563a..9b8c97592cc 100644
--- a/apps/files_versions/l10n/sr.js
+++ b/apps/files_versions/l10n/sr.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Не могу да вратим: %s",
"Versions" : "Верзије",
"Failed to revert {file} to revision {timestamp}." : "Не могу да вратим {file} на ревизију {timestamp}.",
- "More versions..." : "Још верзија...",
+ "Restore" : "Врати",
"No other versions available" : "Нема других верзија",
- "Restore" : "Врати"
+ "More versions..." : "Још верзија..."
},
"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);");
diff --git a/apps/files_versions/l10n/sr.json b/apps/files_versions/l10n/sr.json
index 8dfb6c37748..73484b6f3d5 100644
--- a/apps/files_versions/l10n/sr.json
+++ b/apps/files_versions/l10n/sr.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Не могу да вратим: %s",
"Versions" : "Верзије",
"Failed to revert {file} to revision {timestamp}." : "Не могу да вратим {file} на ревизију {timestamp}.",
- "More versions..." : "Још верзија...",
+ "Restore" : "Врати",
"No other versions available" : "Нема других верзија",
- "Restore" : "Врати"
+ "More versions..." : "Још верзија..."
},"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/sr@latin.js b/apps/files_versions/l10n/sr@latin.js
index 7b6f750d1a6..627d70eb51b 100644
--- a/apps/files_versions/l10n/sr@latin.js
+++ b/apps/files_versions/l10n/sr@latin.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Ne mogu da vratim: %s",
"Versions" : "Verzije",
"Failed to revert {file} to revision {timestamp}." : "Ne mogu da vratim {file} na reviziju {timestamp}.",
- "More versions..." : "Još verzija...",
+ "Restore" : "Vrati",
"No other versions available" : "Nema drugih verzija",
- "Restore" : "Vrati"
+ "More versions..." : "Još verzija..."
},
"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);");
diff --git a/apps/files_versions/l10n/sr@latin.json b/apps/files_versions/l10n/sr@latin.json
index b7a0eb3b398..63fe55cf50e 100644
--- a/apps/files_versions/l10n/sr@latin.json
+++ b/apps/files_versions/l10n/sr@latin.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Ne mogu da vratim: %s",
"Versions" : "Verzije",
"Failed to revert {file} to revision {timestamp}." : "Ne mogu da vratim {file} na reviziju {timestamp}.",
- "More versions..." : "Još verzija...",
+ "Restore" : "Vrati",
"No other versions available" : "Nema drugih verzija",
- "Restore" : "Vrati"
+ "More versions..." : "Još verzija..."
},"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/sv.js b/apps/files_versions/l10n/sv.js
index 6ff23cc5635..1b5d05f51ec 100644
--- a/apps/files_versions/l10n/sv.js
+++ b/apps/files_versions/l10n/sv.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Kunde inte återställa: %s",
"Versions" : "Versioner",
"Failed to revert {file} to revision {timestamp}." : "Kunde inte återställa {file} till revision {timestamp}.",
- "More versions..." : "Fler versioner...",
+ "Restore" : "Återskapa",
"No other versions available" : "Inga andra versioner tillgängliga",
- "Restore" : "Återskapa"
+ "More versions..." : "Fler versioner..."
},
"nplurals=2; plural=(n != 1);");
diff --git a/apps/files_versions/l10n/sv.json b/apps/files_versions/l10n/sv.json
index ccf056f6f0f..30589a25bb5 100644
--- a/apps/files_versions/l10n/sv.json
+++ b/apps/files_versions/l10n/sv.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Kunde inte återställa: %s",
"Versions" : "Versioner",
"Failed to revert {file} to revision {timestamp}." : "Kunde inte återställa {file} till revision {timestamp}.",
- "More versions..." : "Fler versioner...",
+ "Restore" : "Återskapa",
"No other versions available" : "Inga andra versioner tillgängliga",
- "Restore" : "Återskapa"
+ "More versions..." : "Fler versioner..."
},"pluralForm" :"nplurals=2; plural=(n != 1);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/th_TH.js b/apps/files_versions/l10n/th_TH.js
index 81559c9cea3..97d0539ca55 100644
--- a/apps/files_versions/l10n/th_TH.js
+++ b/apps/files_versions/l10n/th_TH.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "ไม่สามารถย้อนกลับ: %s",
"Versions" : "รุ่น",
"Failed to revert {file} to revision {timestamp}." : "{file} ล้มเหลวที่จะย้อนกลับ มีการแก้ไขเมื่อ {timestamp}",
- "More versions..." : "รุ่นอื่นๆ ...",
+ "Restore" : "คืนค่า",
"No other versions available" : "ไม่มีรุ่นอื่นๆ",
- "Restore" : "คืนค่า"
+ "More versions..." : "รุ่นอื่นๆ ..."
},
"nplurals=1; plural=0;");
diff --git a/apps/files_versions/l10n/th_TH.json b/apps/files_versions/l10n/th_TH.json
index bd07d72a582..a67fa3e17e0 100644
--- a/apps/files_versions/l10n/th_TH.json
+++ b/apps/files_versions/l10n/th_TH.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "ไม่สามารถย้อนกลับ: %s",
"Versions" : "รุ่น",
"Failed to revert {file} to revision {timestamp}." : "{file} ล้มเหลวที่จะย้อนกลับ มีการแก้ไขเมื่อ {timestamp}",
- "More versions..." : "รุ่นอื่นๆ ...",
+ "Restore" : "คืนค่า",
"No other versions available" : "ไม่มีรุ่นอื่นๆ",
- "Restore" : "คืนค่า"
+ "More versions..." : "รุ่นอื่นๆ ..."
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/tr.js b/apps/files_versions/l10n/tr.js
index ad248adc1dd..00d5cbe15d4 100644
--- a/apps/files_versions/l10n/tr.js
+++ b/apps/files_versions/l10n/tr.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Geri alınamayan: %s",
"Versions" : "Sürümler",
"Failed to revert {file} to revision {timestamp}." : "{file} dosyası {timestamp} gözden geçirmesine geri alınamadı.",
- "More versions..." : "Daha fazla sürüm...",
+ "Restore" : "Geri yükle",
"No other versions available" : "Başka sürüm mevcut değil",
- "Restore" : "Geri yükle"
+ "More versions..." : "Daha fazla sürüm..."
},
"nplurals=2; plural=(n > 1);");
diff --git a/apps/files_versions/l10n/tr.json b/apps/files_versions/l10n/tr.json
index 49731d545c6..73aab761203 100644
--- a/apps/files_versions/l10n/tr.json
+++ b/apps/files_versions/l10n/tr.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Geri alınamayan: %s",
"Versions" : "Sürümler",
"Failed to revert {file} to revision {timestamp}." : "{file} dosyası {timestamp} gözden geçirmesine geri alınamadı.",
- "More versions..." : "Daha fazla sürüm...",
+ "Restore" : "Geri yükle",
"No other versions available" : "Başka sürüm mevcut değil",
- "Restore" : "Geri yükle"
+ "More versions..." : "Daha fazla sürüm..."
},"pluralForm" :"nplurals=2; plural=(n > 1);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/uk.js b/apps/files_versions/l10n/uk.js
index 02947793545..75335f25e55 100644
--- a/apps/files_versions/l10n/uk.js
+++ b/apps/files_versions/l10n/uk.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Не вдалося відновити: %s",
"Versions" : "Версії",
"Failed to revert {file} to revision {timestamp}." : "Не вдалося повернути {file} до ревізії {timestamp}.",
- "More versions..." : "Більше версій ...",
+ "Restore" : "Відновити",
"No other versions available" : "Інші версії недоступні",
- "Restore" : "Відновити"
+ "More versions..." : "Більше версій ..."
},
"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);");
diff --git a/apps/files_versions/l10n/uk.json b/apps/files_versions/l10n/uk.json
index 6571b1fe2b5..54a0d7a816f 100644
--- a/apps/files_versions/l10n/uk.json
+++ b/apps/files_versions/l10n/uk.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Не вдалося відновити: %s",
"Versions" : "Версії",
"Failed to revert {file} to revision {timestamp}." : "Не вдалося повернути {file} до ревізії {timestamp}.",
- "More versions..." : "Більше версій ...",
+ "Restore" : "Відновити",
"No other versions available" : "Інші версії недоступні",
- "Restore" : "Відновити"
+ "More versions..." : "Більше версій ..."
},"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/vi.js b/apps/files_versions/l10n/vi.js
index 08f6c9bb25e..2d06f12d8c1 100644
--- a/apps/files_versions/l10n/vi.js
+++ b/apps/files_versions/l10n/vi.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "Không thể khôi phục: %s",
"Versions" : "Phiên bản",
"Failed to revert {file} to revision {timestamp}." : "Thất bại khi trở lại {file} khi sử đổi {timestamp}.",
- "More versions..." : "Nhiều phiên bản ...",
+ "Restore" : "Khôi phục",
"No other versions available" : "Không có các phiên bản khác có sẵn",
- "Restore" : "Khôi phục"
+ "More versions..." : "Nhiều phiên bản ..."
},
"nplurals=1; plural=0;");
diff --git a/apps/files_versions/l10n/vi.json b/apps/files_versions/l10n/vi.json
index 21b8a964fe0..e126e6e2d53 100644
--- a/apps/files_versions/l10n/vi.json
+++ b/apps/files_versions/l10n/vi.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "Không thể khôi phục: %s",
"Versions" : "Phiên bản",
"Failed to revert {file} to revision {timestamp}." : "Thất bại khi trở lại {file} khi sử đổi {timestamp}.",
- "More versions..." : "Nhiều phiên bản ...",
+ "Restore" : "Khôi phục",
"No other versions available" : "Không có các phiên bản khác có sẵn",
- "Restore" : "Khôi phục"
+ "More versions..." : "Nhiều phiên bản ..."
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/zh_CN.js b/apps/files_versions/l10n/zh_CN.js
index 8c1ca7ad3ee..b94ec419d23 100644
--- a/apps/files_versions/l10n/zh_CN.js
+++ b/apps/files_versions/l10n/zh_CN.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "无法恢复: %s",
"Versions" : "版本",
"Failed to revert {file} to revision {timestamp}." : "无法恢复 {file} 到 {timestamp} 的版本。",
- "More versions..." : "更多版本...",
+ "Restore" : "恢复",
"No other versions available" : "无其他版本可用",
- "Restore" : "恢复"
+ "More versions..." : "更多版本..."
},
"nplurals=1; plural=0;");
diff --git a/apps/files_versions/l10n/zh_CN.json b/apps/files_versions/l10n/zh_CN.json
index 4ffb09503b0..80f8624f9dd 100644
--- a/apps/files_versions/l10n/zh_CN.json
+++ b/apps/files_versions/l10n/zh_CN.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "无法恢复: %s",
"Versions" : "版本",
"Failed to revert {file} to revision {timestamp}." : "无法恢复 {file} 到 {timestamp} 的版本。",
- "More versions..." : "更多版本...",
+ "Restore" : "恢复",
"No other versions available" : "无其他版本可用",
- "Restore" : "恢复"
+ "More versions..." : "更多版本..."
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/apps/files_versions/l10n/zh_TW.js b/apps/files_versions/l10n/zh_TW.js
index 8094658394e..72f086ff446 100644
--- a/apps/files_versions/l10n/zh_TW.js
+++ b/apps/files_versions/l10n/zh_TW.js
@@ -4,8 +4,8 @@ OC.L10N.register(
"Could not revert: %s" : "無法還原:%s",
"Versions" : "版本",
"Failed to revert {file} to revision {timestamp}." : "無法還原檔案 {file} 至版本 {timestamp}",
- "More versions..." : "更多版本…",
+ "Restore" : "復原",
"No other versions available" : "沒有其他版本了",
- "Restore" : "復原"
+ "More versions..." : "更多版本…"
},
"nplurals=1; plural=0;");
diff --git a/apps/files_versions/l10n/zh_TW.json b/apps/files_versions/l10n/zh_TW.json
index 0766f66976f..37506095c20 100644
--- a/apps/files_versions/l10n/zh_TW.json
+++ b/apps/files_versions/l10n/zh_TW.json
@@ -2,8 +2,8 @@
"Could not revert: %s" : "無法還原:%s",
"Versions" : "版本",
"Failed to revert {file} to revision {timestamp}." : "無法還原檔案 {file} 至版本 {timestamp}",
- "More versions..." : "更多版本…",
+ "Restore" : "復原",
"No other versions available" : "沒有其他版本了",
- "Restore" : "復原"
+ "More versions..." : "更多版本…"
},"pluralForm" :"nplurals=1; plural=0;"
} \ No newline at end of file
diff --git a/apps/files_versions/lib/backgroundjob/expireversions.php b/apps/files_versions/lib/backgroundjob/expireversions.php
new file mode 100644
index 00000000000..afdd5eed57a
--- /dev/null
+++ b/apps/files_versions/lib/backgroundjob/expireversions.php
@@ -0,0 +1,98 @@
+<?php
+/**
+ * @author Victor Dubiniuk <dubiniuk@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCA\Files_Versions\BackgroundJob;
+
+use OCP\IUserManager;
+use OCA\Files_Versions\AppInfo\Application;
+use OCA\Files_Versions\Storage;
+use OCA\Files_Versions\Expiration;
+
+class ExpireVersions extends \OC\BackgroundJob\TimedJob {
+
+ const ITEMS_PER_SESSION = 1000;
+
+ /**
+ * @var Expiration
+ */
+ private $expiration;
+
+ /**
+ * @var IUserManager
+ */
+ private $userManager;
+
+ public function __construct(IUserManager $userManager = null, Expiration $expiration = null) {
+ // Run once per 30 minutes
+ $this->setInterval(60 * 30);
+
+ if (is_null($expiration) || is_null($userManager)) {
+ $this->fixDIForJobs();
+ } else {
+ $this->expiration = $expiration;
+ $this->userManager = $userManager;
+ }
+ }
+
+ protected function fixDIForJobs() {
+ $application = new Application();
+ $this->expiration = $application->getContainer()->query('Expiration');
+ $this->userManager = \OC::$server->getUserManager();
+ }
+
+ protected function run($argument) {
+ $maxAge = $this->expiration->getMaxAgeAsTimestamp();
+ if (!$maxAge) {
+ return;
+ }
+
+ $users = $this->userManager->search('');
+ $isFSready = false;
+ foreach ($users as $user) {
+ $uid = $user->getUID();
+ if (!$isFSready) {
+ if (!$this->setupFS($uid)) {
+ continue;
+ }
+ $isFSready = true;
+ }
+ Storage::expireOlderThanMaxForUser($uid);
+ }
+
+ \OC_Util::tearDownFS();
+ }
+
+ /**
+ * Act on behalf on trash item owner
+ * @param string $user
+ * @return boolean
+ */
+ private function setupFS($user){
+ if (!$this->userManager->userExists($user)) {
+ return false;
+ }
+
+ \OC_Util::tearDownFS();
+ \OC_Util::setupFS($user);
+
+ return true;
+ }
+}
diff --git a/apps/files_versions/lib/expiration.php b/apps/files_versions/lib/expiration.php
new file mode 100644
index 00000000000..fba705251e9
--- /dev/null
+++ b/apps/files_versions/lib/expiration.php
@@ -0,0 +1,198 @@
+<?php
+/**
+ * @author Victor Dubiniuk <dubiniuk@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCA\Files_Versions;
+
+use \OCP\IConfig;
+use \OCP\AppFramework\Utility\ITimeFactory;
+
+class Expiration {
+
+ // how long do we keep files a version if no other value is defined in the config file (unit: days)
+ const NO_OBLIGATION = -1;
+
+ /** @var ITimeFactory */
+ private $timeFactory;
+
+ /** @var string */
+ private $retentionObligation;
+
+ /** @var int */
+ private $minAge;
+
+ /** @var int */
+ private $maxAge;
+
+ /** @var bool */
+ private $canPurgeToSaveSpace;
+
+ public function __construct(IConfig $config,ITimeFactory $timeFactory){
+ $this->timeFactory = $timeFactory;
+ $this->retentionObligation = $config->getSystemValue('versions_retention_obligation', 'auto');
+
+ if ($this->retentionObligation !== 'disabled') {
+ $this->parseRetentionObligation();
+ }
+ }
+
+ /**
+ * Is versions expiration enabled
+ * @return bool
+ */
+ public function isEnabled(){
+ return $this->retentionObligation !== 'disabled';
+ }
+
+ /**
+ * Is default expiration active
+ */
+ public function shouldAutoExpire(){
+ return $this->minAge === self::NO_OBLIGATION
+ || $this->maxAge === self::NO_OBLIGATION;
+ }
+
+ /**
+ * Check if given timestamp in expiration range
+ * @param int $timestamp
+ * @param bool $quotaExceeded
+ * @return bool
+ */
+ public function isExpired($timestamp, $quotaExceeded = false){
+ // No expiration if disabled
+ if (!$this->isEnabled()) {
+ return false;
+ }
+
+ // Purge to save space (if allowed)
+ if ($quotaExceeded && $this->canPurgeToSaveSpace) {
+ return true;
+ }
+
+ $time = $this->timeFactory->getTime();
+ // Never expire dates in future e.g. misconfiguration or negative time
+ // adjustment
+ if ($time<$timestamp) {
+ return false;
+ }
+
+ // Purge as too old
+ if ($this->maxAge !== self::NO_OBLIGATION) {
+ $maxTimestamp = $time - ($this->maxAge * 86400);
+ $isOlderThanMax = $timestamp < $maxTimestamp;
+ } else {
+ $isOlderThanMax = false;
+ }
+
+ if ($this->minAge !== self::NO_OBLIGATION) {
+ // older than Min obligation and we are running out of quota?
+ $minTimestamp = $time - ($this->minAge * 86400);
+ $isMinReached = ($timestamp < $minTimestamp) && $quotaExceeded;
+ } else {
+ $isMinReached = false;
+ }
+
+ return $isOlderThanMax || $isMinReached;
+ }
+
+ /**
+ * Get maximal retention obligation as a timestamp
+ * @return int
+ */
+ public function getMaxAgeAsTimestamp(){
+ $maxAge = false;
+ if ($this->isEnabled() && $this->maxAge !== self::NO_OBLIGATION) {
+ $time = $this->timeFactory->getTime();
+ $maxAge = $time - ($this->maxAge * 86400);
+ }
+ return $maxAge;
+ }
+
+ /**
+ * Read versions_retention_obligation, validate it
+ * and set private members accordingly
+ */
+ private function parseRetentionObligation(){
+ $splitValues = explode(',', $this->retentionObligation);
+ if (!isset($splitValues[0])) {
+ $minValue = 'auto';
+ } else {
+ $minValue = trim($splitValues[0]);
+ }
+
+ if (!isset($splitValues[1])) {
+ $maxValue = self::NO_OBLIGATION;
+ } else {
+ $maxValue = trim($splitValues[1]);
+ }
+
+ $isValid = true;
+ // Validate
+ if (!ctype_digit($minValue) && $minValue !== 'auto') {
+ $isValid = false;
+ \OC::$server->getLogger()->warning(
+ $minValue . ' is not a valid value for minimal versions retention obligation. Check versions_retention_obligation in your config.php. Falling back to auto.',
+ ['app'=>'files_versions']
+ );
+ }
+
+ if (!ctype_digit($maxValue) && $maxValue !== 'auto') {
+ $isValid = false;
+ \OC::$server->getLogger()->warning(
+ $maxValue . ' is not a valid value for maximal versions retention obligation. Check versions_retention_obligation in your config.php. Falling back to auto.',
+ ['app'=>'files_versions']
+ );
+ }
+
+ if (!$isValid){
+ $minValue = 'auto';
+ $maxValue = 'auto';
+ }
+
+
+ if ($minValue === 'auto' && $maxValue === 'auto') {
+ // Default: Delete anytime if space needed
+ $this->minAge = self::NO_OBLIGATION;
+ $this->maxAge = self::NO_OBLIGATION;
+ $this->canPurgeToSaveSpace = true;
+ } elseif ($minValue !== 'auto' && $maxValue === 'auto') {
+ // Keep for X days but delete anytime if space needed
+ $this->minAge = intval($minValue);
+ $this->maxAge = self::NO_OBLIGATION;
+ $this->canPurgeToSaveSpace = true;
+ } elseif ($minValue === 'auto' && $maxValue !== 'auto') {
+ // Delete anytime if space needed, Delete all older than max automatically
+ $this->minAge = self::NO_OBLIGATION;
+ $this->maxAge = intval($maxValue);
+ $this->canPurgeToSaveSpace = true;
+ } elseif ($minValue !== 'auto' && $maxValue !== 'auto') {
+ // Delete all older than max OR older than min if space needed
+
+ // Max < Min as per https://github.com/owncloud/core/issues/16301
+ if ($maxValue < $minValue) {
+ $maxValue = $minValue;
+ }
+
+ $this->minAge = intval($minValue);
+ $this->maxAge = intval($maxValue);
+ $this->canPurgeToSaveSpace = false;
+ }
+ }
+}
diff --git a/apps/files_versions/lib/storage.php b/apps/files_versions/lib/storage.php
index e0034f6165f..6aa58c55e9b 100644
--- a/apps/files_versions/lib/storage.php
+++ b/apps/files_versions/lib/storage.php
@@ -40,6 +40,7 @@
namespace OCA\Files_Versions;
+use OCA\Files_Versions\AppInfo\Application;
use OCA\Files_Versions\Command\Expire;
class Storage {
@@ -67,6 +68,9 @@ class Storage {
//until the end one version per week
6 => array('intervalEndsAfter' => -1, 'step' => 604800),
);
+
+ /** @var \OCA\Files_Versions\AppInfo\Application */
+ private static $application;
public static function getUidAndFilename($filename) {
$uid = \OC\Files\Filesystem::getOwner($filename);
@@ -400,6 +404,38 @@ class Storage {
}
/**
+ * Expire versions that older than max version retention time
+ * @param string $uid
+ */
+ public static function expireOlderThanMaxForUser($uid){
+ $expiration = self::getExpiration();
+ $threshold = $expiration->getMaxAgeAsTimestamp();
+ $versions = self::getAllVersions($uid);
+ if (!$threshold || !array_key_exists('all', $versions)) {
+ return;
+ }
+
+ $toDelete = [];
+ foreach (array_reverse($versions['all']) as $key => $version) {
+ if (intval($version['version'])<$threshold) {
+ $toDelete[$key] = $version;
+ } else {
+ //Versions are sorted by time - nothing mo to iterate.
+ break;
+ }
+ }
+
+ $view = new \OC\Files\View('/' . $uid . '/files_versions');
+ if (!empty($toDelete)) {
+ foreach ($toDelete as $version) {
+ \OC_Hook::emit('\OCP\Versions', 'preDelete', array('path' => $version['path'].'.v'.$version['version']));
+ self::deleteVersion($view, $version['path'] . '.v' . $version['version']);
+ \OC_Hook::emit('\OCP\Versions', 'delete', array('path' => $version['path'].'.v'.$version['version']));
+ }
+ }
+ }
+
+ /**
* translate a timestamp into a string like "5 days ago"
* @param int $timestamp
* @return string for example "5 days ago"
@@ -479,10 +515,36 @@ class Storage {
* get list of files we want to expire
* @param array $versions list of versions
* @param integer $time
+ * @param bool $quotaExceeded is versions storage limit reached
* @return array containing the list of to deleted versions and the size of them
*/
- protected static function getExpireList($time, $versions) {
+ protected static function getExpireList($time, $versions, $quotaExceeded = false) {
+ $expiration = self::getExpiration();
+
+ if ($expiration->shouldAutoExpire()) {
+ list($toDelete, $size) = self::getAutoExpireList($time, $versions);
+ } else {
+ $size = 0;
+ $toDelete = []; // versions we want to delete
+ }
+
+ foreach ($versions as $key => $version) {
+ if ($expiration->isExpired($version['version'], $quotaExceeded) && !isset($toDelete[$key])) {
+ $size += $version['size'];
+ $toDelete[$key] = $version['path'] . '.v' . $version['version'];
+ }
+ }
+
+ return [$toDelete, $size];
+ }
+ /**
+ * get list of files we want to expire
+ * @param array $versions list of versions
+ * @param integer $time
+ * @return array containing the list of to deleted versions and the size of them
+ */
+ protected static function getAutoExpireList($time, $versions) {
$size = 0;
$toDelete = array(); // versions we want to delete
@@ -529,7 +591,6 @@ class Storage {
}
return array($toDelete, $size);
-
}
/**
@@ -541,8 +602,12 @@ class Storage {
* @param int $neededSpace requested versions size
*/
private static function scheduleExpire($uid, $fileName, $versionsSize = null, $neededSpace = 0) {
- $command = new Expire($uid, $fileName, $versionsSize, $neededSpace);
- \OC::$server->getCommandBus()->push($command);
+ // let the admin disable auto expire
+ $expiration = self::getExpiration();
+ if ($expiration->isEnabled()) {
+ $command = new Expire($uid, $fileName, $versionsSize, $neededSpace);
+ \OC::$server->getCommandBus()->push($command);
+ }
}
/**
@@ -555,7 +620,9 @@ class Storage {
*/
public static function expire($filename, $versionsSize = null, $offset = 0) {
$config = \OC::$server->getConfig();
- if($config->getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
+ $expiration = self::getExpiration();
+
+ if($config->getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true' && $expiration->isEnabled()) {
list($uid, $filename) = self::getUidAndFilename($filename);
if (empty($filename)) {
// file maybe renamed or deleted
@@ -599,7 +666,7 @@ class Storage {
$allVersions = Storage::getVersions($uid, $filename);
$time = time();
- list($toDelete, $sizeOfDeletedVersions) = self::getExpireList($time, $allVersions);
+ list($toDelete, $sizeOfDeletedVersions) = self::getExpireList($time, $allVersions, $availableSpace <= 0);
$availableSpace = $availableSpace + $sizeOfDeletedVersions;
$versionsSize = $versionsSize - $sizeOfDeletedVersions;
@@ -610,7 +677,7 @@ class Storage {
$allVersions = $result['all'];
foreach ($result['by_file'] as $versions) {
- list($toDeleteNew, $size) = self::getExpireList($time, $versions);
+ list($toDeleteNew, $size) = self::getExpireList($time, $versions, $availableSpace <= 0);
$toDelete = array_merge($toDelete, $toDeleteNew);
$sizeOfDeletedVersions += $size;
}
@@ -672,4 +739,15 @@ class Storage {
}
}
+ /**
+ * Static workaround
+ * @return Expiration
+ */
+ protected static function getExpiration(){
+ if (is_null(self::$application)) {
+ self::$application = new Application();
+ }
+ return self::$application->getContainer()->query('Expiration');
+ }
+
}
diff --git a/apps/files_versions/tests/expirationtest.php b/apps/files_versions/tests/expirationtest.php
new file mode 100644
index 00000000000..54024b85b78
--- /dev/null
+++ b/apps/files_versions/tests/expirationtest.php
@@ -0,0 +1,204 @@
+<?php
+/**
+ * @author Victor Dubiniuk <dubiniuk@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCA\Files_Versions\Tests;
+
+use \OCA\Files_Versions\Expiration;
+
+class Expiration_Test extends \Test\TestCase {
+ const SECONDS_PER_DAY = 86400; //60*60*24
+
+ public function expirationData(){
+ $today = 100*self::SECONDS_PER_DAY;
+ $back10Days = (100-10)*self::SECONDS_PER_DAY;
+ $back20Days = (100-20)*self::SECONDS_PER_DAY;
+ $back30Days = (100-30)*self::SECONDS_PER_DAY;
+ $back35Days = (100-35)*self::SECONDS_PER_DAY;
+
+ // it should never happen, but who knows :/
+ $ahead100Days = (100+100)*self::SECONDS_PER_DAY;
+
+ return [
+ // Expiration is disabled - always should return false
+ [ 'disabled', $today, $back10Days, false, false],
+ [ 'disabled', $today, $back10Days, true, false],
+ [ 'disabled', $today, $ahead100Days, true, false],
+
+ // Default: expire in 30 days or earlier when quota requirements are met
+ [ 'auto', $today, $back10Days, false, false],
+ [ 'auto', $today, $back35Days, false, false],
+ [ 'auto', $today, $back10Days, true, true],
+ [ 'auto', $today, $back35Days, true, true],
+ [ 'auto', $today, $ahead100Days, true, true],
+
+ // The same with 'auto'
+ [ 'auto, auto', $today, $back10Days, false, false],
+ [ 'auto, auto', $today, $back35Days, false, false],
+ [ 'auto, auto', $today, $back10Days, true, true],
+ [ 'auto, auto', $today, $back35Days, true, true],
+
+ // Keep for 15 days but expire anytime if space needed
+ [ '15, auto', $today, $back10Days, false, false],
+ [ '15, auto', $today, $back20Days, false, false],
+ [ '15, auto', $today, $back10Days, true, true],
+ [ '15, auto', $today, $back20Days, true, true],
+ [ '15, auto', $today, $ahead100Days, true, true],
+
+ // Expire anytime if space needed, Expire all older than max
+ [ 'auto, 15', $today, $back10Days, false, false],
+ [ 'auto, 15', $today, $back20Days, false, true],
+ [ 'auto, 15', $today, $back10Days, true, true],
+ [ 'auto, 15', $today, $back20Days, true, true],
+ [ 'auto, 15', $today, $ahead100Days, true, true],
+
+ // Expire all older than max OR older than min if space needed
+ [ '15, 25', $today, $back10Days, false, false],
+ [ '15, 25', $today, $back20Days, false, false],
+ [ '15, 25', $today, $back30Days, false, true],
+ [ '15, 25', $today, $back10Days, false, false],
+ [ '15, 25', $today, $back20Days, true, true],
+ [ '15, 25', $today, $back30Days, true, true],
+ [ '15, 25', $today, $ahead100Days, true, false],
+
+ // Expire all older than max OR older than min if space needed
+ // Max<Min case
+ [ '25, 15', $today, $back10Days, false, false],
+ [ '25, 15', $today, $back20Days, false, false],
+ [ '25, 15', $today, $back30Days, false, true],
+ [ '25, 15', $today, $back10Days, false, false],
+ [ '25, 15', $today, $back20Days, true, false],
+ [ '25, 15', $today, $back30Days, true, true],
+ [ '25, 15', $today, $ahead100Days, true, false],
+ ];
+ }
+
+ /**
+ * @dataProvider expirationData
+ *
+ * @param string $retentionObligation
+ * @param int $timeNow
+ * @param int $timestamp
+ * @param bool $quotaExceeded
+ * @param string $expectedResult
+ */
+ public function testExpiration($retentionObligation, $timeNow, $timestamp, $quotaExceeded, $expectedResult){
+ $mockedConfig = $this->getMockedConfig($retentionObligation);
+ $mockedTimeFactory = $this->getMockedTimeFactory($timeNow);
+
+ $expiration = new Expiration($mockedConfig, $mockedTimeFactory);
+ $actualResult = $expiration->isExpired($timestamp, $quotaExceeded);
+
+ $this->assertEquals($expectedResult, $actualResult);
+ }
+
+
+ public function configData(){
+ return [
+ [ 'disabled', null, null, null],
+ [ 'auto', Expiration::NO_OBLIGATION, Expiration::NO_OBLIGATION, true ],
+ [ 'auto,auto', Expiration::NO_OBLIGATION, Expiration::NO_OBLIGATION, true ],
+ [ 'auto, auto', Expiration::NO_OBLIGATION, Expiration::NO_OBLIGATION, true ],
+ [ 'auto, 3', Expiration::NO_OBLIGATION, 3, true ],
+ [ '5, auto', 5, Expiration::NO_OBLIGATION, true ],
+ [ '3, 5', 3, 5, false ],
+ [ '10, 3', 10, 10, false ],
+ [ 'g,a,r,b,a,g,e', Expiration::NO_OBLIGATION, Expiration::NO_OBLIGATION, true ],
+ [ '-3,8', Expiration::NO_OBLIGATION, Expiration::NO_OBLIGATION, true ]
+ ];
+ }
+
+
+ /**
+ * @dataProvider configData
+ *
+ * @param string $configValue
+ * @param int $expectedMinAge
+ * @param int $expectedMaxAge
+ * @param bool $expectedCanPurgeToSaveSpace
+ */
+ public function testParseRetentionObligation($configValue, $expectedMinAge, $expectedMaxAge, $expectedCanPurgeToSaveSpace){
+ $mockedConfig = $this->getMockedConfig($configValue);
+ $mockedTimeFactory = $this->getMockedTimeFactory(
+ time()
+ );
+
+ $expiration = new Expiration($mockedConfig, $mockedTimeFactory);
+ $this->assertAttributeEquals($expectedMinAge, 'minAge', $expiration);
+ $this->assertAttributeEquals($expectedMaxAge, 'maxAge', $expiration);
+ $this->assertAttributeEquals($expectedCanPurgeToSaveSpace, 'canPurgeToSaveSpace', $expiration);
+ }
+
+ /**
+ *
+ * @param int $time
+ * @return \OCP\AppFramework\Utility\ITimeFactory
+ */
+ private function getMockedTimeFactory($time){
+ $mockedTimeFactory = $this->getMockBuilder('\OCP\AppFramework\Utility\ITimeFactory')
+ ->disableOriginalConstructor()
+ ->setMethods(['getTime'])
+ ->getMock()
+ ;
+ $mockedTimeFactory->expects($this->any())->method('getTime')->will(
+ $this->returnValue($time)
+ );
+
+ return $mockedTimeFactory;
+ }
+
+ /**
+ *
+ * @param string $returnValue
+ * @return \OCP\IConfig
+ */
+ private function getMockedConfig($returnValue){
+ $mockedConfig = $this->getMockBuilder('\OCP\IConfig')
+ ->disableOriginalConstructor()
+ ->setMethods(
+ [
+ 'setSystemValues',
+ 'setSystemValue',
+ 'getSystemValue',
+ 'deleteSystemValue',
+ 'getAppKeys',
+ 'setAppValue',
+ 'getAppValue',
+ 'deleteAppValue',
+ 'deleteAppValues',
+ 'setUserValue',
+ 'getUserValue',
+ 'getUserValueForUsers',
+ 'getUserKeys',
+ 'deleteUserValue',
+ 'deleteAllUserValues',
+ 'deleteAppFromAllUsers',
+ 'getUsersForUserValue'
+ ]
+ )
+ ->getMock()
+ ;
+ $mockedConfig->expects($this->any())->method('getSystemValue')->will(
+ $this->returnValue($returnValue)
+ );
+
+ return $mockedConfig;
+ }
+}
diff --git a/apps/user_ldap/l10n/da.js b/apps/user_ldap/l10n/da.js
index 2f664ee6c21..7b9222d3abd 100644
--- a/apps/user_ldap/l10n/da.js
+++ b/apps/user_ldap/l10n/da.js
@@ -29,8 +29,8 @@ OC.L10N.register(
"An error occurred. Please check the Base DN, as well as connection settings and credentials." : "Der opstod en fejl. Tjek venligst Base DN, såvel som forbindelsesindstillingerne og brugeroplysningerne.",
"Do you really want to delete the current Server Configuration?" : "Ønsker du virkelig at slette den nuværende Server Konfiguration?",
"Confirm Deletion" : "Bekræft sletning",
- "Mappings cleared successfully!" : "Kortlægningerne blev ryddet af vejen!",
- "Error while clearing the mappings." : "Fejl under rydning af kortlægninger.",
+ "Mappings cleared successfully!" : "Tilknytningerne blev ryddet af vejen!",
+ "Error while clearing the mappings." : "Fejl under rydning af tilknytninger.",
"Anonymous bind is not allowed. Please provide a User DN and Password." : "Anonyme bindinger tillades ikke. Angiv venligst et User DN og adgangskode.",
"LDAP Operations error. Anonymous bind might not be allowed." : "LDAP-driftsfejl. Anonyme bindinger tillades muligvis ikke.",
"Saving failed. Please make sure the database is in Operation. Reload before continuing." : "Lagringen mislykkedes. Sørg venligst for at databasen er i drift. Genindlæs for der fortsættes.",
@@ -39,7 +39,7 @@ OC.L10N.register(
"Select attributes" : "Vælg attributter",
"User not found. Please check your login attributes and username. Effective filter (to copy-and-paste for command line validation): <br/>" : "Bruger blev ikke fundet. Tjek venligst dine login-attributter og brugernavnet. Gældende filter (til kopiér-og-indsæt for validering via kommandolinje): <br/>",
"User found and settings verified." : "Bruger blev fundetog indstillingerne bekræftet.",
- "Settings verified, but one user found. Only the first will be able to login. Consider a more narrow filter." : "Indstillingerne blev verificieret, men én bruger blev fundet. Det er blot den første, der vil kunne logge ind. Overvej et mere begrænset filter.",
+ "Settings verified, but one user found. Only the first will be able to login. Consider a more narrow filter." : "Indstillingerne blev verificieret, men én bruger blev fundet. Kun den første, vil kunne logge ind. Overvej et mere begrænset filter.",
"An unspecified error occurred. Please check the settings and the log." : "Der opstod en uspecificeret fejl. Tjek venligst indstillingerne og loggen.",
"The search filter is invalid, probably due to syntax issues like uneven number of opened and closed brackets. Please revise." : "Søgefilteret er ugyldigt - sandsynligvis på grund af problemer med syntaksen, såsom et ulige antal åbne og lukkede parenteser. Gennemse venligst. ",
"A connection error to LDAP / AD occurred, please check host, port and credentials." : "Der opstod en forbindelsesfejl til LDAP/AD - tjek venligst vært, port og brugeroplysninger.",
@@ -75,11 +75,11 @@ OC.L10N.register(
"Other Attributes:" : "Andre attributter:",
"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" : "Definerer dét filter der anvendes, når der er forsøg på at logge ind. %%uuid erstattter brugernavnet i login-handlingen. Eksempel: \"uid=%%uuid\"",
"Test Loginname" : "Test loginnavn",
- "Verify settings" : "Verificér indstillinger",
+ "Verify settings" : "Kontrollér indstillinger",
"1. Server" : "1. server",
"%s. Server:" : "%s. server:",
"Add a new and blank configuration" : "Tilføj en ny og tom konfiguration",
- "Copy current configuration into new directory binding" : "Kopiér nuværende konfiguration ind i en ny mappetildeling",
+ "Copy current configuration into new directory binding" : "Kopiér nuværende konfiguration ind i en ny mappetilknytning",
"Delete the current configuration" : "Slet den aktuelle konfiguration",
"Host" : "Vært",
"You can omit the protocol, except you require SSL. Then start with ldaps://" : "Du kan udelade protokollen, medmindre du skal bruge SSL. Start i så fald med ldaps://",
@@ -98,7 +98,7 @@ OC.L10N.register(
"Limit %s access to users meeting these criteria:" : "Begræns %s-adgangen til brugere som imødekommer disse kriterier:",
"The most common object classes for users are organizationalPerson, person, user, and inetOrgPerson. If you are not sure which object class to select, please consult your directory admin." : "De fleste gængse objektklasser for brugere er organizationalPerson, person, user og inetOrgPerson. Hvis du ikker er sikker på hvilken objektklasse, der skal vælges, så tal med administratoren af dit katalog.",
"The filter specifies which LDAP users shall have access to the %s instance." : "Filteret angiver hvilke LDAP-brugere, der skal have adgang til %s-instansen.",
- "Verify settings and count users" : "Verificér indstillinger og optalte brugere",
+ "Verify settings and count users" : "Kontrollér indstillinger og optalte brugere",
"Saving" : "Gemmer",
"Back" : "Tilbage",
"Continue" : "Videre",
diff --git a/apps/user_ldap/l10n/da.json b/apps/user_ldap/l10n/da.json
index 5de47b4abcb..5c0c3ad1d0c 100644
--- a/apps/user_ldap/l10n/da.json
+++ b/apps/user_ldap/l10n/da.json
@@ -27,8 +27,8 @@
"An error occurred. Please check the Base DN, as well as connection settings and credentials." : "Der opstod en fejl. Tjek venligst Base DN, såvel som forbindelsesindstillingerne og brugeroplysningerne.",
"Do you really want to delete the current Server Configuration?" : "Ønsker du virkelig at slette den nuværende Server Konfiguration?",
"Confirm Deletion" : "Bekræft sletning",
- "Mappings cleared successfully!" : "Kortlægningerne blev ryddet af vejen!",
- "Error while clearing the mappings." : "Fejl under rydning af kortlægninger.",
+ "Mappings cleared successfully!" : "Tilknytningerne blev ryddet af vejen!",
+ "Error while clearing the mappings." : "Fejl under rydning af tilknytninger.",
"Anonymous bind is not allowed. Please provide a User DN and Password." : "Anonyme bindinger tillades ikke. Angiv venligst et User DN og adgangskode.",
"LDAP Operations error. Anonymous bind might not be allowed." : "LDAP-driftsfejl. Anonyme bindinger tillades muligvis ikke.",
"Saving failed. Please make sure the database is in Operation. Reload before continuing." : "Lagringen mislykkedes. Sørg venligst for at databasen er i drift. Genindlæs for der fortsættes.",
@@ -37,7 +37,7 @@
"Select attributes" : "Vælg attributter",
"User not found. Please check your login attributes and username. Effective filter (to copy-and-paste for command line validation): <br/>" : "Bruger blev ikke fundet. Tjek venligst dine login-attributter og brugernavnet. Gældende filter (til kopiér-og-indsæt for validering via kommandolinje): <br/>",
"User found and settings verified." : "Bruger blev fundetog indstillingerne bekræftet.",
- "Settings verified, but one user found. Only the first will be able to login. Consider a more narrow filter." : "Indstillingerne blev verificieret, men én bruger blev fundet. Det er blot den første, der vil kunne logge ind. Overvej et mere begrænset filter.",
+ "Settings verified, but one user found. Only the first will be able to login. Consider a more narrow filter." : "Indstillingerne blev verificieret, men én bruger blev fundet. Kun den første, vil kunne logge ind. Overvej et mere begrænset filter.",
"An unspecified error occurred. Please check the settings and the log." : "Der opstod en uspecificeret fejl. Tjek venligst indstillingerne og loggen.",
"The search filter is invalid, probably due to syntax issues like uneven number of opened and closed brackets. Please revise." : "Søgefilteret er ugyldigt - sandsynligvis på grund af problemer med syntaksen, såsom et ulige antal åbne og lukkede parenteser. Gennemse venligst. ",
"A connection error to LDAP / AD occurred, please check host, port and credentials." : "Der opstod en forbindelsesfejl til LDAP/AD - tjek venligst vært, port og brugeroplysninger.",
@@ -73,11 +73,11 @@
"Other Attributes:" : "Andre attributter:",
"Defines the filter to apply, when login is attempted. %%uid replaces the username in the login action. Example: \"uid=%%uid\"" : "Definerer dét filter der anvendes, når der er forsøg på at logge ind. %%uuid erstattter brugernavnet i login-handlingen. Eksempel: \"uid=%%uuid\"",
"Test Loginname" : "Test loginnavn",
- "Verify settings" : "Verificér indstillinger",
+ "Verify settings" : "Kontrollér indstillinger",
"1. Server" : "1. server",
"%s. Server:" : "%s. server:",
"Add a new and blank configuration" : "Tilføj en ny og tom konfiguration",
- "Copy current configuration into new directory binding" : "Kopiér nuværende konfiguration ind i en ny mappetildeling",
+ "Copy current configuration into new directory binding" : "Kopiér nuværende konfiguration ind i en ny mappetilknytning",
"Delete the current configuration" : "Slet den aktuelle konfiguration",
"Host" : "Vært",
"You can omit the protocol, except you require SSL. Then start with ldaps://" : "Du kan udelade protokollen, medmindre du skal bruge SSL. Start i så fald med ldaps://",
@@ -96,7 +96,7 @@
"Limit %s access to users meeting these criteria:" : "Begræns %s-adgangen til brugere som imødekommer disse kriterier:",
"The most common object classes for users are organizationalPerson, person, user, and inetOrgPerson. If you are not sure which object class to select, please consult your directory admin." : "De fleste gængse objektklasser for brugere er organizationalPerson, person, user og inetOrgPerson. Hvis du ikker er sikker på hvilken objektklasse, der skal vælges, så tal med administratoren af dit katalog.",
"The filter specifies which LDAP users shall have access to the %s instance." : "Filteret angiver hvilke LDAP-brugere, der skal have adgang til %s-instansen.",
- "Verify settings and count users" : "Verificér indstillinger og optalte brugere",
+ "Verify settings and count users" : "Kontrollér indstillinger og optalte brugere",
"Saving" : "Gemmer",
"Back" : "Tilbage",
"Continue" : "Videre",