summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/dav/lib/Upload/UploadHome.php3
-rw-r--r--apps/files/js/file-upload.js14
-rw-r--r--apps/files/js/filelist.js2
-rw-r--r--apps/files/js/mainfileinfodetailview.js9
-rw-r--r--apps/files/l10n/en_GB.js3
-rw-r--r--apps/files/l10n/en_GB.json3
-rw-r--r--apps/files/l10n/es.js3
-rw-r--r--apps/files/l10n/es.json3
-rw-r--r--apps/files/l10n/fr.js2
-rw-r--r--apps/files/l10n/fr.json2
-rw-r--r--apps/files/l10n/ka_GE.js3
-rw-r--r--apps/files/l10n/ka_GE.json3
-rw-r--r--apps/files/l10n/ko.js4
-rw-r--r--apps/files/l10n/ko.json4
-rw-r--r--apps/files/l10n/nb.js2
-rw-r--r--apps/files/l10n/nb.json2
-rw-r--r--apps/files/l10n/nl.js3
-rw-r--r--apps/files/l10n/nl.json3
-rw-r--r--apps/files/l10n/ro.js129
-rw-r--r--apps/files/l10n/ro.json129
-rw-r--r--apps/files/l10n/ru.js3
-rw-r--r--apps/files/l10n/ru.json3
-rw-r--r--apps/files/l10n/tr.js3
-rw-r--r--apps/files/l10n/tr.json3
-rw-r--r--apps/files/lib/AppInfo/Application.php5
-rw-r--r--apps/files/lib/Service/TagService.php16
-rw-r--r--apps/files/tests/Service/TagServiceTest.php8
-rw-r--r--apps/files/tests/js/filelistSpec.js49
-rw-r--r--apps/files/tests/js/mainfileinfodetailviewSpec.js29
-rw-r--r--apps/files_external/l10n/de.js1
-rw-r--r--apps/files_external/l10n/de.json1
-rw-r--r--apps/files_external/l10n/de_DE.js1
-rw-r--r--apps/files_external/l10n/de_DE.json1
-rw-r--r--apps/files_external/l10n/en_GB.js1
-rw-r--r--apps/files_external/l10n/en_GB.json1
-rw-r--r--apps/files_external/l10n/es.js1
-rw-r--r--apps/files_external/l10n/es.json1
-rw-r--r--apps/files_external/l10n/hu.js1
-rw-r--r--apps/files_external/l10n/hu.json1
-rw-r--r--apps/files_external/l10n/it.js1
-rw-r--r--apps/files_external/l10n/it.json1
-rw-r--r--apps/files_external/l10n/ka_GE.js1
-rw-r--r--apps/files_external/l10n/ka_GE.json1
-rw-r--r--apps/files_external/l10n/ko.js1
-rw-r--r--apps/files_external/l10n/ko.json1
-rw-r--r--apps/files_external/l10n/nl.js1
-rw-r--r--apps/files_external/l10n/nl.json1
-rw-r--r--apps/files_external/l10n/pt_BR.js1
-rw-r--r--apps/files_external/l10n/pt_BR.json1
-rw-r--r--apps/files_external/l10n/sr.js1
-rw-r--r--apps/files_external/l10n/sr.json1
-rw-r--r--apps/files_external/l10n/tr.js1
-rw-r--r--apps/files_external/l10n/tr.json1
-rw-r--r--apps/files_sharing/l10n/ko.js12
-rw-r--r--apps/files_sharing/l10n/ko.json12
-rw-r--r--apps/files_sharing/lib/External/Mount.php10
-rw-r--r--apps/sharebymail/l10n/sv.js18
-rw-r--r--apps/sharebymail/l10n/sv.json18
-rw-r--r--apps/theming/css/theming.scss28
-rw-r--r--apps/theming/lib/Capabilities.php2
-rw-r--r--apps/theming/lib/Controller/ThemingController.php4
-rw-r--r--apps/theming/lib/ThemingDefaults.php15
-rw-r--r--apps/theming/lib/Util.php47
-rw-r--r--apps/theming/tests/CapabilitiesTest.php46
-rw-r--r--apps/theming/tests/ThemingDefaultsTest.php44
-rw-r--r--apps/theming/tests/UtilTest.php53
-rw-r--r--apps/updatenotification/js/notification.js7
-rw-r--r--apps/user_ldap/composer/composer/autoload_classmap.php2
-rw-r--r--apps/user_ldap/composer/composer/autoload_static.php2
-rw-r--r--apps/user_ldap/lib/AccessFactory.php61
-rw-r--r--apps/user_ldap/lib/ConnectionFactory.php38
-rw-r--r--apps/user_ldap/lib/Jobs/Sync.php37
-rw-r--r--apps/user_ldap/tests/Jobs/SyncTest.php225
73 files changed, 904 insertions, 246 deletions
diff --git a/apps/dav/lib/Upload/UploadHome.php b/apps/dav/lib/Upload/UploadHome.php
index 9f4ae0e8a2c..ec31e93f4f9 100644
--- a/apps/dav/lib/Upload/UploadHome.php
+++ b/apps/dav/lib/Upload/UploadHome.php
@@ -66,7 +66,8 @@ class UploadHome implements ICollection {
}
function getName() {
- return 'uploads';
+ list(,$name) = \Sabre\Uri\split($this->principalInfo['uri']);
+ return $name;
}
function setName($name) {
diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js
index 8e95abcb5e8..ad56492730e 100644
--- a/apps/files/js/file-upload.js
+++ b/apps/files/js/file-upload.js
@@ -235,7 +235,7 @@ OC.FileUpload.prototype = {
) {
data.isChunked = true;
chunkFolderPromise = this.uploader.davClient.createDirectory(
- 'uploads/' + encodeURIComponent(OC.getCurrentUser().uid) + '/' + encodeURIComponent(this.getId())
+ 'uploads/' + OC.getCurrentUser().uid + '/' + this.getId()
);
// TODO: if fails, it means same id already existed, need to retry
} else {
@@ -272,8 +272,8 @@ OC.FileUpload.prototype = {
}
return this.uploader.davClient.move(
- 'uploads/' + encodeURIComponent(uid) + '/' + encodeURIComponent(this.getId()) + '/.file',
- 'files/' + encodeURIComponent(uid) + '/' + OC.joinPaths(this.getFullPath(), this.getFileName()),
+ 'uploads/' + uid + '/' + this.getId() + '/.file',
+ 'files/' + uid + '/' + OC.joinPaths(this.getFullPath(), this.getFileName()),
true,
headers
);
@@ -282,7 +282,7 @@ OC.FileUpload.prototype = {
_deleteChunkFolder: function() {
// delete transfer directory for this upload
this.uploader.davClient.remove(
- 'uploads/' + encodeURIComponent(OC.getCurrentUser().uid) + '/' + encodeURIComponent(this.getId())
+ 'uploads/' + OC.getCurrentUser().uid + '/' + this.getId()
);
},
@@ -1166,9 +1166,9 @@ OC.Uploader.prototype = _.extend({
var chunkId = range.split('/')[0].split('-')[0];
data.url = OC.getRootPath() +
'/remote.php/dav/uploads' +
- '/' + encodeURIComponent(OC.getCurrentUser().uid) +
- '/' + encodeURIComponent(upload.getId()) +
- '/' + encodeURIComponent(chunkId);
+ '/' + OC.getCurrentUser().uid +
+ '/' + upload.getId() +
+ '/' + chunkId;
delete data.contentRange;
delete data.headers['Content-Range'];
});
diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js
index 7a4ea492752..e50b402dea8 100644
--- a/apps/files/js/filelist.js
+++ b/apps/files/js/filelist.js
@@ -2266,7 +2266,7 @@
function updateInList(fileInfo) {
self.updateRow(tr, fileInfo);
- self._updateDetailsView(fileInfo, false);
+ self._updateDetailsView(fileInfo.name, false);
}
// TODO: too many nested blocks, move parts into functions
diff --git a/apps/files/js/mainfileinfodetailview.js b/apps/files/js/mainfileinfodetailview.js
index ea3063f6176..626ab86ded3 100644
--- a/apps/files/js/mainfileinfodetailview.js
+++ b/apps/files/js/mainfileinfodetailview.js
@@ -20,9 +20,11 @@
'</a>' +
'</div>' +
' <div class="file-details ellipsis">' +
+ ' {{#if hasFavoriteAction}}' +
' <a href="#" class="action action-favorite favorite permanent">' +
' <span class="icon {{starClass}}" title="{{starAltText}}"></span>' +
' </a>' +
+ ' {{/if}}' +
' {{#if hasSize}}<span class="size" title="{{altSize}}">{{size}}</span>, {{/if}}<span class="date live-relative-timestamp" data-timestamp="{{timestamp}}" title="{{altDate}}">{{date}}</span>' +
' </div>' +
'</div>' +
@@ -175,6 +177,12 @@
if (this.model) {
var isFavorite = (this.model.get('tags') || []).indexOf(OC.TAG_FAVORITE) >= 0;
+ var availableActions = this._fileActions.get(
+ this.model.get('mimetype'),
+ this.model.get('type'),
+ this.model.get('permissions')
+ );
+ var hasFavoriteAction = 'Favorite' in availableActions;
this.$el.html(this.template({
type: this.model.isImage()? 'image': '',
nameLabel: t('files', 'Name'),
@@ -189,6 +197,7 @@
altDate: OC.Util.formatDate(this.model.get('mtime')),
timestamp: this.model.get('mtime'),
date: OC.Util.relativeModifiedDate(this.model.get('mtime')),
+ hasFavoriteAction: hasFavoriteAction,
starAltText: isFavorite ? t('files', 'Favorited') : t('files', 'Favorite'),
starClass: isFavorite ? 'icon-starred' : 'icon-star',
permalink: this._makePermalink(this.model.get('id')),
diff --git a/apps/files/l10n/en_GB.js b/apps/files/l10n/en_GB.js
index 424d470d970..21f6e339784 100644
--- a/apps/files/l10n/en_GB.js
+++ b/apps/files/l10n/en_GB.js
@@ -62,8 +62,11 @@ OC.L10N.register(
"You don’t have permission to upload or create files here" : "You don’t have permission to upload or create files here",
"_Uploading %n file_::_Uploading %n files_" : ["Uploading %n file","Uploading %n files"],
"New" : "New",
+ "{used} of {quota} used" : "{used} of {quota} used",
+ "{used} used" : "{used} used",
"\"{name}\" is an invalid file name." : "\"{name}\" is an invalid file name.",
"File name cannot be empty." : "File name cannot be empty.",
+ "\"/\" is not allowed inside a file name." : "\"/\" is not allowed inside a file name.",
"\"{name}\" is not an allowed filetype" : "\"{name}\" is not an allowed filetype",
"Storage of {owner} is full, files can not be updated or synced anymore!" : "Storage of {owner} is full, files can not be updated or synced anymore!",
"Your storage is full, files can not be updated or synced anymore!" : "Your storage is full, files can not be updated or synced anymore!",
diff --git a/apps/files/l10n/en_GB.json b/apps/files/l10n/en_GB.json
index 1ac5d53c7a6..f8ff0a553b5 100644
--- a/apps/files/l10n/en_GB.json
+++ b/apps/files/l10n/en_GB.json
@@ -60,8 +60,11 @@
"You don’t have permission to upload or create files here" : "You don’t have permission to upload or create files here",
"_Uploading %n file_::_Uploading %n files_" : ["Uploading %n file","Uploading %n files"],
"New" : "New",
+ "{used} of {quota} used" : "{used} of {quota} used",
+ "{used} used" : "{used} used",
"\"{name}\" is an invalid file name." : "\"{name}\" is an invalid file name.",
"File name cannot be empty." : "File name cannot be empty.",
+ "\"/\" is not allowed inside a file name." : "\"/\" is not allowed inside a file name.",
"\"{name}\" is not an allowed filetype" : "\"{name}\" is not an allowed filetype",
"Storage of {owner} is full, files can not be updated or synced anymore!" : "Storage of {owner} is full, files can not be updated or synced anymore!",
"Your storage is full, files can not be updated or synced anymore!" : "Your storage is full, files can not be updated or synced anymore!",
diff --git a/apps/files/l10n/es.js b/apps/files/l10n/es.js
index a4666bd7bdf..0852da86efc 100644
--- a/apps/files/l10n/es.js
+++ b/apps/files/l10n/es.js
@@ -62,8 +62,11 @@ OC.L10N.register(
"You don’t have permission to upload or create files here" : "No tiene permisos para subir o crear archivos aquí",
"_Uploading %n file_::_Uploading %n files_" : ["Subiendo %n archivo","Subiendo %n archivos"],
"New" : "Nuevo",
+ "{used} of {quota} used" : "{used} usados de {quota}",
+ "{used} used" : "{used} usados",
"\"{name}\" is an invalid file name." : "\"{name}\" es un nombre de archivo inválido.",
"File name cannot be empty." : "El nombre de archivo no puede estar vacío.",
+ "\"/\" is not allowed inside a file name." : "\"/\" no se permite dentro de un nombre de archivo.",
"\"{name}\" is not an allowed filetype" : "\"{name}\" no es un tipo de archivo permitido",
"Storage of {owner} is full, files can not be updated or synced anymore!" : "El almacén de {owner} está repleto, ¡los archivos no se actualizarán ni sincronizarán más!",
"Your storage is full, files can not be updated or synced anymore!" : "Su almacenamiento está lleno, ¡los archivos no se actualizarán ni sincronizarán más!",
diff --git a/apps/files/l10n/es.json b/apps/files/l10n/es.json
index 44db92002f2..db8baad60b3 100644
--- a/apps/files/l10n/es.json
+++ b/apps/files/l10n/es.json
@@ -60,8 +60,11 @@
"You don’t have permission to upload or create files here" : "No tiene permisos para subir o crear archivos aquí",
"_Uploading %n file_::_Uploading %n files_" : ["Subiendo %n archivo","Subiendo %n archivos"],
"New" : "Nuevo",
+ "{used} of {quota} used" : "{used} usados de {quota}",
+ "{used} used" : "{used} usados",
"\"{name}\" is an invalid file name." : "\"{name}\" es un nombre de archivo inválido.",
"File name cannot be empty." : "El nombre de archivo no puede estar vacío.",
+ "\"/\" is not allowed inside a file name." : "\"/\" no se permite dentro de un nombre de archivo.",
"\"{name}\" is not an allowed filetype" : "\"{name}\" no es un tipo de archivo permitido",
"Storage of {owner} is full, files can not be updated or synced anymore!" : "El almacén de {owner} está repleto, ¡los archivos no se actualizarán ni sincronizarán más!",
"Your storage is full, files can not be updated or synced anymore!" : "Su almacenamiento está lleno, ¡los archivos no se actualizarán ni sincronizarán más!",
diff --git a/apps/files/l10n/fr.js b/apps/files/l10n/fr.js
index b5035e6a1a3..ccce056d631 100644
--- a/apps/files/l10n/fr.js
+++ b/apps/files/l10n/fr.js
@@ -62,9 +62,11 @@ OC.L10N.register(
"You don’t have permission to upload or create files here" : "Vous n'avez pas la permission d'envoyer ou de créer des fichiers ici",
"_Uploading %n file_::_Uploading %n files_" : ["Téléversement de %n fichier","Téléversement de %n fichiers"],
"New" : "Nouveau",
+ "{used} of {quota} used" : "{used} de {quota} utilisé",
"{used} used" : "{used} utilisé",
"\"{name}\" is an invalid file name." : "\"{name}\" n'est pas un nom de fichier valide.",
"File name cannot be empty." : "Le nom de fichier ne peut être vide.",
+ "\"/\" is not allowed inside a file name." : "\"/\" n'est pas autorisé dans les noms de fichier.",
"\"{name}\" is not an allowed filetype" : "\"{name}\" n'est pas un nom de fichier autorisé.",
"Storage of {owner} is full, files can not be updated or synced anymore!" : "L'espace de stockage de {owner} est plein. Les fichiers ne peuvent plus être mis à jour ni synchronisés !",
"Your storage is full, files can not be updated or synced anymore!" : "Votre espace de stockage est plein. Les fichiers ne peuvent plus être mis à jour ni synchronisés !",
diff --git a/apps/files/l10n/fr.json b/apps/files/l10n/fr.json
index d65a471164e..d1e1320c0dc 100644
--- a/apps/files/l10n/fr.json
+++ b/apps/files/l10n/fr.json
@@ -60,9 +60,11 @@
"You don’t have permission to upload or create files here" : "Vous n'avez pas la permission d'envoyer ou de créer des fichiers ici",
"_Uploading %n file_::_Uploading %n files_" : ["Téléversement de %n fichier","Téléversement de %n fichiers"],
"New" : "Nouveau",
+ "{used} of {quota} used" : "{used} de {quota} utilisé",
"{used} used" : "{used} utilisé",
"\"{name}\" is an invalid file name." : "\"{name}\" n'est pas un nom de fichier valide.",
"File name cannot be empty." : "Le nom de fichier ne peut être vide.",
+ "\"/\" is not allowed inside a file name." : "\"/\" n'est pas autorisé dans les noms de fichier.",
"\"{name}\" is not an allowed filetype" : "\"{name}\" n'est pas un nom de fichier autorisé.",
"Storage of {owner} is full, files can not be updated or synced anymore!" : "L'espace de stockage de {owner} est plein. Les fichiers ne peuvent plus être mis à jour ni synchronisés !",
"Your storage is full, files can not be updated or synced anymore!" : "Votre espace de stockage est plein. Les fichiers ne peuvent plus être mis à jour ni synchronisés !",
diff --git a/apps/files/l10n/ka_GE.js b/apps/files/l10n/ka_GE.js
index 401b93a0e6a..b2b68baa747 100644
--- a/apps/files/l10n/ka_GE.js
+++ b/apps/files/l10n/ka_GE.js
@@ -62,8 +62,11 @@ OC.L10N.register(
"You don’t have permission to upload or create files here" : "აქ ფაილების შექმნის ან ატვირთვის უფლება არ გაქვთ",
"_Uploading %n file_::_Uploading %n files_" : ["ვტვირთავთ %n ფაილს"],
"New" : "ახალი",
+ "{used} of {quota} used" : "გამოყენებულია {used} სულ {quota}-დან",
+ "{used} used" : "გამოყენებულია {used}",
"\"{name}\" is an invalid file name." : "\"{name}\" არასწორი ფაილის სახელია.",
"File name cannot be empty." : "ფაილის სახელი არ შეიძლება იყოს ცარიელი.",
+ "\"/\" is not allowed inside a file name." : "\"/\" ფაილის სახელში არაა ნებადართული.",
"\"{name}\" is not an allowed filetype" : "\"{name}\" არაა დაშვებული ფაილის ტიპი",
"Storage of {owner} is full, files can not be updated or synced anymore!" : "{owner}-ის საცავი სავსეა, ფაილები მეტი ვეღარ განახლდება/სინქრონიზირდება!",
"Your storage is full, files can not be updated or synced anymore!" : "თქვენი საცავი გადაივსო. ფაილების განახლება და სინქრონიზირება ვერ მოხერხდება!",
diff --git a/apps/files/l10n/ka_GE.json b/apps/files/l10n/ka_GE.json
index 36f2400edd8..5c496dc08cf 100644
--- a/apps/files/l10n/ka_GE.json
+++ b/apps/files/l10n/ka_GE.json
@@ -60,8 +60,11 @@
"You don’t have permission to upload or create files here" : "აქ ფაილების შექმნის ან ატვირთვის უფლება არ გაქვთ",
"_Uploading %n file_::_Uploading %n files_" : ["ვტვირთავთ %n ფაილს"],
"New" : "ახალი",
+ "{used} of {quota} used" : "გამოყენებულია {used} სულ {quota}-დან",
+ "{used} used" : "გამოყენებულია {used}",
"\"{name}\" is an invalid file name." : "\"{name}\" არასწორი ფაილის სახელია.",
"File name cannot be empty." : "ფაილის სახელი არ შეიძლება იყოს ცარიელი.",
+ "\"/\" is not allowed inside a file name." : "\"/\" ფაილის სახელში არაა ნებადართული.",
"\"{name}\" is not an allowed filetype" : "\"{name}\" არაა დაშვებული ფაილის ტიპი",
"Storage of {owner} is full, files can not be updated or synced anymore!" : "{owner}-ის საცავი სავსეა, ფაილები მეტი ვეღარ განახლდება/სინქრონიზირდება!",
"Your storage is full, files can not be updated or synced anymore!" : "თქვენი საცავი გადაივსო. ფაილების განახლება და სინქრონიზირება ვერ მოხერხდება!",
diff --git a/apps/files/l10n/ko.js b/apps/files/l10n/ko.js
index 8b6ab2b51b0..cfe3b955df7 100644
--- a/apps/files/l10n/ko.js
+++ b/apps/files/l10n/ko.js
@@ -13,9 +13,9 @@ OC.L10N.register(
"Could not create folder \"{dir}\"" : "폴더 \"{dir}\"을(를) 만들 수 없음",
"Upload cancelled." : "업로드가 취소되었습니다.",
"Unable to upload {filename} as it is a directory or has 0 bytes" : "{filename}을(를) 업로드할 수 없습니다. 폴더이거나 0 바이트 파일입니다.",
- "Not enough free space, you are uploading {size1} but only {size2} is left" : "빈 공간이 부족합니다. 업로드할 파일 크기는 {size1}이지만 현재 {size2}만큼 비었습니다",
+ "Not enough free space, you are uploading {size1} but only {size2} is left" : "남은 공간이 부족합니다. 업로드할 파일 크기는 {size1}이지만 현재 {size2}만큼 남아 있습니다",
"Target folder \"{dir}\" does not exist any more" : "대상 폴더 \"{dir}\"이(가) 더 이상 존재하지 않습니다",
- "Not enough free space" : "빈 공간이 부족합니다",
+ "Not enough free space" : "남은 공간이 부족함",
"Uploading …" : "업로드 중…",
"…" : "…",
"{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize}/{totalSize}({bitrate})",
diff --git a/apps/files/l10n/ko.json b/apps/files/l10n/ko.json
index b9ea23ab0b9..0854c201bf9 100644
--- a/apps/files/l10n/ko.json
+++ b/apps/files/l10n/ko.json
@@ -11,9 +11,9 @@
"Could not create folder \"{dir}\"" : "폴더 \"{dir}\"을(를) 만들 수 없음",
"Upload cancelled." : "업로드가 취소되었습니다.",
"Unable to upload {filename} as it is a directory or has 0 bytes" : "{filename}을(를) 업로드할 수 없습니다. 폴더이거나 0 바이트 파일입니다.",
- "Not enough free space, you are uploading {size1} but only {size2} is left" : "빈 공간이 부족합니다. 업로드할 파일 크기는 {size1}이지만 현재 {size2}만큼 비었습니다",
+ "Not enough free space, you are uploading {size1} but only {size2} is left" : "남은 공간이 부족합니다. 업로드할 파일 크기는 {size1}이지만 현재 {size2}만큼 남아 있습니다",
"Target folder \"{dir}\" does not exist any more" : "대상 폴더 \"{dir}\"이(가) 더 이상 존재하지 않습니다",
- "Not enough free space" : "빈 공간이 부족합니다",
+ "Not enough free space" : "남은 공간이 부족함",
"Uploading …" : "업로드 중…",
"…" : "…",
"{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize}/{totalSize}({bitrate})",
diff --git a/apps/files/l10n/nb.js b/apps/files/l10n/nb.js
index b9e3ee0a1b8..45b9027f782 100644
--- a/apps/files/l10n/nb.js
+++ b/apps/files/l10n/nb.js
@@ -62,6 +62,8 @@ OC.L10N.register(
"You don’t have permission to upload or create files here" : "Du har ikke tillatelse til å laste opp eller opprette filer her",
"_Uploading %n file_::_Uploading %n files_" : ["Laster opp %n fil","Laster opp %n filer"],
"New" : "Ny",
+ "{used} of {quota} used" : "{used} av {quota} brukt",
+ "{used} used" : "{used} brukt",
"\"{name}\" is an invalid file name." : "\"{name}\" er et uglydig filnavn.",
"File name cannot be empty." : "Filnavn kan ikke være tomt.",
"\"{name}\" is not an allowed filetype" : "\"{name}\" er ikke en tillatt filtype",
diff --git a/apps/files/l10n/nb.json b/apps/files/l10n/nb.json
index 4c4e0622362..0328ceb283a 100644
--- a/apps/files/l10n/nb.json
+++ b/apps/files/l10n/nb.json
@@ -60,6 +60,8 @@
"You don’t have permission to upload or create files here" : "Du har ikke tillatelse til å laste opp eller opprette filer her",
"_Uploading %n file_::_Uploading %n files_" : ["Laster opp %n fil","Laster opp %n filer"],
"New" : "Ny",
+ "{used} of {quota} used" : "{used} av {quota} brukt",
+ "{used} used" : "{used} brukt",
"\"{name}\" is an invalid file name." : "\"{name}\" er et uglydig filnavn.",
"File name cannot be empty." : "Filnavn kan ikke være tomt.",
"\"{name}\" is not an allowed filetype" : "\"{name}\" er ikke en tillatt filtype",
diff --git a/apps/files/l10n/nl.js b/apps/files/l10n/nl.js
index 73a52503cef..5ee5d8c6181 100644
--- a/apps/files/l10n/nl.js
+++ b/apps/files/l10n/nl.js
@@ -62,8 +62,11 @@ OC.L10N.register(
"You don’t have permission to upload or create files here" : "Je hebt geen toestemming om hier te uploaden of bestanden te maken",
"_Uploading %n file_::_Uploading %n files_" : ["%n bestand aan het uploaden","%n bestanden aan het uploaden"],
"New" : "Nieuw",
+ "{used} of {quota} used" : "{used} van {quota} gebruikt",
+ "{used} used" : "{used} gebruikt",
"\"{name}\" is an invalid file name." : "\"{name}\" is een ongeldige bestandsnaam.",
"File name cannot be empty." : "Bestandsnaam kan niet leeg zijn.",
+ "\"/\" is not allowed inside a file name." : "\"/\" is niet toegestaan binnen een bestandsnaam.",
"\"{name}\" is not an allowed filetype" : "\"{name}\" bestandstype is een niet toegestaande",
"Storage of {owner} is full, files can not be updated or synced anymore!" : "Opslagruimte van {owner} zit vol, bestanden kunnen niet meer worden geüpload of gesynchroniseerd!",
"Your storage is full, files can not be updated or synced anymore!" : "Je opslagruimte zit vol. Bestanden kunnen niet meer worden gewijzigd of gesynchroniseerd!",
diff --git a/apps/files/l10n/nl.json b/apps/files/l10n/nl.json
index 55c83f970ba..2cc15f1f564 100644
--- a/apps/files/l10n/nl.json
+++ b/apps/files/l10n/nl.json
@@ -60,8 +60,11 @@
"You don’t have permission to upload or create files here" : "Je hebt geen toestemming om hier te uploaden of bestanden te maken",
"_Uploading %n file_::_Uploading %n files_" : ["%n bestand aan het uploaden","%n bestanden aan het uploaden"],
"New" : "Nieuw",
+ "{used} of {quota} used" : "{used} van {quota} gebruikt",
+ "{used} used" : "{used} gebruikt",
"\"{name}\" is an invalid file name." : "\"{name}\" is een ongeldige bestandsnaam.",
"File name cannot be empty." : "Bestandsnaam kan niet leeg zijn.",
+ "\"/\" is not allowed inside a file name." : "\"/\" is niet toegestaan binnen een bestandsnaam.",
"\"{name}\" is not an allowed filetype" : "\"{name}\" bestandstype is een niet toegestaande",
"Storage of {owner} is full, files can not be updated or synced anymore!" : "Opslagruimte van {owner} zit vol, bestanden kunnen niet meer worden geüpload of gesynchroniseerd!",
"Your storage is full, files can not be updated or synced anymore!" : "Je opslagruimte zit vol. Bestanden kunnen niet meer worden gewijzigd of gesynchroniseerd!",
diff --git a/apps/files/l10n/ro.js b/apps/files/l10n/ro.js
index e7b93b7b005..285604b1ea1 100644
--- a/apps/files/l10n/ro.js
+++ b/apps/files/l10n/ro.js
@@ -1,10 +1,12 @@
OC.L10N.register(
"files",
{
+ "Storage is temporarily not available" : "Spațiu de stocare este indisponibil temporar",
"Storage invalid" : "Spațiu de stocare invalid",
"Unknown error" : "Eroare necunoscută",
- "Files" : "Fișiere",
- "All files" : "Toate fișierele.",
+ "All files" : "Toate fișierele",
+ "Recent" : "Recente",
+ "File could not be found" : "Fișierul nu a fost găsit",
"Home" : "Acasă",
"Close" : "Închide",
"Favorites" : "Favorite",
@@ -12,21 +14,21 @@ OC.L10N.register(
"Upload cancelled." : "Încărcare anulată.",
"Unable to upload {filename} as it is a directory or has 0 bytes" : "Nu se poate încărca {filename} deoarece este un director sau are mărimea de 0 octeți",
"Not enough free space, you are uploading {size1} but only {size2} is left" : "Spațiu liber insuficient, încărcați {size1} însă doar {size2} disponibil rămas",
- "Uploading..." : "Încărcare",
- "..." : "...",
- "{hours}:{minutes}h" : "{hours}:{minutes}h",
- "{minutes}:{seconds}m" : "{minutes}:{seconds}m",
- "{seconds} second{plural_s} left" : "{seconds} secunde{plural_s} rămase",
- "{seconds}s" : "{seconds}s",
- "Any moment now..." : "În orice moment...",
- "Soon..." : "În curând...",
- "File upload is in progress. Leaving the page now will cancel the upload." : "Fișierul este în curs de încărcare. Părăsirea paginii va întrerupe încărcarea.",
+ "Target folder \"{dir}\" does not exist any more" : "Directorul \"{dir}\" nu mai există",
+ "Not enough free space" : "Spațiu insuficient",
+ "Uploading …" : "Încărcare...",
+ "…" : "...",
+ "{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} din {totalSize} ({bitrate})",
+ "Target folder does not exist any more" : "Directorul destinație nu mai există",
"Actions" : "Acțiuni",
"Download" : "Descarcă",
"Rename" : "Redenumește",
+ "Move or copy" : "Mută sau copiază",
+ "Target folder" : "Directorul destinație",
"Delete" : "Șterge",
"Disconnect storage" : "Deconectează stocarea",
"Unshare" : "Nu mai partaja",
+ "Files" : "Fișiere",
"Details" : "Detalii",
"Select" : "Alege",
"Pending" : "În așteptare",
@@ -35,6 +37,8 @@ OC.L10N.register(
"This directory is unavailable, please check the logs or contact the administrator" : "Acest director nu este disponibil, te rugăm verifică logurile sau contactează un administrator",
"Could not move \"{file}\", target exists" : "Nu s-a putut muta fișierul \"{file}\", există deja un altul cu același nume în directorul destinație",
"Could not move \"{file}\"" : "Nu s-a putut muta fișierul \"{file}\"",
+ "Could not copy \"{file}\"" : "Nu s-a putut copia \"{file}\"",
+ "Copied {origin} inside {destination}" : "S-a copiat {origin} în {destination}",
"{newName} already exists" : "{newName} există deja",
"Could not rename \"{fileName}\", it does not exist any more" : "Nu s-a putut redenumi \"{fileName}\", fișierul nu mai există",
"The name \"{targetName}\" is already used in the folder \"{dir}\". Please choose a different name." : "Numele \"{targetName}\" este deja folosit în directorul \"{dir}\". Alege un nume diferit.",
@@ -52,73 +56,98 @@ OC.L10N.register(
"You don’t have permission to upload or create files here" : "Nu aveți permisiunea de a încărca sau crea fișiere aici",
"_Uploading %n file_::_Uploading %n files_" : ["Se încarcă %n fișier.","Se încarcă %n fișiere.","Se încarcă %n fișiere."],
"New" : "Nou",
+ "{used} of {quota} used" : "{used} din {quota} folosiți",
+ "{used} used" : "{used} folosiți",
"\"{name}\" is an invalid file name." : "\"{name}\" este un nume de fișier nevalid.",
"File name cannot be empty." : "Numele fișierului nu poate rămâne gol.",
+ "\"{name}\" is not an allowed filetype" : "\"{name}\" ",
+ "Storage of {owner} is full, files can not be updated or synced anymore!" : "Spațiul de stocare pentru {owner} este plin, fișierele nu mai pot fi incărcate sau sincronizate!",
"Your storage is full, files can not be updated or synced anymore!" : "Spațiul de stocare este plin, fișierele nu mai pot fi actualizate sau sincronizate!",
+ "Storage of {owner} is almost full ({usedSpacePercent}%)" : "Spațiul de stocare pentru {owner} este aproape plin ({usedSpacePercent}%)",
"Your storage is almost full ({usedSpacePercent}%)" : "Spațiul de stocare este aproape plin ({usedSpacePercent}%)",
+ "Copied!" : "S-a copiat!",
+ "Copy direct link (only works for users who have access to this file/folder)" : "Copiază link direct (funcționeză numai pentru utilizatorii care au acces la acest fișier/director)",
"Path" : "Cale",
"_%n byte_::_%n bytes_" : ["%n octet","%n octeți","%n octeți"],
"Favorited" : "Adăugate la favorite",
"Favorite" : "Favorit",
- "Local link" : "Legătură locală",
- "Folder" : "Dosar",
"New folder" : "Un nou dosar",
- "Upload" : "Încărcă",
+ "Upload file" : "Încarcă fișier",
+ "Remove from favorites" : "Șterge din favorite",
+ "Add to favorites" : "Adaugă la favorite",
"An error occurred while trying to update the tags" : "A apărut o eroare în timpul actualizării etichetelor",
- "A new file or folder has been <strong>created</strong>" : "Un nou fișier sau dosar a fost <strong>creat</strong>",
- "A file or folder has been <strong>deleted</strong>" : "Un nou fișier sau dosar a fost <strong>șters</strong>",
+ "Added to favorites" : "Adaugat la favorite",
+ "Removed from favorites" : "Șters din favorite",
+ "You added {file} to your favorites" : "Ai adaugat {file} în favorite",
+ "You removed {file} from your favorites" : "Ai șters {file} din favorite",
+ "Created by {user}" : "Creat de {user}",
+ "Changed by {user}" : "Modificat de {user}",
+ "Deleted by {user}" : "Șters de {user}",
+ "Restored by {user}" : "Restaurat de {user}",
+ "Renamed by {user}" : "Redenumit de {user}",
+ "Moved by {user}" : "Mutat de {user}",
+ "\"remote user\"" : "\"utilizator la distanță\"",
+ "You created {file}" : "Ai creat {file}",
+ "{user} created {file}" : "{user} a creat {file}",
+ "{file} was created in a public folder" : "{file} a fost creat într-un director public ",
+ "You changed {file}" : "Ai modificat {file}",
+ "{user} changed {file}" : "{user} a modificat {file}",
+ "You deleted {file}" : "Ai șters {file}",
+ "{user} deleted {file}" : "{user} a șters {file}",
+ "You restored {file}" : "Ai restaurat {file}",
+ "{user} restored {file}" : "{user} a restaurat {file}",
+ "You renamed {oldfile} to {newfile}" : "Ai redenumit {oldfile} în {newfile}",
+ "{user} renamed {oldfile} to {newfile}" : "{user} a redenumit {oldfile} în {newfile}",
+ "You moved {oldfile} to {newfile}" : "Ai mutat{oldfile} în {newfile}",
+ "{user} moved {oldfile} to {newfile}" : "{user} a mutat {oldfile} în {newfile}",
+ "A file has been added to or removed from your <strong>favorites</strong>" : "Un fișier a fost adăugat în sau șters din <strong>favorites</strong>",
+ "A file or folder has been <strong>changed</strong> or <strong>renamed</strong>" : "Un fișier sau director a fost <strong>modificat</strong> sau <strong>redenumit</strong>",
+ "A new file or folder has been <strong>created</strong>" : "Un nou fișier sau director a fost <strong>creat</strong>",
+ "A file or folder has been <strong>deleted</strong>" : "Un fișier sau director a fost <strong>șters</strong>",
"A file or folder has been <strong>restored</strong>" : "Un fișier sau dosar a fost <strong>restaurat</strong>",
- "You created %1$s" : "Ai creat %1$s",
- "%2$s created %1$s" : "%2$s a creat %1$s",
- "%1$s was created in a public folder" : "%1$s a fost creat în dosarul public",
- "You changed %1$s" : "Ai schimbat %1$s",
- "%2$s changed %1$s" : "%2$s a schimbat %1$s",
- "You deleted %1$s" : "Ai şters %1$s",
- "%2$s deleted %1$s" : "%2$s a șters %1$s",
- "You restored %1$s" : "Ai restaurat %1$s",
- "%2$s restored %1$s" : "%2$s a restaurat %1$s",
- "Changed by %2$s" : "Modificat de %2$s",
- "Deleted by %2$s" : "Șters de %2$s",
- "Restored by %2$s" : "Restaurat de %2$s",
"Upload (max. %s)" : "Încarcă (max. %s)",
"File handling" : "Manipulare fișiere",
"Maximum upload size" : "Dimensiune maximă admisă la încărcare",
"max. possible: " : "max. posibil:",
"Save" : "Salvează",
+ "With PHP-FPM it might take 5 minutes for changes to be applied." : "Cu PHP-FPM poate dura 5 minute pentru a aplica schimbările..",
"Missing permissions to edit from here." : "Nu ai permisiuni pentru a edita aici.",
+ "%s of %s used" : "%s din %s folosiți",
+ "%s used" : "%s folosiți",
"Settings" : "Setări",
"Show hidden files" : "Arată fișierele ascunse",
"WebDAV" : "WebDAV",
+ "Use this address to <a href=\"%s\" target=\"_blank\" rel=\"noreferrer noopener\">access your Files via WebDAV</a>" : "Folosește această adresă <a href=\"%s\" target=\"_blank\" rel=\"noreferrer noopener\">pentru a accesa Fișierele prin WebDAV</a>",
+ "Cancel upload" : "Anulează încărcarea",
"No files in here" : "Niciun fișier aici",
"Upload some content or sync with your devices!" : "Încarcă ceva conținut sau sincronizează cu dispozitivele tale!",
"No entries found in this folder" : "Niciun element găsit în acest director",
"Select all" : "Selectează tot",
"Upload too large" : "Fișierul încărcat este prea mare",
"The files you are trying to upload exceed the maximum size for file uploads on this server." : "Fișierele pe care încerci să le încarci depășesc limita de încărcare maximă admisă pe acest server.",
- "No favorites" : "Fără favorite",
+ "No favorites yet" : "Nu aveți favorite încă",
"Files and folders you mark as favorite will show up here" : "FIșierele și directoarele pe care le marchezi ca favorite vor apărea aici",
+ "Shared with you" : "Partajat cu tine",
+ "Shared with others" : "Partajat cu alții",
+ "Shared by link" : "Partajat prin link",
+ "Tags" : "Etichete",
+ "Deleted files" : "Fișiere șterse",
"Text file" : "Fișier text",
"New text file.txt" : "New text file.txt",
- "Storage not available" : "Spațiu de stocare indisponibil",
- "Unable to set upload directory." : "Imposibil de a seta directorul pentru încărcare.",
- "Invalid Token" : "Jeton Invalid",
- "No file was uploaded. Unknown error" : "Niciun fișier nu a fost încărcat. Eroare necunoscută",
- "There is no error, the file uploaded with success" : "Nu a apărut nici o eroare, fișierul a fost încărcat cu succes",
- "The uploaded file exceeds the upload_max_filesize directive in php.ini: " : "Fișierul încărcat depășește directiva upload_max_filesize din php.ini:",
- "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Fișierul încărcat depășește directiva MAX_FILE_SIZE specificată în formularul HTML",
- "The uploaded file was only partially uploaded" : "Fișierul a fost încărcat doar parțial",
- "No file was uploaded" : "Nu a fost încărcat niciun fișier",
- "Missing a temporary folder" : "Lipsește un dosar temporar",
- "Failed to write to disk" : "Eroare la scrierea pe disc",
- "Not enough storage available" : "Nu este disponibil suficient spațiu pe disc",
- "The target folder has been moved or deleted." : "Dosarul țintă a fost mutat sau șters.",
- "Upload failed. Could not find uploaded file" : "Încărcare eșuată. Nu se poate găsi fișierul încărcat",
- "Upload failed. Could not get file info." : "Încărcare eșuată. Nu se pot obține informații despre fișier.",
- "Invalid directory." : "Dosar invalid.",
- "Total file size {size1} exceeds upload limit {size2}" : "Mărimea fișierului este {size1} ce depășește limita de încărcare de {size2}",
- "Could not get result from server." : "Nu se poate obține rezultatul de la server.",
- "No entries in this folder match '{filter}'" : "Niciun element din acest director nu se potrivește cu '{filter}'",
- "{newname} already exists" : "{newname} există deja",
- "A file or folder has been <strong>changed</strong>" : "Un nou fișier sau dosar a fost <strong>modificat</strong>"
+ "Uploading..." : "Încărcare",
+ "..." : "...",
+ "{hours}:{minutes}h" : "{hours}:{minutes}h",
+ "{minutes}:{seconds}m" : "{minutes}:{seconds}m",
+ "{seconds}s" : "{seconds}s",
+ "Any moment now..." : "În orice moment...",
+ "Soon..." : "În curând...",
+ "File upload is in progress. Leaving the page now will cancel the upload." : "Fișierul este în curs de încărcare. Părăsirea paginii va întrerupe încărcarea.",
+ "Move" : "Mută",
+ "Folder" : "Dosar",
+ "Upload" : "Încărcă",
+ "A new file or folder has been <strong>deleted</strong>" : "Un nou fișier sau director a fost <strong>șters</strong>",
+ "A new file or folder has been <strong>restored</strong>" : "Un fișier sau director a fost <strong>restaurat</strong>",
+ "Use this address to <a href=\"%s\" target=\"_blank\" rel=\"noreferrer\">access your Files via WebDAV</a>" : "Folosește această adresă <a href=\"%s\" target=\"_blank\" rel=\"noreferrer\">pentru a accesa Fișierele prin WebDAV</a>",
+ "No favorites" : "Fără favorite"
},
"nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));");
diff --git a/apps/files/l10n/ro.json b/apps/files/l10n/ro.json
index 45c55d2becc..8d41bb52adc 100644
--- a/apps/files/l10n/ro.json
+++ b/apps/files/l10n/ro.json
@@ -1,8 +1,10 @@
{ "translations": {
+ "Storage is temporarily not available" : "Spațiu de stocare este indisponibil temporar",
"Storage invalid" : "Spațiu de stocare invalid",
"Unknown error" : "Eroare necunoscută",
- "Files" : "Fișiere",
- "All files" : "Toate fișierele.",
+ "All files" : "Toate fișierele",
+ "Recent" : "Recente",
+ "File could not be found" : "Fișierul nu a fost găsit",
"Home" : "Acasă",
"Close" : "Închide",
"Favorites" : "Favorite",
@@ -10,21 +12,21 @@
"Upload cancelled." : "Încărcare anulată.",
"Unable to upload {filename} as it is a directory or has 0 bytes" : "Nu se poate încărca {filename} deoarece este un director sau are mărimea de 0 octeți",
"Not enough free space, you are uploading {size1} but only {size2} is left" : "Spațiu liber insuficient, încărcați {size1} însă doar {size2} disponibil rămas",
- "Uploading..." : "Încărcare",
- "..." : "...",
- "{hours}:{minutes}h" : "{hours}:{minutes}h",
- "{minutes}:{seconds}m" : "{minutes}:{seconds}m",
- "{seconds} second{plural_s} left" : "{seconds} secunde{plural_s} rămase",
- "{seconds}s" : "{seconds}s",
- "Any moment now..." : "În orice moment...",
- "Soon..." : "În curând...",
- "File upload is in progress. Leaving the page now will cancel the upload." : "Fișierul este în curs de încărcare. Părăsirea paginii va întrerupe încărcarea.",
+ "Target folder \"{dir}\" does not exist any more" : "Directorul \"{dir}\" nu mai există",
+ "Not enough free space" : "Spațiu insuficient",
+ "Uploading …" : "Încărcare...",
+ "…" : "...",
+ "{loadedSize} of {totalSize} ({bitrate})" : "{loadedSize} din {totalSize} ({bitrate})",
+ "Target folder does not exist any more" : "Directorul destinație nu mai există",
"Actions" : "Acțiuni",
"Download" : "Descarcă",
"Rename" : "Redenumește",
+ "Move or copy" : "Mută sau copiază",
+ "Target folder" : "Directorul destinație",
"Delete" : "Șterge",
"Disconnect storage" : "Deconectează stocarea",
"Unshare" : "Nu mai partaja",
+ "Files" : "Fișiere",
"Details" : "Detalii",
"Select" : "Alege",
"Pending" : "În așteptare",
@@ -33,6 +35,8 @@
"This directory is unavailable, please check the logs or contact the administrator" : "Acest director nu este disponibil, te rugăm verifică logurile sau contactează un administrator",
"Could not move \"{file}\", target exists" : "Nu s-a putut muta fișierul \"{file}\", există deja un altul cu același nume în directorul destinație",
"Could not move \"{file}\"" : "Nu s-a putut muta fișierul \"{file}\"",
+ "Could not copy \"{file}\"" : "Nu s-a putut copia \"{file}\"",
+ "Copied {origin} inside {destination}" : "S-a copiat {origin} în {destination}",
"{newName} already exists" : "{newName} există deja",
"Could not rename \"{fileName}\", it does not exist any more" : "Nu s-a putut redenumi \"{fileName}\", fișierul nu mai există",
"The name \"{targetName}\" is already used in the folder \"{dir}\". Please choose a different name." : "Numele \"{targetName}\" este deja folosit în directorul \"{dir}\". Alege un nume diferit.",
@@ -50,73 +54,98 @@
"You don’t have permission to upload or create files here" : "Nu aveți permisiunea de a încărca sau crea fișiere aici",
"_Uploading %n file_::_Uploading %n files_" : ["Se încarcă %n fișier.","Se încarcă %n fișiere.","Se încarcă %n fișiere."],
"New" : "Nou",
+ "{used} of {quota} used" : "{used} din {quota} folosiți",
+ "{used} used" : "{used} folosiți",
"\"{name}\" is an invalid file name." : "\"{name}\" este un nume de fișier nevalid.",
"File name cannot be empty." : "Numele fișierului nu poate rămâne gol.",
+ "\"{name}\" is not an allowed filetype" : "\"{name}\" ",
+ "Storage of {owner} is full, files can not be updated or synced anymore!" : "Spațiul de stocare pentru {owner} este plin, fișierele nu mai pot fi incărcate sau sincronizate!",
"Your storage is full, files can not be updated or synced anymore!" : "Spațiul de stocare este plin, fișierele nu mai pot fi actualizate sau sincronizate!",
+ "Storage of {owner} is almost full ({usedSpacePercent}%)" : "Spațiul de stocare pentru {owner} este aproape plin ({usedSpacePercent}%)",
"Your storage is almost full ({usedSpacePercent}%)" : "Spațiul de stocare este aproape plin ({usedSpacePercent}%)",
+ "Copied!" : "S-a copiat!",
+ "Copy direct link (only works for users who have access to this file/folder)" : "Copiază link direct (funcționeză numai pentru utilizatorii care au acces la acest fișier/director)",
"Path" : "Cale",
"_%n byte_::_%n bytes_" : ["%n octet","%n octeți","%n octeți"],
"Favorited" : "Adăugate la favorite",
"Favorite" : "Favorit",
- "Local link" : "Legătură locală",
- "Folder" : "Dosar",
"New folder" : "Un nou dosar",
- "Upload" : "Încărcă",
+ "Upload file" : "Încarcă fișier",
+ "Remove from favorites" : "Șterge din favorite",
+ "Add to favorites" : "Adaugă la favorite",
"An error occurred while trying to update the tags" : "A apărut o eroare în timpul actualizării etichetelor",
- "A new file or folder has been <strong>created</strong>" : "Un nou fișier sau dosar a fost <strong>creat</strong>",
- "A file or folder has been <strong>deleted</strong>" : "Un nou fișier sau dosar a fost <strong>șters</strong>",
+ "Added to favorites" : "Adaugat la favorite",
+ "Removed from favorites" : "Șters din favorite",
+ "You added {file} to your favorites" : "Ai adaugat {file} în favorite",
+ "You removed {file} from your favorites" : "Ai șters {file} din favorite",
+ "Created by {user}" : "Creat de {user}",
+ "Changed by {user}" : "Modificat de {user}",
+ "Deleted by {user}" : "Șters de {user}",
+ "Restored by {user}" : "Restaurat de {user}",
+ "Renamed by {user}" : "Redenumit de {user}",
+ "Moved by {user}" : "Mutat de {user}",
+ "\"remote user\"" : "\"utilizator la distanță\"",
+ "You created {file}" : "Ai creat {file}",
+ "{user} created {file}" : "{user} a creat {file}",
+ "{file} was created in a public folder" : "{file} a fost creat într-un director public ",
+ "You changed {file}" : "Ai modificat {file}",
+ "{user} changed {file}" : "{user} a modificat {file}",
+ "You deleted {file}" : "Ai șters {file}",
+ "{user} deleted {file}" : "{user} a șters {file}",
+ "You restored {file}" : "Ai restaurat {file}",
+ "{user} restored {file}" : "{user} a restaurat {file}",
+ "You renamed {oldfile} to {newfile}" : "Ai redenumit {oldfile} în {newfile}",
+ "{user} renamed {oldfile} to {newfile}" : "{user} a redenumit {oldfile} în {newfile}",
+ "You moved {oldfile} to {newfile}" : "Ai mutat{oldfile} în {newfile}",
+ "{user} moved {oldfile} to {newfile}" : "{user} a mutat {oldfile} în {newfile}",
+ "A file has been added to or removed from your <strong>favorites</strong>" : "Un fișier a fost adăugat în sau șters din <strong>favorites</strong>",
+ "A file or folder has been <strong>changed</strong> or <strong>renamed</strong>" : "Un fișier sau director a fost <strong>modificat</strong> sau <strong>redenumit</strong>",
+ "A new file or folder has been <strong>created</strong>" : "Un nou fișier sau director a fost <strong>creat</strong>",
+ "A file or folder has been <strong>deleted</strong>" : "Un fișier sau director a fost <strong>șters</strong>",
"A file or folder has been <strong>restored</strong>" : "Un fișier sau dosar a fost <strong>restaurat</strong>",
- "You created %1$s" : "Ai creat %1$s",
- "%2$s created %1$s" : "%2$s a creat %1$s",
- "%1$s was created in a public folder" : "%1$s a fost creat în dosarul public",
- "You changed %1$s" : "Ai schimbat %1$s",
- "%2$s changed %1$s" : "%2$s a schimbat %1$s",
- "You deleted %1$s" : "Ai şters %1$s",
- "%2$s deleted %1$s" : "%2$s a șters %1$s",
- "You restored %1$s" : "Ai restaurat %1$s",
- "%2$s restored %1$s" : "%2$s a restaurat %1$s",
- "Changed by %2$s" : "Modificat de %2$s",
- "Deleted by %2$s" : "Șters de %2$s",
- "Restored by %2$s" : "Restaurat de %2$s",
"Upload (max. %s)" : "Încarcă (max. %s)",
"File handling" : "Manipulare fișiere",
"Maximum upload size" : "Dimensiune maximă admisă la încărcare",
"max. possible: " : "max. posibil:",
"Save" : "Salvează",
+ "With PHP-FPM it might take 5 minutes for changes to be applied." : "Cu PHP-FPM poate dura 5 minute pentru a aplica schimbările..",
"Missing permissions to edit from here." : "Nu ai permisiuni pentru a edita aici.",
+ "%s of %s used" : "%s din %s folosiți",
+ "%s used" : "%s folosiți",
"Settings" : "Setări",
"Show hidden files" : "Arată fișierele ascunse",
"WebDAV" : "WebDAV",
+ "Use this address to <a href=\"%s\" target=\"_blank\" rel=\"noreferrer noopener\">access your Files via WebDAV</a>" : "Folosește această adresă <a href=\"%s\" target=\"_blank\" rel=\"noreferrer noopener\">pentru a accesa Fișierele prin WebDAV</a>",
+ "Cancel upload" : "Anulează încărcarea",
"No files in here" : "Niciun fișier aici",
"Upload some content or sync with your devices!" : "Încarcă ceva conținut sau sincronizează cu dispozitivele tale!",
"No entries found in this folder" : "Niciun element găsit în acest director",
"Select all" : "Selectează tot",
"Upload too large" : "Fișierul încărcat este prea mare",
"The files you are trying to upload exceed the maximum size for file uploads on this server." : "Fișierele pe care încerci să le încarci depășesc limita de încărcare maximă admisă pe acest server.",
- "No favorites" : "Fără favorite",
+ "No favorites yet" : "Nu aveți favorite încă",
"Files and folders you mark as favorite will show up here" : "FIșierele și directoarele pe care le marchezi ca favorite vor apărea aici",
+ "Shared with you" : "Partajat cu tine",
+ "Shared with others" : "Partajat cu alții",
+ "Shared by link" : "Partajat prin link",
+ "Tags" : "Etichete",
+ "Deleted files" : "Fișiere șterse",
"Text file" : "Fișier text",
"New text file.txt" : "New text file.txt",
- "Storage not available" : "Spațiu de stocare indisponibil",
- "Unable to set upload directory." : "Imposibil de a seta directorul pentru încărcare.",
- "Invalid Token" : "Jeton Invalid",
- "No file was uploaded. Unknown error" : "Niciun fișier nu a fost încărcat. Eroare necunoscută",
- "There is no error, the file uploaded with success" : "Nu a apărut nici o eroare, fișierul a fost încărcat cu succes",
- "The uploaded file exceeds the upload_max_filesize directive in php.ini: " : "Fișierul încărcat depășește directiva upload_max_filesize din php.ini:",
- "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Fișierul încărcat depășește directiva MAX_FILE_SIZE specificată în formularul HTML",
- "The uploaded file was only partially uploaded" : "Fișierul a fost încărcat doar parțial",
- "No file was uploaded" : "Nu a fost încărcat niciun fișier",
- "Missing a temporary folder" : "Lipsește un dosar temporar",
- "Failed to write to disk" : "Eroare la scrierea pe disc",
- "Not enough storage available" : "Nu este disponibil suficient spațiu pe disc",
- "The target folder has been moved or deleted." : "Dosarul țintă a fost mutat sau șters.",
- "Upload failed. Could not find uploaded file" : "Încărcare eșuată. Nu se poate găsi fișierul încărcat",
- "Upload failed. Could not get file info." : "Încărcare eșuată. Nu se pot obține informații despre fișier.",
- "Invalid directory." : "Dosar invalid.",
- "Total file size {size1} exceeds upload limit {size2}" : "Mărimea fișierului este {size1} ce depășește limita de încărcare de {size2}",
- "Could not get result from server." : "Nu se poate obține rezultatul de la server.",
- "No entries in this folder match '{filter}'" : "Niciun element din acest director nu se potrivește cu '{filter}'",
- "{newname} already exists" : "{newname} există deja",
- "A file or folder has been <strong>changed</strong>" : "Un nou fișier sau dosar a fost <strong>modificat</strong>"
+ "Uploading..." : "Încărcare",
+ "..." : "...",
+ "{hours}:{minutes}h" : "{hours}:{minutes}h",
+ "{minutes}:{seconds}m" : "{minutes}:{seconds}m",
+ "{seconds}s" : "{seconds}s",
+ "Any moment now..." : "În orice moment...",
+ "Soon..." : "În curând...",
+ "File upload is in progress. Leaving the page now will cancel the upload." : "Fișierul este în curs de încărcare. Părăsirea paginii va întrerupe încărcarea.",
+ "Move" : "Mută",
+ "Folder" : "Dosar",
+ "Upload" : "Încărcă",
+ "A new file or folder has been <strong>deleted</strong>" : "Un nou fișier sau director a fost <strong>șters</strong>",
+ "A new file or folder has been <strong>restored</strong>" : "Un fișier sau director a fost <strong>restaurat</strong>",
+ "Use this address to <a href=\"%s\" target=\"_blank\" rel=\"noreferrer\">access your Files via WebDAV</a>" : "Folosește această adresă <a href=\"%s\" target=\"_blank\" rel=\"noreferrer\">pentru a accesa Fișierele prin WebDAV</a>",
+ "No favorites" : "Fără favorite"
},"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/l10n/ru.js b/apps/files/l10n/ru.js
index b6222725a72..9878e2f78dd 100644
--- a/apps/files/l10n/ru.js
+++ b/apps/files/l10n/ru.js
@@ -62,8 +62,11 @@ OC.L10N.register(
"You don’t have permission to upload or create files here" : "У вас нет разрешений на создание или загрузку файлов в эту папку.",
"_Uploading %n file_::_Uploading %n files_" : ["Выгружа%nется файл","Выгружаются %n файла","Выгружаются %n файлов","Загружаются %n файлов"],
"New" : "Новый",
+ "{used} of {quota} used" : "использовано {used} из {quota}",
+ "{used} used" : "использовано {used}",
"\"{name}\" is an invalid file name." : "«{name}» — недопустимое имя файла.",
"File name cannot be empty." : "Имя файла не может быть пустым.",
+ "\"/\" is not allowed inside a file name." : "Символ «/» недопустим в имени файла.",
"\"{name}\" is not an allowed filetype" : "«{name}» - недопустимый тип файла.",
"Storage of {owner} is full, files can not be updated or synced anymore!" : "Хранилище {owner} переполнено, файлы больше не могут быть обновлены или синхронизированы!",
"Your storage is full, files can not be updated or synced anymore!" : "Ваше хранилище переполнено, файлы больше не могут быть обновлены или синхронизированы!",
diff --git a/apps/files/l10n/ru.json b/apps/files/l10n/ru.json
index e989cdd3183..be07497fda4 100644
--- a/apps/files/l10n/ru.json
+++ b/apps/files/l10n/ru.json
@@ -60,8 +60,11 @@
"You don’t have permission to upload or create files here" : "У вас нет разрешений на создание или загрузку файлов в эту папку.",
"_Uploading %n file_::_Uploading %n files_" : ["Выгружа%nется файл","Выгружаются %n файла","Выгружаются %n файлов","Загружаются %n файлов"],
"New" : "Новый",
+ "{used} of {quota} used" : "использовано {used} из {quota}",
+ "{used} used" : "использовано {used}",
"\"{name}\" is an invalid file name." : "«{name}» — недопустимое имя файла.",
"File name cannot be empty." : "Имя файла не может быть пустым.",
+ "\"/\" is not allowed inside a file name." : "Символ «/» недопустим в имени файла.",
"\"{name}\" is not an allowed filetype" : "«{name}» - недопустимый тип файла.",
"Storage of {owner} is full, files can not be updated or synced anymore!" : "Хранилище {owner} переполнено, файлы больше не могут быть обновлены или синхронизированы!",
"Your storage is full, files can not be updated or synced anymore!" : "Ваше хранилище переполнено, файлы больше не могут быть обновлены или синхронизированы!",
diff --git a/apps/files/l10n/tr.js b/apps/files/l10n/tr.js
index 6d68c8889bc..e1252d20b18 100644
--- a/apps/files/l10n/tr.js
+++ b/apps/files/l10n/tr.js
@@ -62,8 +62,11 @@ OC.L10N.register(
"You don’t have permission to upload or create files here" : "Buraya dosya yükleme veya ekleme izniniz yok",
"_Uploading %n file_::_Uploading %n files_" : ["%n dosya yükleniyor","%n dosya yükleniyor"],
"New" : "Yeni",
+ "{used} of {quota} used" : "{used} / {quota} kullanılmış",
+ "{used} used" : "{used} kullanılmış",
"\"{name}\" is an invalid file name." : "\"{name}\" geçersiz bir dosya adı.",
"File name cannot be empty." : "Dosya adı boş olamaz.",
+ "\"/\" is not allowed inside a file name." : "Dosya adında \"/\" kullanılamaz.",
"\"{name}\" is not an allowed filetype" : "\"{name}\" dosya türüne izin verilmiyor",
"Storage of {owner} is full, files can not be updated or synced anymore!" : "{owner} için boş depolama alanı kalmadı. Artık dosyalar güncellenmeyecek ya da eşitlenmeyecek!",
"Your storage is full, files can not be updated or synced anymore!" : "Boş depolama alanınız kalmadı. Artık dosyalar güncellenmeyecek ya da eşitlenmeyecek!",
diff --git a/apps/files/l10n/tr.json b/apps/files/l10n/tr.json
index cde68e5b35b..ca8bfbf8028 100644
--- a/apps/files/l10n/tr.json
+++ b/apps/files/l10n/tr.json
@@ -60,8 +60,11 @@
"You don’t have permission to upload or create files here" : "Buraya dosya yükleme veya ekleme izniniz yok",
"_Uploading %n file_::_Uploading %n files_" : ["%n dosya yükleniyor","%n dosya yükleniyor"],
"New" : "Yeni",
+ "{used} of {quota} used" : "{used} / {quota} kullanılmış",
+ "{used} used" : "{used} kullanılmış",
"\"{name}\" is an invalid file name." : "\"{name}\" geçersiz bir dosya adı.",
"File name cannot be empty." : "Dosya adı boş olamaz.",
+ "\"/\" is not allowed inside a file name." : "Dosya adında \"/\" kullanılamaz.",
"\"{name}\" is not an allowed filetype" : "\"{name}\" dosya türüne izin verilmiyor",
"Storage of {owner} is full, files can not be updated or synced anymore!" : "{owner} için boş depolama alanı kalmadı. Artık dosyalar güncellenmeyecek ya da eşitlenmeyecek!",
"Your storage is full, files can not be updated or synced anymore!" : "Boş depolama alanınız kalmadı. Artık dosyalar güncellenmeyecek ya da eşitlenmeyecek!",
diff --git a/apps/files/lib/AppInfo/Application.php b/apps/files/lib/AppInfo/Application.php
index 7042af10ca2..e55d1c549a5 100644
--- a/apps/files/lib/AppInfo/Application.php
+++ b/apps/files/lib/AppInfo/Application.php
@@ -81,13 +81,14 @@ class Application extends App {
$container->registerService('Tagger', function(IContainer $c) {
return $c->query('ServerContainer')->getTagManager()->load('files');
});
- $container->registerService('TagService', function(IContainer $c) {
+ $container->registerService('TagService', function(IContainer $c) use ($server) {
$homeFolder = $c->query('ServerContainer')->getUserFolder();
return new TagService(
$c->query('ServerContainer')->getUserSession(),
$c->query('ServerContainer')->getActivityManager(),
$c->query('Tagger'),
- $homeFolder
+ $homeFolder,
+ $server->getEventDispatcher()
);
});
diff --git a/apps/files/lib/Service/TagService.php b/apps/files/lib/Service/TagService.php
index d812b16c30e..7437f0c31ad 100644
--- a/apps/files/lib/Service/TagService.php
+++ b/apps/files/lib/Service/TagService.php
@@ -31,6 +31,8 @@ use OCP\Files\Folder;
use OCP\ITags;
use OCP\IUser;
use OCP\IUserSession;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+use Symfony\Component\EventDispatcher\GenericEvent;
/**
* Service class to manage tags on files.
@@ -45,23 +47,28 @@ class TagService {
private $tagger;
/** @var Folder */
private $homeFolder;
+ /** @var EventDispatcherInterface */
+ private $dispatcher;
/**
* @param IUserSession $userSession
* @param IManager $activityManager
* @param ITags $tagger
* @param Folder $homeFolder
+ * @param EventDispatcherInterface $dispatcher
*/
public function __construct(
IUserSession $userSession,
IManager $activityManager,
ITags $tagger,
- Folder $homeFolder
+ Folder $homeFolder,
+ EventDispatcherInterface $dispatcher
) {
$this->userSession = $userSession;
$this->activityManager = $activityManager;
$this->tagger = $tagger;
$this->homeFolder = $homeFolder;
+ $this->dispatcher = $dispatcher;
}
/**
@@ -114,6 +121,13 @@ class TagService {
return;
}
+ $eventName = $addToFavorite ? 'addFavorite' : 'removeFavorite';
+ $this->dispatcher->dispatch(self::class . '::' . $eventName, new GenericEvent(null, [
+ 'userId' => $user->getUID(),
+ 'fileId' => $fileId,
+ 'path' => $path,
+ ]));
+
$event = $this->activityManager->generateEvent();
try {
$event->setApp('files')
diff --git a/apps/files/tests/Service/TagServiceTest.php b/apps/files/tests/Service/TagServiceTest.php
index 1c4ac2328ec..4e2aeb84246 100644
--- a/apps/files/tests/Service/TagServiceTest.php
+++ b/apps/files/tests/Service/TagServiceTest.php
@@ -28,6 +28,7 @@ use OC\Tags;
use OCA\Files\Service\TagService;
use OCP\Activity\IManager;
use OCP\IUserSession;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
/**
* Class TagServiceTest
@@ -54,6 +55,9 @@ class TagServiceTest extends \Test\TestCase {
*/
private $root;
+ /** @var EventDispatcherInterface|\PHPUnit_Framework_MockObject_MockObject */
+ private $dispatcher;
+
/**
* @var \OCA\Files\Service\TagService|\PHPUnit_Framework_MockObject_MockObject
*/
@@ -66,7 +70,7 @@ class TagServiceTest extends \Test\TestCase {
protected function setUp() {
parent::setUp();
- $this->user = $this->getUniqueID('user');
+ $this->user = static::getUniqueID('user');
$this->activityManager = $this->createMock(IManager::class);
\OC::$server->getUserManager()->createUser($this->user, 'test');
\OC_User::setUserId($this->user);
@@ -83,6 +87,7 @@ class TagServiceTest extends \Test\TestCase {
->will($this->returnValue($user));
$this->root = \OC::$server->getUserFolder();
+ $this->dispatcher = $this->createMock(EventDispatcherInterface::class);
$this->tagger = \OC::$server->getTagManager()->load('files');
$this->tagService = $this->getTagService(['addActivity']);
@@ -99,6 +104,7 @@ class TagServiceTest extends \Test\TestCase {
$this->activityManager,
$this->tagger,
$this->root,
+ $this->dispatcher,
])
->setMethods($methods)
->getMock();
diff --git a/apps/files/tests/js/filelistSpec.js b/apps/files/tests/js/filelistSpec.js
index fc5a6c18f95..08da15b8a88 100644
--- a/apps/files/tests/js/filelistSpec.js
+++ b/apps/files/tests/js/filelistSpec.js
@@ -612,6 +612,12 @@ describe('OCA.Files.FileList tests', function() {
beforeEach(function() {
deferredRename = $.Deferred();
renameStub = sinon.stub(filesClient, 'move').returns(deferredRename.promise());
+
+ for (var i = 0; i < testFiles.length; i++) {
+ var file = testFiles[i];
+ file.path = '/some/subdir';
+ fileList.add(file, {silent: true});
+ }
});
afterEach(function() {
renameStub.restore();
@@ -619,9 +625,6 @@ describe('OCA.Files.FileList tests', function() {
function doCancelRename() {
var $input;
- for (var i = 0; i < testFiles.length; i++) {
- fileList.add(testFiles[i]);
- }
// trigger rename prompt
fileList.rename('One.txt');
@@ -636,12 +639,6 @@ describe('OCA.Files.FileList tests', function() {
function doRename() {
var $input;
- for (var i = 0; i < testFiles.length; i++) {
- var file = testFiles[i];
- file.path = '/some/subdir';
- fileList.add(file, {silent: true});
- }
-
// trigger rename prompt
fileList.rename('One.txt');
$input = fileList.$fileList.find('input.filename');
@@ -677,6 +674,36 @@ describe('OCA.Files.FileList tests', function() {
expect(notificationStub.calledOnce).toEqual(true);
});
+ it('Shows renamed file details if rename ajax call suceeded', function() {
+ fileList.showDetailsView('One.txt');
+
+ expect($('#app-sidebar').hasClass('disappear')).toEqual(false);
+ expect(fileList._detailsView.getFileInfo().get('id')).toEqual(1);
+ expect(fileList._detailsView.getFileInfo().get('name')).toEqual('One.txt');
+
+ doRename();
+
+ deferredRename.resolve(201);
+
+ expect($('#app-sidebar').hasClass('disappear')).toEqual(false);
+ expect(fileList._detailsView.getFileInfo().get('id')).toEqual(1);
+ expect(fileList._detailsView.getFileInfo().get('name')).toEqual('Tu_after_three.txt');
+ });
+ it('Shows again file details if rename ajax call failed', function() {
+ fileList.showDetailsView('One.txt');
+
+ expect($('#app-sidebar').hasClass('disappear')).toEqual(false);
+ expect(fileList._detailsView.getFileInfo().get('id')).toEqual(1);
+ expect(fileList._detailsView.getFileInfo().get('name')).toEqual('One.txt');
+
+ doRename();
+
+ deferredRename.reject(403);
+
+ expect($('#app-sidebar').hasClass('disappear')).toEqual(false);
+ expect(fileList._detailsView.getFileInfo().get('id')).toEqual(1);
+ expect(fileList._detailsView.getFileInfo().get('name')).toEqual('One.txt');
+ });
it('Correctly updates file link after rename', function() {
var $tr;
doRename();
@@ -731,10 +758,6 @@ describe('OCA.Files.FileList tests', function() {
it('Validates the file name', function() {
var $input, $tr;
- for (var i = 0; i < testFiles.length; i++) {
- fileList.add(testFiles[i], {silent: true});
- }
-
$tr = fileList.findFileEl('One.txt');
expect($tr.find('a.name').css('display')).not.toEqual('none');
diff --git a/apps/files/tests/js/mainfileinfodetailviewSpec.js b/apps/files/tests/js/mainfileinfodetailviewSpec.js
index faf0faa8d8f..0201429a472 100644
--- a/apps/files/tests/js/mainfileinfodetailviewSpec.js
+++ b/apps/files/tests/js/mainfileinfodetailviewSpec.js
@@ -68,6 +68,12 @@ describe('OCA.Files.MainFileInfoDetailView tests', function() {
.toEqual(OC.getProtocol() + '://' + OC.getHost() + OC.generateUrl('/f/5'));
});
it('displays favorite icon', function() {
+ fileActions.registerAction({
+ name: 'Favorite',
+ mime: 'all',
+ permissions: OC.PERMISSION_NONE
+ });
+
testFileInfo.set('tags', [OC.TAG_FAVORITE]);
view.setFileInfo(testFileInfo);
expect(view.$el.find('.action-favorite > span').hasClass('icon-starred')).toEqual(true);
@@ -78,6 +84,15 @@ describe('OCA.Files.MainFileInfoDetailView tests', function() {
expect(view.$el.find('.action-favorite > span').hasClass('icon-starred')).toEqual(false);
expect(view.$el.find('.action-favorite > span').hasClass('icon-star')).toEqual(true);
});
+ it('does not display favorite icon if favorite action is not available', function() {
+ testFileInfo.set('tags', [OC.TAG_FAVORITE]);
+ view.setFileInfo(testFileInfo);
+ expect(view.$el.find('.action-favorite').length).toEqual(0);
+
+ testFileInfo.set('tags', []);
+ view.setFileInfo(testFileInfo);
+ expect(view.$el.find('.action-favorite').length).toEqual(0);
+ });
it('displays mime icon', function() {
// File
var lazyLoadPreviewStub = sinon.stub(fileList, 'lazyLoadPreview');
@@ -183,6 +198,13 @@ describe('OCA.Files.MainFileInfoDetailView tests', function() {
expect(view.$el.find('.fileName h3').attr('title')).toEqual('hello.txt');
});
it('rerenders when changes are made on the model', function() {
+ // Show the "Favorite" icon
+ fileActions.registerAction({
+ name: 'Favorite',
+ mime: 'all',
+ permissions: OC.PERMISSION_NONE
+ });
+
view.setFileInfo(testFileInfo);
testFileInfo.set('tags', [OC.TAG_FAVORITE]);
@@ -196,6 +218,13 @@ describe('OCA.Files.MainFileInfoDetailView tests', function() {
expect(view.$el.find('.action-favorite > span').hasClass('icon-star')).toEqual(true);
});
it('unbinds change listener from model', function() {
+ // Show the "Favorite" icon
+ fileActions.registerAction({
+ name: 'Favorite',
+ mime: 'all',
+ permissions: OC.PERMISSION_NONE
+ });
+
view.setFileInfo(testFileInfo);
view.setFileInfo(new OCA.Files.FileInfoModel({
id: 999,
diff --git a/apps/files_external/l10n/de.js b/apps/files_external/l10n/de.js
index 40126676f0a..eb8fbdf0d8c 100644
--- a/apps/files_external/l10n/de.js
+++ b/apps/files_external/l10n/de.js
@@ -75,6 +75,7 @@ OC.L10N.register(
"Region" : "Region",
"Enable SSL" : "SSL aktivieren",
"Enable Path Style" : "Pfad-Stil aktivieren",
+ "Legacy (v2) authentication" : "Legacy-Authentifizierung (V2)",
"WebDAV" : "WebDAV",
"URL" : "URL",
"Remote subfolder" : "Entfernter Unterordner",
diff --git a/apps/files_external/l10n/de.json b/apps/files_external/l10n/de.json
index c93ba785568..53fd2e422fa 100644
--- a/apps/files_external/l10n/de.json
+++ b/apps/files_external/l10n/de.json
@@ -73,6 +73,7 @@
"Region" : "Region",
"Enable SSL" : "SSL aktivieren",
"Enable Path Style" : "Pfad-Stil aktivieren",
+ "Legacy (v2) authentication" : "Legacy-Authentifizierung (V2)",
"WebDAV" : "WebDAV",
"URL" : "URL",
"Remote subfolder" : "Entfernter Unterordner",
diff --git a/apps/files_external/l10n/de_DE.js b/apps/files_external/l10n/de_DE.js
index 6851466d426..5f01b5179de 100644
--- a/apps/files_external/l10n/de_DE.js
+++ b/apps/files_external/l10n/de_DE.js
@@ -75,6 +75,7 @@ OC.L10N.register(
"Region" : "Region",
"Enable SSL" : "SSL aktivieren",
"Enable Path Style" : "Pfadstil aktivieren",
+ "Legacy (v2) authentication" : "Legacy-Authentifizierung (V2)",
"WebDAV" : "WebDAV",
"URL" : "Adresse",
"Remote subfolder" : "Entfernter Unterordner",
diff --git a/apps/files_external/l10n/de_DE.json b/apps/files_external/l10n/de_DE.json
index 22e359c0378..e5f25c97a1f 100644
--- a/apps/files_external/l10n/de_DE.json
+++ b/apps/files_external/l10n/de_DE.json
@@ -73,6 +73,7 @@
"Region" : "Region",
"Enable SSL" : "SSL aktivieren",
"Enable Path Style" : "Pfadstil aktivieren",
+ "Legacy (v2) authentication" : "Legacy-Authentifizierung (V2)",
"WebDAV" : "WebDAV",
"URL" : "Adresse",
"Remote subfolder" : "Entfernter Unterordner",
diff --git a/apps/files_external/l10n/en_GB.js b/apps/files_external/l10n/en_GB.js
index 131c9af43ad..45fe58c0b36 100644
--- a/apps/files_external/l10n/en_GB.js
+++ b/apps/files_external/l10n/en_GB.js
@@ -75,6 +75,7 @@ OC.L10N.register(
"Region" : "Region",
"Enable SSL" : "Enable SSL",
"Enable Path Style" : "Enable Path Style",
+ "Legacy (v2) authentication" : "Legacy (v2) authentication",
"WebDAV" : "WebDAV",
"URL" : "URL",
"Remote subfolder" : "Remote subfolder",
diff --git a/apps/files_external/l10n/en_GB.json b/apps/files_external/l10n/en_GB.json
index 5c60ec6e344..f7ac7290e7a 100644
--- a/apps/files_external/l10n/en_GB.json
+++ b/apps/files_external/l10n/en_GB.json
@@ -73,6 +73,7 @@
"Region" : "Region",
"Enable SSL" : "Enable SSL",
"Enable Path Style" : "Enable Path Style",
+ "Legacy (v2) authentication" : "Legacy (v2) authentication",
"WebDAV" : "WebDAV",
"URL" : "URL",
"Remote subfolder" : "Remote subfolder",
diff --git a/apps/files_external/l10n/es.js b/apps/files_external/l10n/es.js
index b980588862e..7bfed57158d 100644
--- a/apps/files_external/l10n/es.js
+++ b/apps/files_external/l10n/es.js
@@ -75,6 +75,7 @@ OC.L10N.register(
"Region" : "Región",
"Enable SSL" : "Habilitar SSL",
"Enable Path Style" : "Habilitar Estilo de Ruta",
+ "Legacy (v2) authentication" : "Autenticación heredada (v2)",
"WebDAV" : "WebDAV",
"URL" : "URL",
"Remote subfolder" : "Subcarpeta remota",
diff --git a/apps/files_external/l10n/es.json b/apps/files_external/l10n/es.json
index 0c6ab09d88d..79c81accd58 100644
--- a/apps/files_external/l10n/es.json
+++ b/apps/files_external/l10n/es.json
@@ -73,6 +73,7 @@
"Region" : "Región",
"Enable SSL" : "Habilitar SSL",
"Enable Path Style" : "Habilitar Estilo de Ruta",
+ "Legacy (v2) authentication" : "Autenticación heredada (v2)",
"WebDAV" : "WebDAV",
"URL" : "URL",
"Remote subfolder" : "Subcarpeta remota",
diff --git a/apps/files_external/l10n/hu.js b/apps/files_external/l10n/hu.js
index 81eddd893a0..8dcecbaeffb 100644
--- a/apps/files_external/l10n/hu.js
+++ b/apps/files_external/l10n/hu.js
@@ -75,6 +75,7 @@ OC.L10N.register(
"Region" : "Megye",
"Enable SSL" : "SSL engedélyezése",
"Enable Path Style" : "Útvonal stílus engedélyezés",
+ "Legacy (v2) authentication" : "Elavult (v2) authetikáció",
"WebDAV" : "WebDAV",
"URL" : "URL",
"Remote subfolder" : "Távoli almappa",
diff --git a/apps/files_external/l10n/hu.json b/apps/files_external/l10n/hu.json
index f05459b00b9..fc51260454c 100644
--- a/apps/files_external/l10n/hu.json
+++ b/apps/files_external/l10n/hu.json
@@ -73,6 +73,7 @@
"Region" : "Megye",
"Enable SSL" : "SSL engedélyezése",
"Enable Path Style" : "Útvonal stílus engedélyezés",
+ "Legacy (v2) authentication" : "Elavult (v2) authetikáció",
"WebDAV" : "WebDAV",
"URL" : "URL",
"Remote subfolder" : "Távoli almappa",
diff --git a/apps/files_external/l10n/it.js b/apps/files_external/l10n/it.js
index e19f6a657db..4bd2908b431 100644
--- a/apps/files_external/l10n/it.js
+++ b/apps/files_external/l10n/it.js
@@ -75,6 +75,7 @@ OC.L10N.register(
"Region" : "Regione",
"Enable SSL" : "Abilita SSL",
"Enable Path Style" : "Abilita stile percorsi",
+ "Legacy (v2) authentication" : "Autenticazione tradizionale (v2)",
"WebDAV" : "WebDAV",
"URL" : "URL",
"Remote subfolder" : "Sottocartella remota",
diff --git a/apps/files_external/l10n/it.json b/apps/files_external/l10n/it.json
index ecb8d2082e6..36d4b296199 100644
--- a/apps/files_external/l10n/it.json
+++ b/apps/files_external/l10n/it.json
@@ -73,6 +73,7 @@
"Region" : "Regione",
"Enable SSL" : "Abilita SSL",
"Enable Path Style" : "Abilita stile percorsi",
+ "Legacy (v2) authentication" : "Autenticazione tradizionale (v2)",
"WebDAV" : "WebDAV",
"URL" : "URL",
"Remote subfolder" : "Sottocartella remota",
diff --git a/apps/files_external/l10n/ka_GE.js b/apps/files_external/l10n/ka_GE.js
index ff2f4e9afab..782242ae5dc 100644
--- a/apps/files_external/l10n/ka_GE.js
+++ b/apps/files_external/l10n/ka_GE.js
@@ -75,6 +75,7 @@ OC.L10N.register(
"Region" : "რეგიონი",
"Enable SSL" : "SSL-ის ამოქმედება",
"Enable Path Style" : "ბილიკის სტილის ამოქმედება",
+ "Legacy (v2) authentication" : "ლეგატი (ვ2) აუტენტიფიკაცია",
"WebDAV" : "WebDAV-ი",
"URL" : "URL",
"Remote subfolder" : "დისტანციური ქვე-დირექტორია",
diff --git a/apps/files_external/l10n/ka_GE.json b/apps/files_external/l10n/ka_GE.json
index 34f02298e85..7d9ebcdb3b1 100644
--- a/apps/files_external/l10n/ka_GE.json
+++ b/apps/files_external/l10n/ka_GE.json
@@ -73,6 +73,7 @@
"Region" : "რეგიონი",
"Enable SSL" : "SSL-ის ამოქმედება",
"Enable Path Style" : "ბილიკის სტილის ამოქმედება",
+ "Legacy (v2) authentication" : "ლეგატი (ვ2) აუტენტიფიკაცია",
"WebDAV" : "WebDAV-ი",
"URL" : "URL",
"Remote subfolder" : "დისტანციური ქვე-დირექტორია",
diff --git a/apps/files_external/l10n/ko.js b/apps/files_external/l10n/ko.js
index 192c5a1c5c0..f91f5f72320 100644
--- a/apps/files_external/l10n/ko.js
+++ b/apps/files_external/l10n/ko.js
@@ -75,6 +75,7 @@ OC.L10N.register(
"Region" : "지역",
"Enable SSL" : "SSL 사용",
"Enable Path Style" : "경로 스타일 사용",
+ "Legacy (v2) authentication" : "레거시(v2) 인증",
"WebDAV" : "WebDAV",
"URL" : "URL",
"Remote subfolder" : "원격 하위 폴더",
diff --git a/apps/files_external/l10n/ko.json b/apps/files_external/l10n/ko.json
index aa11d68aa48..4f2bd99e984 100644
--- a/apps/files_external/l10n/ko.json
+++ b/apps/files_external/l10n/ko.json
@@ -73,6 +73,7 @@
"Region" : "지역",
"Enable SSL" : "SSL 사용",
"Enable Path Style" : "경로 스타일 사용",
+ "Legacy (v2) authentication" : "레거시(v2) 인증",
"WebDAV" : "WebDAV",
"URL" : "URL",
"Remote subfolder" : "원격 하위 폴더",
diff --git a/apps/files_external/l10n/nl.js b/apps/files_external/l10n/nl.js
index 2749e59e11b..5e53b24ddc6 100644
--- a/apps/files_external/l10n/nl.js
+++ b/apps/files_external/l10n/nl.js
@@ -75,6 +75,7 @@ OC.L10N.register(
"Region" : "Regio",
"Enable SSL" : "Activeren SSL",
"Enable Path Style" : "Activeren pad stijl",
+ "Legacy (v2) authentication" : "Legacy (v2) authenticatie",
"WebDAV" : "WebDAV",
"URL" : "URL",
"Remote subfolder" : "Externe submap",
diff --git a/apps/files_external/l10n/nl.json b/apps/files_external/l10n/nl.json
index 8258427503a..ee2ffa25a93 100644
--- a/apps/files_external/l10n/nl.json
+++ b/apps/files_external/l10n/nl.json
@@ -73,6 +73,7 @@
"Region" : "Regio",
"Enable SSL" : "Activeren SSL",
"Enable Path Style" : "Activeren pad stijl",
+ "Legacy (v2) authentication" : "Legacy (v2) authenticatie",
"WebDAV" : "WebDAV",
"URL" : "URL",
"Remote subfolder" : "Externe submap",
diff --git a/apps/files_external/l10n/pt_BR.js b/apps/files_external/l10n/pt_BR.js
index 077b89e1cf7..c2fe422e7b3 100644
--- a/apps/files_external/l10n/pt_BR.js
+++ b/apps/files_external/l10n/pt_BR.js
@@ -75,6 +75,7 @@ OC.L10N.register(
"Region" : "Região",
"Enable SSL" : "Habilitar SSL",
"Enable Path Style" : "Habilitar Estilo do Caminho",
+ "Legacy (v2) authentication" : "Autenticação (v2) herdada",
"WebDAV" : "WebDAV",
"URL" : "URL",
"Remote subfolder" : "Subpasta remota",
diff --git a/apps/files_external/l10n/pt_BR.json b/apps/files_external/l10n/pt_BR.json
index f9472a5c79d..4f5550870c5 100644
--- a/apps/files_external/l10n/pt_BR.json
+++ b/apps/files_external/l10n/pt_BR.json
@@ -73,6 +73,7 @@
"Region" : "Região",
"Enable SSL" : "Habilitar SSL",
"Enable Path Style" : "Habilitar Estilo do Caminho",
+ "Legacy (v2) authentication" : "Autenticação (v2) herdada",
"WebDAV" : "WebDAV",
"URL" : "URL",
"Remote subfolder" : "Subpasta remota",
diff --git a/apps/files_external/l10n/sr.js b/apps/files_external/l10n/sr.js
index ddff1a6a318..bd94b6dd843 100644
--- a/apps/files_external/l10n/sr.js
+++ b/apps/files_external/l10n/sr.js
@@ -75,6 +75,7 @@ OC.L10N.register(
"Region" : "Регија",
"Enable SSL" : "Омогући ССЛ",
"Enable Path Style" : "Омогући стил путање",
+ "Legacy (v2) authentication" : "Стара (v2) провера идентитета",
"WebDAV" : "ВебДАВ",
"URL" : "УРЛ",
"Remote subfolder" : "Удаљена потфасцикла",
diff --git a/apps/files_external/l10n/sr.json b/apps/files_external/l10n/sr.json
index 15b84d8ac51..7aa88bfaade 100644
--- a/apps/files_external/l10n/sr.json
+++ b/apps/files_external/l10n/sr.json
@@ -73,6 +73,7 @@
"Region" : "Регија",
"Enable SSL" : "Омогући ССЛ",
"Enable Path Style" : "Омогући стил путање",
+ "Legacy (v2) authentication" : "Стара (v2) провера идентитета",
"WebDAV" : "ВебДАВ",
"URL" : "УРЛ",
"Remote subfolder" : "Удаљена потфасцикла",
diff --git a/apps/files_external/l10n/tr.js b/apps/files_external/l10n/tr.js
index 152963db282..1def1246fde 100644
--- a/apps/files_external/l10n/tr.js
+++ b/apps/files_external/l10n/tr.js
@@ -75,6 +75,7 @@ OC.L10N.register(
"Region" : "Bölge",
"Enable SSL" : "SSL Kullanılsın",
"Enable Path Style" : "Yol Stili Kullanılsın",
+ "Legacy (v2) authentication" : "Eski (v2) kimlik doğrulama",
"WebDAV" : "WebDAV",
"URL" : "Adres",
"Remote subfolder" : "Uzak alt klasör",
diff --git a/apps/files_external/l10n/tr.json b/apps/files_external/l10n/tr.json
index efa75513f54..ea9fbc84c5f 100644
--- a/apps/files_external/l10n/tr.json
+++ b/apps/files_external/l10n/tr.json
@@ -73,6 +73,7 @@
"Region" : "Bölge",
"Enable SSL" : "SSL Kullanılsın",
"Enable Path Style" : "Yol Stili Kullanılsın",
+ "Legacy (v2) authentication" : "Eski (v2) kimlik doğrulama",
"WebDAV" : "WebDAV",
"URL" : "Adres",
"Remote subfolder" : "Uzak alt klasör",
diff --git a/apps/files_sharing/l10n/ko.js b/apps/files_sharing/l10n/ko.js
index aad92ab9ef6..5f8e4374ab8 100644
--- a/apps/files_sharing/l10n/ko.js
+++ b/apps/files_sharing/l10n/ko.js
@@ -15,7 +15,7 @@ OC.L10N.register(
"Invalid server URL" : "잘못된 서버 URL",
"Failed to add the public link to your Nextcloud" : "Nextcloud에 공개 링크를 추가할 수 없음",
"Share" : "공유",
- "No expiration date set" : "만료 날짜가 설정되지 않음",
+ "No expiration date set" : "만료 날짜가 설정되지 않았음",
"Shared by" : "공유한 사용자:",
"Sharing" : "공유",
"File shares" : "파일 공유",
@@ -71,17 +71,17 @@ OC.L10N.register(
"Wrong path, file/folder doesn't exist" : "잘못된 경로, 파일/폴더가 존재하지 않음",
"Could not create share" : "공유를 만들 수 없음",
"invalid permissions" : "잘못된 권한",
- "Please specify a valid user" : "유효한 사용자를 지정하십시오",
- "Group sharing is disabled by the administrator" : "그룹 공유는 관리자에 의해 비활성화되어 있음",
- "Please specify a valid group" : "유효한 그룹을 지정하십시오",
- "Public link sharing is disabled by the administrator" : "공개 링크 공유는 관리자에 의해 비활성화되어 있음",
+ "Please specify a valid user" : "올바른 사용자를 지정하십시오",
+ "Group sharing is disabled by the administrator" : "관리자가 그룹 공유를 비활성화함",
+ "Please specify a valid group" : "올바른 그룹을 지정하십시오",
+ "Public link sharing is disabled by the administrator" : "관리자가 공개 링크 공유를 비활성화함",
"Public upload disabled by the administrator" : "공개 업로드는 관리자에 의해 비활성화되어 있음",
"Public upload is only possible for publicly shared folders" : "공개 공유 폴더에만 공개 업로드를 사용할 수 있음",
"Invalid date, date format must be YYYY-MM-DD" : "잘못된 날짜, YYYY-MM-DD 형식이어야 합니다.",
"Sharing %s failed because the back end does not allow shares from type %s" : "%s을(를) 공유할 수 없습니다. 백엔드에서 %s 형식의 공유를 지원하지 않습니다",
"You cannot share to a Circle if the app is not enabled" : "서클 앱이 활성화되어 있지 않으면 서클로 공유할 수 없음",
"Please specify a valid circle" : "올바른 서클을 지정하십시오",
- "Unknown share type" : "알 수 없는 공유 유형",
+ "Unknown share type" : "알 수 없는 공유 형식",
"Not a directory" : "디렉터리가 아님",
"Could not lock path" : "경로를 잠글 수 없음",
"Wrong or no update parameter given" : "업데이트 인자가 잘못되었거나 지정되지 않았음",
diff --git a/apps/files_sharing/l10n/ko.json b/apps/files_sharing/l10n/ko.json
index d60145d5faf..00c5d8b954a 100644
--- a/apps/files_sharing/l10n/ko.json
+++ b/apps/files_sharing/l10n/ko.json
@@ -13,7 +13,7 @@
"Invalid server URL" : "잘못된 서버 URL",
"Failed to add the public link to your Nextcloud" : "Nextcloud에 공개 링크를 추가할 수 없음",
"Share" : "공유",
- "No expiration date set" : "만료 날짜가 설정되지 않음",
+ "No expiration date set" : "만료 날짜가 설정되지 않았음",
"Shared by" : "공유한 사용자:",
"Sharing" : "공유",
"File shares" : "파일 공유",
@@ -69,17 +69,17 @@
"Wrong path, file/folder doesn't exist" : "잘못된 경로, 파일/폴더가 존재하지 않음",
"Could not create share" : "공유를 만들 수 없음",
"invalid permissions" : "잘못된 권한",
- "Please specify a valid user" : "유효한 사용자를 지정하십시오",
- "Group sharing is disabled by the administrator" : "그룹 공유는 관리자에 의해 비활성화되어 있음",
- "Please specify a valid group" : "유효한 그룹을 지정하십시오",
- "Public link sharing is disabled by the administrator" : "공개 링크 공유는 관리자에 의해 비활성화되어 있음",
+ "Please specify a valid user" : "올바른 사용자를 지정하십시오",
+ "Group sharing is disabled by the administrator" : "관리자가 그룹 공유를 비활성화함",
+ "Please specify a valid group" : "올바른 그룹을 지정하십시오",
+ "Public link sharing is disabled by the administrator" : "관리자가 공개 링크 공유를 비활성화함",
"Public upload disabled by the administrator" : "공개 업로드는 관리자에 의해 비활성화되어 있음",
"Public upload is only possible for publicly shared folders" : "공개 공유 폴더에만 공개 업로드를 사용할 수 있음",
"Invalid date, date format must be YYYY-MM-DD" : "잘못된 날짜, YYYY-MM-DD 형식이어야 합니다.",
"Sharing %s failed because the back end does not allow shares from type %s" : "%s을(를) 공유할 수 없습니다. 백엔드에서 %s 형식의 공유를 지원하지 않습니다",
"You cannot share to a Circle if the app is not enabled" : "서클 앱이 활성화되어 있지 않으면 서클로 공유할 수 없음",
"Please specify a valid circle" : "올바른 서클을 지정하십시오",
- "Unknown share type" : "알 수 없는 공유 유형",
+ "Unknown share type" : "알 수 없는 공유 형식",
"Not a directory" : "디렉터리가 아님",
"Could not lock path" : "경로를 잠글 수 없음",
"Wrong or no update parameter given" : "업데이트 인자가 잘못되었거나 지정되지 않았음",
diff --git a/apps/files_sharing/lib/External/Mount.php b/apps/files_sharing/lib/External/Mount.php
index d756a1830b2..e12f8823cd8 100644
--- a/apps/files_sharing/lib/External/Mount.php
+++ b/apps/files_sharing/lib/External/Mount.php
@@ -68,4 +68,14 @@ class Mount extends MountPoint implements MoveableMount {
public function removeMount() {
return $this->manager->removeShare($this->mountPoint);
}
+
+ /**
+ * Get the type of mount point, used to distinguish things like shares and external storages
+ * in the web interface
+ *
+ * @return string
+ */
+ public function getMountType() {
+ return 'shared';
+ }
}
diff --git a/apps/sharebymail/l10n/sv.js b/apps/sharebymail/l10n/sv.js
index eb3b8451e6b..03789a8af96 100644
--- a/apps/sharebymail/l10n/sv.js
+++ b/apps/sharebymail/l10n/sv.js
@@ -5,9 +5,9 @@ OC.L10N.register(
"Shared with {email}" : "Delad med {email}",
"Shared with %1$s by %2$s" : "Delad med %1$s av %2$s",
"Shared with {email} by {actor}" : "Delad med {email} av {actor}",
- "Password for mail share sent to %1$s" : "Lösenord för maildelning sändes till %1$s",
- "Password for mail share sent to {email}" : "Lösenord för maildelning skickat till {email}",
- "Password for mail share sent to you" : "Lösenord för epostdelning skickat till dig",
+ "Password for mail share sent to %1$s" : "Lösenord för e-postdelning sändes till %1$s",
+ "Password for mail share sent to {email}" : "Lösenord för e-postdelning skickat till {email}",
+ "Password for mail share sent to you" : "Lösenord för e-postdelning skickat till dig",
"You shared %1$s with %2$s by mail" : "Du delade %1$s med %2$s via e-post",
"You shared {file} with {email} by mail" : "Du delade {file} med {email} via e-post",
"%3$s shared %1$s with %2$s by mail" : "%3$s delade %1$s med %2$s via e-post",
@@ -17,15 +17,15 @@ OC.L10N.register(
"Password to access %1$s was sent to you" : "Lösenord för att nå %1$s sändes till dig",
"Password to access {file} was sent to you" : "Lösenord till {file} sändes till dig",
"Sharing %s failed, this item is already shared with %s" : "Delning av %s misslyckades, det är redan delat med %s",
- "We can't send you the auto-generated password. Please set a valid email address in your personal settings and try again." : "Vi kan inte sända dig det autogenererade lösenordet. Vänligen ange en giltig epost-adress i dina personliga inställningar och försök igen.",
+ "We can't send you the auto-generated password. Please set a valid email address in your personal settings and try again." : "Vi kan inte skicka det autogenererade lösenordet till dig. Vänligen ange en giltig e-postadress i dina personliga inställningar och försök igen.",
"Failed to send share by email" : "Misslyckades att sända delning med e-post",
"%s shared »%s« with you" : "%s delade »%s« med dig",
"%s shared »%s« with you." : "%s delade »%s« med dig.",
- "Click the button below to open it." : "Klicka knappen nedan för att öppna det.",
+ "Click the button below to open it." : "Klicka på knappen nedan för att öppna det.",
"Open »%s«" : "Öppna »%s«",
"%s via %s" : "%s via %s",
- "%s shared »%s« with you.\nYou should have already received a separate mail with a link to access it.\n" : "%s delade »%s« med dig.\nDu ska redan ha fått ett separat epost med en länk för att nå det.\n",
- "%s shared »%s« with you. You should have already received a separate mail with a link to access it." : "%s delade »%s« med dig. Du ska redan ha fått ett separat e-post med en länk för att nå det.",
+ "%s shared »%s« with you.\nYou should have already received a separate mail with a link to access it.\n" : "%s delade »%s« med dig.\nDu ska redan ha fått ett separat mail med en länk för att komma åt det.\n",
+ "%s shared »%s« with you. You should have already received a separate mail with a link to access it." : "%s delade »%s« med dig. Du ska redan ha fått ett separat mail med en länk för att komma åt det.",
"Password to access »%s« shared to you by %s" : "Lösenord för att få tillgång till »%s« delat med dig av %s",
"Password to access »%s«" : "Lösenord för att nå »%s«",
"It is protected with the following password: %s" : "Den är skyddad med följande lösenord: %s",
@@ -35,8 +35,8 @@ OC.L10N.register(
"You can choose a different password at any time in the share dialog." : "Du kan välja ett annat lösenord när som helst i delningsdialogen.",
"Could not find share" : "Kunde inte hitta delning",
"Share by mail" : "Dela via e-post",
- "Allows users to share a personalized link to a file or folder by putting in an email address." : "Tillåt användare att dela en personlig länk till en fil eller mapp genom att ange en e-post-adress",
- "Send password by mail" : "Skicka lösenord med e-post",
+ "Allows users to share a personalized link to a file or folder by putting in an email address." : "Tillåt användare att dela en personlig länk till en fil eller mapp genom att ange en e-postadress",
+ "Send password by mail" : "Skicka lösenord via e-post",
"Enforce password protection" : "Tvinga lösenordsskydd",
"Failed to send share by E-mail" : "Misslyckades att dela via e-post",
"%s shared »%s« with you on behalf of %s" : "%s delade »%s« med dig på begäran av %s",
diff --git a/apps/sharebymail/l10n/sv.json b/apps/sharebymail/l10n/sv.json
index 75e3bb9d299..ced3fece128 100644
--- a/apps/sharebymail/l10n/sv.json
+++ b/apps/sharebymail/l10n/sv.json
@@ -3,9 +3,9 @@
"Shared with {email}" : "Delad med {email}",
"Shared with %1$s by %2$s" : "Delad med %1$s av %2$s",
"Shared with {email} by {actor}" : "Delad med {email} av {actor}",
- "Password for mail share sent to %1$s" : "Lösenord för maildelning sändes till %1$s",
- "Password for mail share sent to {email}" : "Lösenord för maildelning skickat till {email}",
- "Password for mail share sent to you" : "Lösenord för epostdelning skickat till dig",
+ "Password for mail share sent to %1$s" : "Lösenord för e-postdelning sändes till %1$s",
+ "Password for mail share sent to {email}" : "Lösenord för e-postdelning skickat till {email}",
+ "Password for mail share sent to you" : "Lösenord för e-postdelning skickat till dig",
"You shared %1$s with %2$s by mail" : "Du delade %1$s med %2$s via e-post",
"You shared {file} with {email} by mail" : "Du delade {file} med {email} via e-post",
"%3$s shared %1$s with %2$s by mail" : "%3$s delade %1$s med %2$s via e-post",
@@ -15,15 +15,15 @@
"Password to access %1$s was sent to you" : "Lösenord för att nå %1$s sändes till dig",
"Password to access {file} was sent to you" : "Lösenord till {file} sändes till dig",
"Sharing %s failed, this item is already shared with %s" : "Delning av %s misslyckades, det är redan delat med %s",
- "We can't send you the auto-generated password. Please set a valid email address in your personal settings and try again." : "Vi kan inte sända dig det autogenererade lösenordet. Vänligen ange en giltig epost-adress i dina personliga inställningar och försök igen.",
+ "We can't send you the auto-generated password. Please set a valid email address in your personal settings and try again." : "Vi kan inte skicka det autogenererade lösenordet till dig. Vänligen ange en giltig e-postadress i dina personliga inställningar och försök igen.",
"Failed to send share by email" : "Misslyckades att sända delning med e-post",
"%s shared »%s« with you" : "%s delade »%s« med dig",
"%s shared »%s« with you." : "%s delade »%s« med dig.",
- "Click the button below to open it." : "Klicka knappen nedan för att öppna det.",
+ "Click the button below to open it." : "Klicka på knappen nedan för att öppna det.",
"Open »%s«" : "Öppna »%s«",
"%s via %s" : "%s via %s",
- "%s shared »%s« with you.\nYou should have already received a separate mail with a link to access it.\n" : "%s delade »%s« med dig.\nDu ska redan ha fått ett separat epost med en länk för att nå det.\n",
- "%s shared »%s« with you. You should have already received a separate mail with a link to access it." : "%s delade »%s« med dig. Du ska redan ha fått ett separat e-post med en länk för att nå det.",
+ "%s shared »%s« with you.\nYou should have already received a separate mail with a link to access it.\n" : "%s delade »%s« med dig.\nDu ska redan ha fått ett separat mail med en länk för att komma åt det.\n",
+ "%s shared »%s« with you. You should have already received a separate mail with a link to access it." : "%s delade »%s« med dig. Du ska redan ha fått ett separat mail med en länk för att komma åt det.",
"Password to access »%s« shared to you by %s" : "Lösenord för att få tillgång till »%s« delat med dig av %s",
"Password to access »%s«" : "Lösenord för att nå »%s«",
"It is protected with the following password: %s" : "Den är skyddad med följande lösenord: %s",
@@ -33,8 +33,8 @@
"You can choose a different password at any time in the share dialog." : "Du kan välja ett annat lösenord när som helst i delningsdialogen.",
"Could not find share" : "Kunde inte hitta delning",
"Share by mail" : "Dela via e-post",
- "Allows users to share a personalized link to a file or folder by putting in an email address." : "Tillåt användare att dela en personlig länk till en fil eller mapp genom att ange en e-post-adress",
- "Send password by mail" : "Skicka lösenord med e-post",
+ "Allows users to share a personalized link to a file or folder by putting in an email address." : "Tillåt användare att dela en personlig länk till en fil eller mapp genom att ange en e-postadress",
+ "Send password by mail" : "Skicka lösenord via e-post",
"Enforce password protection" : "Tvinga lösenordsskydd",
"Failed to send share by E-mail" : "Misslyckades att dela via e-post",
"%s shared »%s« with you on behalf of %s" : "%s delade »%s« med dig på begäran av %s",
diff --git a/apps/theming/css/theming.scss b/apps/theming/css/theming.scss
index 4474c232d94..63d466542e1 100644
--- a/apps/theming/css/theming.scss
+++ b/apps/theming/css/theming.scss
@@ -1,3 +1,12 @@
+/** Calculate luma as it is also used in OCA\Theming\Util::calculateLuma */
+@function luma($c) {
+ $-local-red: red(rgba($c, 1.0));
+ $-local-green: green(rgba($c, 1.0));
+ $-local-blue: blue(rgba($c, 1.0));
+
+ @return (0.2126 * $-local-red + 0.7152 * $-local-green + 0.0722 * $-local-blue) / 255;
+}
+
.nc-theming-main-background {
background-color: $color-primary;
}
@@ -10,7 +19,13 @@
color: $color-primary-text;
}
-@if (lightness($color-primary) > 55) {
+@if (luma($color-primary) > 0.6) {
+ #appmenu:not(.inverted) svg {
+ filter: invert(1);
+ }
+ #appmenu.inverted svg {
+ filter: none;
+ }
.searchbox input[type="search"] {
background: transparent url('../../../core/img/actions/search.svg') no-repeat 6px center;
}
@@ -53,6 +68,13 @@
background-color: nc-darken($color-primary-element, 30%) !important;
}
}
+} @else {
+ #appmenu:not(.inverted) svg {
+ filter: none;
+ }
+ #appmenu.inverted svg {
+ filter: invert(1);
+ }
}
/* Colorized svg images */
@@ -90,8 +112,8 @@ input.primary,
color: $color-primary-text;
}
-@if (lightness($color-primary) > 50) {
- #body-login #submit-icon.icon-confirm-white {
+@if (luma($color-primary) > 0.6) {
+ #body-login #submit-wrapper .icon-confirm-white {
background-image: url('../../../core/img/actions/confirm.svg');
}
}
diff --git a/apps/theming/lib/Capabilities.php b/apps/theming/lib/Capabilities.php
index 1b6bb8927be..a75403a1fd5 100644
--- a/apps/theming/lib/Capabilities.php
+++ b/apps/theming/lib/Capabilities.php
@@ -81,6 +81,8 @@ class Capabilities implements IPublicCapability {
'background' => $backgroundLogo === 'backgroundColor' ?
$this->theming->getColorPrimary() :
$this->url->getAbsoluteURL($this->theming->getBackground()),
+ 'background-plain' => $backgroundLogo === 'backgroundColor',
+ 'background-default' => !$this->util->isBackgroundThemed(),
],
];
}
diff --git a/apps/theming/lib/Controller/ThemingController.php b/apps/theming/lib/Controller/ThemingController.php
index b7777f1f907..6592eb7f7ab 100644
--- a/apps/theming/lib/Controller/ThemingController.php
+++ b/apps/theming/lib/Controller/ThemingController.php
@@ -176,7 +176,7 @@ class ThemingController extends Controller {
$this->themingDefaults->set($setting, $value);
// reprocess server scss for preview
- $cssCached = $this->scssCacher->process(\OC::$SERVERROOT, '/core/css/server.scss', 'core');
+ $cssCached = $this->scssCacher->process(\OC::$SERVERROOT, 'core/css/server.scss', 'core');
return new DataResponse(
[
@@ -324,7 +324,7 @@ class ThemingController extends Controller {
public function undo($setting) {
$value = $this->themingDefaults->undo($setting);
// reprocess server scss for preview
- $cssCached = $this->scssCacher->process(\OC::$SERVERROOT, '/core/css/server.scss', 'core');
+ $cssCached = $this->scssCacher->process(\OC::$SERVERROOT, 'core/css/server.scss', 'core');
if($setting === 'logoMime') {
try {
diff --git a/apps/theming/lib/ThemingDefaults.php b/apps/theming/lib/ThemingDefaults.php
index 05d387e6273..9dcc981817e 100644
--- a/apps/theming/lib/ThemingDefaults.php
+++ b/apps/theming/lib/ThemingDefaults.php
@@ -196,22 +196,13 @@ class ThemingDefaults extends \OC_Defaults {
* @return string
*/
public function getBackground() {
- $backgroundLogo = $this->config->getAppValue('theming', 'backgroundMime',false);
-
- $backgroundExists = true;
- try {
- $this->appData->getFolder('images')->getFile('background');
- } catch (\Exception $e) {
- $backgroundExists = false;
- }
-
$cacheBusterCounter = $this->config->getAppValue('theming', 'cachebuster', '0');
- if(!$backgroundLogo || !$backgroundExists) {
- return $this->urlGenerator->imagePath('core','background.png') . '?v=' . $cacheBusterCounter;
+ if($this->util->isBackgroundThemed()) {
+ return $this->urlGenerator->linkToRoute('theming.Theming.getLoginBackground') . '?v=' . $cacheBusterCounter;
}
- return $this->urlGenerator->linkToRoute('theming.Theming.getLoginBackground') . '?v=' . $cacheBusterCounter;
+ return $this->urlGenerator->imagePath('core','background.png') . '?v=' . $cacheBusterCounter;
}
/**
diff --git a/apps/theming/lib/Util.php b/apps/theming/lib/Util.php
index 194b5eeb0d0..2f6f4128365 100644
--- a/apps/theming/lib/Util.php
+++ b/apps/theming/lib/Util.php
@@ -63,8 +63,8 @@ class Util {
* @return bool
*/
public function invertTextColor($color) {
- $l = $this->calculateLuminance($color);
- if($l>0.55) {
+ $l = $this->calculateLuma($color);
+ if($l>0.6) {
return true;
} else {
return false;
@@ -90,6 +90,26 @@ class Util {
* @return float
*/
public function calculateLuminance($color) {
+ list($red, $green, $blue) = $this->hexToRGB($color);
+ $compiler = new Compiler();
+ $hsl = $compiler->toHSL($red, $green, $blue);
+ return $hsl[3]/100;
+ }
+
+ /**
+ * @param string $color rgb color value
+ * @return float
+ */
+ public function calculateLuma($color) {
+ list($red, $green, $blue) = $this->hexToRGB($color);
+ return (0.2126 * $red + 0.7152 * $green + 0.0722 * $blue) / 255;
+ }
+
+ /**
+ * @param string $color rgb color value
+ * @return int[]
+ */
+ public function hexToRGB($color) {
$hex = preg_replace("/[^0-9A-Fa-f]/", '', $color);
if (strlen($hex) === 3) {
$hex = $hex{0} . $hex{0} . $hex{1} . $hex{1} . $hex{2} . $hex{2};
@@ -97,12 +117,11 @@ class Util {
if (strlen($hex) !== 6) {
return 0;
}
- $red = hexdec(substr($hex, 0, 2));
- $green = hexdec(substr($hex, 2, 2));
- $blue = hexdec(substr($hex, 4, 2));
- $compiler = new Compiler();
- $hsl = $compiler->toHSL($red, $green, $blue);
- return $hsl[3]/100;
+ return [
+ hexdec(substr($hex, 0, 2)),
+ hexdec(substr($hex, 2, 2)),
+ hexdec(substr($hex, 4, 2))
+ ];
}
/**
@@ -216,4 +235,16 @@ class Util {
return false;
}
+ public function isBackgroundThemed() {
+ $backgroundLogo = $this->config->getAppValue('theming', 'backgroundMime',false);
+
+ $backgroundExists = true;
+ try {
+ $this->appData->getFolder('images')->getFile('background');
+ } catch (\Exception $e) {
+ $backgroundExists = false;
+ }
+ return $backgroundLogo && $backgroundLogo !== 'backgroundColor' && $backgroundExists;
+ }
+
}
diff --git a/apps/theming/tests/CapabilitiesTest.php b/apps/theming/tests/CapabilitiesTest.php
index c760c896425..31e0ae79970 100644
--- a/apps/theming/tests/CapabilitiesTest.php
+++ b/apps/theming/tests/CapabilitiesTest.php
@@ -50,6 +50,9 @@ class CapabilitiesTest extends TestCase {
/** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */
protected $config;
+ /** @var Util|\PHPUnit_Framework_MockObject_MockObject */
+ protected $util;
+
/** @var Capabilities */
protected $capabilities;
@@ -59,13 +62,13 @@ class CapabilitiesTest extends TestCase {
$this->theming = $this->createMock(ThemingDefaults::class);
$this->url = $this->getMockBuilder(IURLGenerator::class)->getMock();
$this->config = $this->createMock(IConfig::class);
- $util = new Util($this->config, $this->createMock(IAppManager::class), $this->createMock(IAppData::class));
- $this->capabilities = new Capabilities($this->theming, $util, $this->url, $this->config);
+ $this->util = $this->createMock(Util::class);
+ $this->capabilities = new Capabilities($this->theming, $this->util, $this->url, $this->config);
}
public function dataGetCapabilities() {
return [
- ['name', 'url', 'slogan', '#FFFFFF', '#000000', 'logo', 'background', 'http://absolute/', [
+ ['name', 'url', 'slogan', '#FFFFFF', '#000000', 'logo', 'background', 'http://absolute/', true, [
'name' => 'name',
'url' => 'url',
'slogan' => 'slogan',
@@ -74,8 +77,10 @@ class CapabilitiesTest extends TestCase {
'color-element' => '#555555',
'logo' => 'http://absolute/logo',
'background' => 'http://absolute/background',
+ 'background-plain' => false,
+ 'background-default' => false,
]],
- ['name1', 'url2', 'slogan3', '#01e4a0', '#ffffff', 'logo5', 'background6', 'http://localhost/', [
+ ['name1', 'url2', 'slogan3', '#01e4a0', '#ffffff', 'logo5', 'background6', 'http://localhost/', false, [
'name' => 'name1',
'url' => 'url2',
'slogan' => 'slogan3',
@@ -84,8 +89,22 @@ class CapabilitiesTest extends TestCase {
'color-element' => '#01e4a0',
'logo' => 'http://localhost/logo5',
'background' => 'http://localhost/background6',
+ 'background-plain' => false,
+ 'background-default' => true,
+ ]],
+ ['name1', 'url2', 'slogan3', '#000000', '#ffffff', 'logo5', 'backgroundColor', 'http://localhost/', true, [
+ 'name' => 'name1',
+ 'url' => 'url2',
+ 'slogan' => 'slogan3',
+ 'color' => '#000000',
+ 'color-text' => '#ffffff',
+ 'color-element' => '#000000',
+ 'logo' => 'http://localhost/logo5',
+ 'background' => '#000000',
+ 'background-plain' => true,
+ 'background-default' => false,
]],
- ['name1', 'url2', 'slogan3', '#000000', '#ffffff', 'logo5', 'backgroundColor', 'http://localhost/', [
+ ['name1', 'url2', 'slogan3', '#000000', '#ffffff', 'logo5', 'backgroundColor', 'http://localhost/', false, [
'name' => 'name1',
'url' => 'url2',
'slogan' => 'slogan3',
@@ -94,6 +113,8 @@ class CapabilitiesTest extends TestCase {
'color-element' => '#000000',
'logo' => 'http://localhost/logo5',
'background' => '#000000',
+ 'background-plain' => true,
+ 'background-default' => true,
]],
];
}
@@ -104,13 +125,14 @@ class CapabilitiesTest extends TestCase {
* @param string $url
* @param string $slogan
* @param string $color
- * @param string $logo
* @param string $textColor
+ * @param string $logo
* @param string $background
* @param string $baseUrl
+ * @param bool $backgroundThemed
* @param string[] $expected
*/
- public function testGetCapabilities($name, $url, $slogan, $color, $textColor, $logo, $background, $baseUrl, array $expected) {
+ public function testGetCapabilities($name, $url, $slogan, $color, $textColor, $logo, $background, $baseUrl, $backgroundThemed, array $expected) {
$this->config->expects($this->once())
->method('getAppValue')
->willReturn($background);
@@ -133,6 +155,16 @@ class CapabilitiesTest extends TestCase {
->method('getTextColorPrimary')
->willReturn($textColor);
+ $util = new Util($this->config, $this->createMock(IAppManager::class), $this->createMock(IAppData::class));
+ $this->util->expects($this->once())
+ ->method('elementColor')
+ ->with($color)
+ ->willReturn($util->elementColor($color));
+
+ $this->util->expects($this->once())
+ ->method('isBackgroundThemed')
+ ->willReturn($backgroundThemed);
+
if($background !== 'backgroundColor') {
$this->theming->expects($this->once())
->method('getBackground')
diff --git a/apps/theming/tests/ThemingDefaultsTest.php b/apps/theming/tests/ThemingDefaultsTest.php
index 843c1d34f9e..d0dc6587f74 100644
--- a/apps/theming/tests/ThemingDefaultsTest.php
+++ b/apps/theming/tests/ThemingDefaultsTest.php
@@ -391,24 +391,14 @@ class ThemingDefaultsTest extends TestCase {
}
public function testGetBackgroundDefault() {
- $this->appData->expects($this->once())
- ->method('getFolder')
- ->willThrowException(new NotFoundException());
- $this->config
- ->expects($this->at(0))
- ->method('getAppValue')
- ->with('theming', 'backgroundMime')
- ->willReturn('');
$this->config
- ->expects($this->at(1))
+ ->expects($this->once())
->method('getAppValue')
->with('theming', 'cachebuster', '0')
->willReturn('0');
- $this->appData
- ->expects($this->once())
- ->method('getFolder')
- ->with('images')
- ->willThrowException(new \Exception());
+ $this->util->expects($this->once())
+ ->method('isBackgroundThemed')
+ ->willReturn(false);
$this->urlGenerator->expects($this->once())
->method('imagePath')
->with('core', 'background.png')
@@ -417,24 +407,14 @@ class ThemingDefaultsTest extends TestCase {
}
public function testGetBackgroundCustom() {
- $folder = $this->createMock(ISimpleFolder::class);
- $file = $this->createMock(ISimpleFile::class);
- $folder->expects($this->once())
- ->method('getFile')
- ->willReturn($file);
- $this->appData->expects($this->once())
- ->method('getFolder')
- ->willReturn($folder);
$this->config
- ->expects($this->at(0))
- ->method('getAppValue')
- ->with('theming', 'backgroundMime', false)
- ->willReturn('image/svg+xml');
- $this->config
- ->expects($this->at(1))
+ ->expects($this->once())
->method('getAppValue')
->with('theming', 'cachebuster', '0')
->willReturn('0');
+ $this->util->expects($this->once())
+ ->method('isBackgroundThemed')
+ ->willReturn(true);
$this->urlGenerator->expects($this->once())
->method('linkToRoute')
->with('theming.Theming.getLoginBackground')
@@ -513,12 +493,12 @@ class ThemingDefaultsTest extends TestCase {
$this->config->expects($this->at(2))->method('getAppValue')->with('theming', 'backgroundMime', false)->willReturn('jpeg');
$this->config->expects($this->at(3))->method('getAppValue')->with('theming', 'logoMime', false)->willReturn('jpeg');
$this->config->expects($this->at(4))->method('getAppValue')->with('theming', 'cachebuster', '0')->willReturn('0');
- $this->config->expects($this->at(5))->method('getAppValue')->with('theming', 'backgroundMime', false)->willReturn('jpeg');
- $this->config->expects($this->at(6))->method('getAppValue')->with('theming', 'cachebuster', '0')->willReturn('0');
- $this->config->expects($this->at(7))->method('getAppValue')->with('theming', 'color', null)->willReturn($this->defaults->getColorPrimary());
+ $this->util->expects($this->once())->method('isBackgroundThemed')->willReturn(true);
+ $this->config->expects($this->at(5))->method('getAppValue')->with('theming', 'cachebuster', '0')->willReturn('0');
+ $this->config->expects($this->at(6))->method('getAppValue')->with('theming', 'color', null)->willReturn($this->defaults->getColorPrimary());
+ $this->config->expects($this->at(7))->method('getAppValue')->with('theming', 'color', $this->defaults->getColorPrimary())->willReturn($this->defaults->getColorPrimary());
$this->config->expects($this->at(8))->method('getAppValue')->with('theming', 'color', $this->defaults->getColorPrimary())->willReturn($this->defaults->getColorPrimary());
$this->config->expects($this->at(9))->method('getAppValue')->with('theming', 'color', $this->defaults->getColorPrimary())->willReturn($this->defaults->getColorPrimary());
- $this->config->expects($this->at(10))->method('getAppValue')->with('theming', 'color', $this->defaults->getColorPrimary())->willReturn($this->defaults->getColorPrimary());
$this->util->expects($this->any())->method('invertTextColor')->with($this->defaults->getColorPrimary())->willReturn(false);
$this->util->expects($this->any())->method('elementColor')->with($this->defaults->getColorPrimary())->willReturn('#aaaaaa');
diff --git a/apps/theming/tests/UtilTest.php b/apps/theming/tests/UtilTest.php
index 94e4c9cbcc8..247bcbae0b2 100644
--- a/apps/theming/tests/UtilTest.php
+++ b/apps/theming/tests/UtilTest.php
@@ -53,14 +53,20 @@ class UtilTest extends TestCase {
$this->util = new Util($this->config, $this->appManager, $this->appData);
}
- public function testInvertTextColorLight() {
- $invert = $this->util->invertTextColor('#ffffff');
- $this->assertEquals(true, $invert);
+ public function dataInvertTextColor() {
+ return [
+ ['#ffffff', true],
+ ['#000000', false],
+ ['#0082C9', false],
+ ['#ffff00', true],
+ ];
}
-
- public function testInvertTextColorDark() {
- $invert = $this->util->invertTextColor('#000000');
- $this->assertEquals(false, $invert);
+ /**
+ * @dataProvider dataInvertTextColor
+ */
+ public function testInvertTextColor($color, $expected) {
+ $invert = $this->util->invertTextColor($color);
+ $this->assertEquals($expected, $invert);
}
public function testCalculateLuminanceLight() {
@@ -183,7 +189,6 @@ class UtilTest extends TestCase {
}
public function testIsAlreadyThemedFalse() {
- $theme = $this->config->getSystemValue('theme', '');
$this->config->expects($this->once())
->method('getSystemValue')
->with('theme', '')
@@ -193,7 +198,6 @@ class UtilTest extends TestCase {
}
public function testIsAlreadyThemedTrue() {
- $theme = $this->config->getSystemValue('theme', '');
$this->config->expects($this->once())
->method('getSystemValue')
->with('theme', '')
@@ -202,4 +206,35 @@ class UtilTest extends TestCase {
$this->assertTrue($actual);
}
+ public function dataIsBackgroundThemed() {
+ return [
+ [false, false, false],
+ ['png', true, true],
+ ['backgroundColor', false, false],
+ ];
+ }
+ /**
+ * @dataProvider dataIsBackgroundThemed
+ */
+ public function testIsBackgroundThemed($backgroundMime, $fileFound, $expected) {
+ $this->config->expects($this->once())
+ ->method('getAppValue')
+ ->with('theming', 'backgroundMime', false)
+ ->willReturn($backgroundMime);
+ $folder = $this->createMock(ISimpleFolder::class);
+ if ($fileFound) {
+ $folder->expects($this->once())
+ ->method('getFile')
+ ->willReturn($this->createMock(ISimpleFile::class));
+ } else {
+ $folder->expects($this->once())
+ ->method('getFile')
+ ->willThrowException(new NotFoundException());
+ }
+ $this->appData->expects($this->once())
+ ->method('getFolder')
+ ->willReturn($folder);
+ $this->assertEquals($expected, $this->util->isBackgroundThemed());
+ }
+
}
diff --git a/apps/updatenotification/js/notification.js b/apps/updatenotification/js/notification.js
index a2e78cecb09..a588ede5ffd 100644
--- a/apps/updatenotification/js/notification.js
+++ b/apps/updatenotification/js/notification.js
@@ -17,10 +17,5 @@ $(document).ready(function(){
var text = t('core', '{version} is available. Get more information on how to update.', {version: oc_updateState.updateVersion}),
element = $('<a>').attr('href', oc_updateState.updateLink).attr('target','_blank').text(text);
- OC.Notification.show(element,
- {
- isHTML: true,
- type: 'error'
- }
- );
+ OC.Notification.showHtml(element, { type: 'error' });
});
diff --git a/apps/user_ldap/composer/composer/autoload_classmap.php b/apps/user_ldap/composer/composer/autoload_classmap.php
index 7bade37d9f7..98a1bbfa1b7 100644
--- a/apps/user_ldap/composer/composer/autoload_classmap.php
+++ b/apps/user_ldap/composer/composer/autoload_classmap.php
@@ -7,6 +7,7 @@ $baseDir = $vendorDir;
return array(
'OCA\\User_LDAP\\Access' => $baseDir . '/../lib/Access.php',
+ 'OCA\\User_LDAP\\AccessFactory' => $baseDir . '/../lib/AccessFactory.php',
'OCA\\User_LDAP\\AppInfo\\Application' => $baseDir . '/../lib/AppInfo/Application.php',
'OCA\\User_LDAP\\BackendUtility' => $baseDir . '/../lib/BackendUtility.php',
'OCA\\User_LDAP\\Command\\CheckUser' => $baseDir . '/../lib/Command/CheckUser.php',
@@ -19,6 +20,7 @@ return array(
'OCA\\User_LDAP\\Command\\TestConfig' => $baseDir . '/../lib/Command/TestConfig.php',
'OCA\\User_LDAP\\Configuration' => $baseDir . '/../lib/Configuration.php',
'OCA\\User_LDAP\\Connection' => $baseDir . '/../lib/Connection.php',
+ 'OCA\\User_LDAP\\ConnectionFactory' => $baseDir . '/../lib/ConnectionFactory.php',
'OCA\\User_LDAP\\Controller\\ConfigAPIController' => $baseDir . '/../lib/Controller/ConfigAPIController.php',
'OCA\\User_LDAP\\Controller\\RenewPasswordController' => $baseDir . '/../lib/Controller/RenewPasswordController.php',
'OCA\\User_LDAP\\Exceptions\\ConstraintViolationException' => $baseDir . '/../lib/Exceptions/ConstraintViolationException.php',
diff --git a/apps/user_ldap/composer/composer/autoload_static.php b/apps/user_ldap/composer/composer/autoload_static.php
index fbe63285273..6c97237d62d 100644
--- a/apps/user_ldap/composer/composer/autoload_static.php
+++ b/apps/user_ldap/composer/composer/autoload_static.php
@@ -19,6 +19,7 @@ class ComposerStaticInitUser_LDAP
public static $classMap = array (
'OCA\\User_LDAP\\Access' => __DIR__ . '/..' . '/../lib/Access.php',
+ 'OCA\\User_LDAP\\AccessFactory' => __DIR__ . '/..' . '/../lib/AccessFactory.php',
'OCA\\User_LDAP\\AppInfo\\Application' => __DIR__ . '/..' . '/../lib/AppInfo/Application.php',
'OCA\\User_LDAP\\BackendUtility' => __DIR__ . '/..' . '/../lib/BackendUtility.php',
'OCA\\User_LDAP\\Command\\CheckUser' => __DIR__ . '/..' . '/../lib/Command/CheckUser.php',
@@ -31,6 +32,7 @@ class ComposerStaticInitUser_LDAP
'OCA\\User_LDAP\\Command\\TestConfig' => __DIR__ . '/..' . '/../lib/Command/TestConfig.php',
'OCA\\User_LDAP\\Configuration' => __DIR__ . '/..' . '/../lib/Configuration.php',
'OCA\\User_LDAP\\Connection' => __DIR__ . '/..' . '/../lib/Connection.php',
+ 'OCA\\User_LDAP\\ConnectionFactory' => __DIR__ . '/..' . '/../lib/ConnectionFactory.php',
'OCA\\User_LDAP\\Controller\\ConfigAPIController' => __DIR__ . '/..' . '/../lib/Controller/ConfigAPIController.php',
'OCA\\User_LDAP\\Controller\\RenewPasswordController' => __DIR__ . '/..' . '/../lib/Controller/RenewPasswordController.php',
'OCA\\User_LDAP\\Exceptions\\ConstraintViolationException' => __DIR__ . '/..' . '/../lib/Exceptions/ConstraintViolationException.php',
diff --git a/apps/user_ldap/lib/AccessFactory.php b/apps/user_ldap/lib/AccessFactory.php
new file mode 100644
index 00000000000..45ff779bb01
--- /dev/null
+++ b/apps/user_ldap/lib/AccessFactory.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * @copyright Copyright (c) 2018 Arthur Schiwon <blizzz@arthur-schiwon.de>
+ *
+ * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\User_LDAP;
+
+
+use OCA\User_LDAP\User\Manager;
+use OCP\IConfig;
+
+class AccessFactory {
+ /** @var ILDAPWrapper */
+ protected $ldap;
+ /** @var Manager */
+ protected $userManager;
+ /** @var Helper */
+ protected $helper;
+ /** @var IConfig */
+ protected $config;
+
+ public function __construct(
+ ILDAPWrapper $ldap,
+ Manager $userManager,
+ Helper $helper,
+ IConfig $config)
+ {
+ $this->ldap = $ldap;
+ $this->userManager = $userManager;
+ $this->helper = $helper;
+ $this->config = $config;
+ }
+
+ public function get(Connection $connection) {
+ return new Access(
+ $connection,
+ $this->ldap,
+ $this->userManager,
+ $this->helper,
+ $this->config
+ );
+ }
+}
diff --git a/apps/user_ldap/lib/ConnectionFactory.php b/apps/user_ldap/lib/ConnectionFactory.php
new file mode 100644
index 00000000000..0857afdcc8d
--- /dev/null
+++ b/apps/user_ldap/lib/ConnectionFactory.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * @copyright Copyright (c) 2018 Arthur Schiwon <blizzz@arthur-schiwon.de>
+ *
+ * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\User_LDAP;
+
+
+class ConnectionFactory {
+ /** @var ILDAPWrapper */
+ private $ldap;
+
+ public function __construct(ILDAPWrapper $ldap) {
+ $this->ldap = $ldap;
+ }
+
+ public function get($prefix) {
+ return new Connection($this->ldap, $prefix, 'user_ldap');
+ }
+}
diff --git a/apps/user_ldap/lib/Jobs/Sync.php b/apps/user_ldap/lib/Jobs/Sync.php
index d8e0e854718..b78a1947e27 100644
--- a/apps/user_ldap/lib/Jobs/Sync.php
+++ b/apps/user_ldap/lib/Jobs/Sync.php
@@ -26,8 +26,10 @@ namespace OCA\User_LDAP\Jobs;
use OC\BackgroundJob\TimedJob;
use OC\ServerNotAvailableException;
use OCA\User_LDAP\Access;
+use OCA\User_LDAP\AccessFactory;
use OCA\User_LDAP\Configuration;
use OCA\User_LDAP\Connection;
+use OCA\User_LDAP\ConnectionFactory;
use OCA\User_LDAP\FilesystemHelper;
use OCA\User_LDAP\Helper;
use OCA\User_LDAP\LDAP;
@@ -62,6 +64,10 @@ class Sync extends TimedJob {
protected $ncUserManager;
/** @var IManager */
protected $notificationManager;
+ /** @var ConnectionFactory */
+ protected $connectionFactory;
+ /** @var AccessFactory */
+ protected $accessFactory;
public function __construct() {
$this->setInterval(
@@ -112,7 +118,7 @@ class Sync extends TimedJob {
/**
* @param array $argument
*/
- protected function run($argument) {
+ public function run($argument) {
$this->setArgument($argument);
$isBackgroundJobModeAjax = $this->config
@@ -140,11 +146,11 @@ class Sync extends TimedJob {
if ($expectMoreResults) {
$this->increaseOffset($cycleData);
} else {
- $this->determineNextCycle();
+ $this->determineNextCycle($cycleData);
}
$this->updateInterval();
} catch (ServerNotAvailableException $e) {
- $this->determineNextCycle();
+ $this->determineNextCycle($cycleData);
}
}
@@ -153,8 +159,8 @@ class Sync extends TimedJob {
* @return bool whether more results are expected from the same configuration
*/
public function runCycle($cycleData) {
- $connection = new Connection($this->ldap, $cycleData['prefix']);
- $access = new Access($connection, $this->ldap, $this->userManager, $this->ldapHelper, $this->config);
+ $connection = $this->connectionFactory->get($cycleData['prefix']);
+ $access = $this->accessFactory->get($connection);
$access->setUserMapper($this->mapper);
$filter = $access->combineFilterWithAnd(array(
@@ -173,7 +179,7 @@ class Sync extends TimedJob {
if($connection->ldapPagingSize === 0) {
return true;
}
- return count($results) !== $connection->ldapPagingSize;
+ return count($results) >= $connection->ldapPagingSize;
}
/**
@@ -246,7 +252,7 @@ class Sync extends TimedJob {
* @param $cycleData
* @return bool
*/
- protected function qualifiesToRun($cycleData) {
+ public function qualifiesToRun($cycleData) {
$lastChange = $this->config->getAppValue('user_ldap', $cycleData['prefix'] . '_lastChange', 0);
if((time() - $lastChange) > 60 * 30) {
return true;
@@ -358,5 +364,22 @@ class Sync extends TimedJob {
} else {
$this->mapper = new UserMapping($this->dbc);
}
+
+ if(isset($argument['connectionFactory'])) {
+ $this->connectionFactory = $argument['connectionFactory'];
+ } else {
+ $this->connectionFactory = new ConnectionFactory($this->ldap);
+ }
+
+ if(isset($argument['accessFactory'])) {
+ $this->accessFactory = $argument['accessFactory'];
+ } else {
+ $this->accessFactory = new AccessFactory(
+ $this->ldap,
+ $this->userManager,
+ $this->ldapHelper,
+ $this->config
+ );
+ }
}
}
diff --git a/apps/user_ldap/tests/Jobs/SyncTest.php b/apps/user_ldap/tests/Jobs/SyncTest.php
index f8a44de87e8..f8852a46664 100644
--- a/apps/user_ldap/tests/Jobs/SyncTest.php
+++ b/apps/user_ldap/tests/Jobs/SyncTest.php
@@ -23,6 +23,10 @@
namespace OCA\User_LDAP\Tests\Jobs;
+use OCA\User_LDAP\Access;
+use OCA\User_LDAP\AccessFactory;
+use OCA\User_LDAP\Connection;
+use OCA\User_LDAP\ConnectionFactory;
use OCA\User_LDAP\Helper;
use OCA\User_LDAP\Jobs\Sync;
use OCA\User_LDAP\LDAP;
@@ -33,6 +37,7 @@ use OCP\IConfig;
use OCP\IDBConnection;
use OCP\IUserManager;
use OCP\Notification\IManager;
+use function Sodium\memcmp;
use Test\TestCase;
class SyncTest extends TestCase {
@@ -59,6 +64,10 @@ class SyncTest extends TestCase {
protected $ncUserManager;
/** @var IManager|\PHPUnit_Framework_MockObject_MockObject */
protected $notificationManager;
+ /** @var ConnectionFactory|\PHPUnit_Framework_MockObject_MockObject */
+ protected $connectionFactory;
+ /** @var AccessFactory|\PHPUnit_Framework_MockObject_MockObject */
+ protected $accessFactory;
public function setUp() {
parent::setUp();
@@ -72,6 +81,8 @@ class SyncTest extends TestCase {
$this->dbc = $this->createMock(IDBConnection::class);
$this->ncUserManager = $this->createMock(IUserManager::class);
$this->notificationManager = $this->createMock(IManager::class);
+ $this->connectionFactory = $this->createMock(ConnectionFactory::class);
+ $this->accessFactory = $this->createMock(AccessFactory::class);
$this->arguments = [
'helper' => $this->helper,
@@ -83,6 +94,8 @@ class SyncTest extends TestCase {
'dbc' => $this->dbc,
'ncUserManager' => $this->ncUserManager,
'notificationManager' => $this->notificationManager,
+ 'connectionFactory' => $this->connectionFactory,
+ 'accessFactory' => $this->accessFactory,
];
$this->sync = new Sync();
@@ -141,4 +154,216 @@ class SyncTest extends TestCase {
$this->sync->updateInterval();
}
+ public function moreResultsProvider() {
+ return [
+ [ 3, 3, true ],
+ [ 3, 5, true ],
+ [ 3, 2, false]
+ ];
+ }
+
+ /**
+ * @dataProvider moreResultsProvider
+ */
+ public function testMoreResults($pagingSize, $results, $expected) {
+ $connection = $this->createMock(Connection::class);
+ $this->connectionFactory->expects($this->any())
+ ->method('get')
+ ->willReturn($connection);
+ $connection->expects($this->any())
+ ->method('__get')
+ ->willReturnCallback(function ($key) use ($pagingSize) {
+ if($key === 'ldapPagingSize') {
+ return $pagingSize;
+ }
+ return null;
+ });
+
+ /** @var Access|\PHPUnit_Framework_MockObject_MockObject $access */
+ $access = $this->createMock(Access::class);
+ $this->accessFactory->expects($this->any())
+ ->method('get')
+ ->with($connection)
+ ->willReturn($access);
+
+ $access->expects($this->once())
+ ->method('fetchListOfUsers')
+ ->willReturn(array_pad([], $results, 'someUser'));
+ $access->connection = $connection;
+ $access->userManager = $this->userManager;
+
+ $this->sync->setArgument($this->arguments);
+ $hasMoreResults = $this->sync->runCycle(['prefix' => 's01', 'offset' => 100]);
+ $this->assertSame($expected, $hasMoreResults);
+ }
+
+ public function cycleDataProvider() {
+ $lastCycle = ['prefix' => 's01', 'offset' => 1000];
+ $lastCycle2 = ['prefix' => '', 'offset' => 1000];
+ return [
+ [ null, ['s01'], ['prefix' => 's01', 'offset' => 0] ],
+ [ null, [''], ['prefix' => '', 'offset' => 0] ],
+ [ $lastCycle, ['s01', 's02'], ['prefix' => 's02', 'offset' => 0] ],
+ [ $lastCycle, [''], ['prefix' => '', 'offset' => 0] ],
+ [ $lastCycle2, ['', 's01'], ['prefix' => 's01', 'offset' => 0] ],
+ [ $lastCycle, [], null ],
+ ];
+ }
+
+ /**
+ * @dataProvider cycleDataProvider
+ */
+ public function testDetermineNextCycle($cycleData, $prefixes, $expectedCycle) {
+ $this->helper->expects($this->any())
+ ->method('getServerConfigurationPrefixes')
+ ->with(true)
+ ->willReturn($prefixes);
+
+ if(is_array($expectedCycle)) {
+ $this->config->expects($this->exactly(2))
+ ->method('setAppValue')
+ ->withConsecutive(
+ ['user_ldap', 'background_sync_prefix', $expectedCycle['prefix']],
+ ['user_ldap', 'background_sync_offset', $expectedCycle['offset']]
+ );
+ } else {
+ $this->config->expects($this->never())
+ ->method('setAppValue');
+ }
+
+ $this->sync->setArgument($this->arguments);
+ $nextCycle = $this->sync->determineNextCycle($cycleData);
+
+ if($expectedCycle === null) {
+ $this->assertNull($nextCycle);
+ } else {
+ $this->assertSame($expectedCycle['prefix'], $nextCycle['prefix']);
+ $this->assertSame($expectedCycle['offset'], $nextCycle['offset']);
+ }
+ }
+
+ public function testQualifiesToRun() {
+ $cycleData = ['prefix' => 's01'];
+
+ $this->config->expects($this->exactly(2))
+ ->method('getAppValue')
+ ->willReturnOnConsecutiveCalls(time() - 60*40, time() - 60*20);
+
+ $this->sync->setArgument($this->arguments);
+ $this->assertTrue($this->sync->qualifiesToRun($cycleData));
+ $this->assertFalse($this->sync->qualifiesToRun($cycleData));
+ }
+
+ public function runDataProvider() {
+ return [
+ #0 - one LDAP server, reset
+ [[
+ 'prefixes' => [''],
+ 'scheduledCycle' => ['prefix' => '', 'offset' => '4500'],
+ 'pagingSize' => 500,
+ 'usersThisCycle' => 0,
+ 'expectedNextCycle' => ['prefix' => '', 'offset' => '0'],
+ 'mappedUsers' => 123,
+ ]],
+ #1 - 2 LDAP servers, next prefix
+ [[
+ 'prefixes' => ['', 's01'],
+ 'scheduledCycle' => ['prefix' => '', 'offset' => '4500'],
+ 'pagingSize' => 500,
+ 'usersThisCycle' => 0,
+ 'expectedNextCycle' => ['prefix' => 's01', 'offset' => '0'],
+ 'mappedUsers' => 123,
+ ]],
+ #2 - 2 LDAP servers, rotate prefix
+ [[
+ 'prefixes' => ['', 's01'],
+ 'scheduledCycle' => ['prefix' => 's01', 'offset' => '4500'],
+ 'pagingSize' => 500,
+ 'usersThisCycle' => 0,
+ 'expectedNextCycle' => ['prefix' => '', 'offset' => '0'],
+ 'mappedUsers' => 123,
+ ]],
+ ];
+ }
+
+ /**
+ * @dataProvider runDataProvider
+ */
+ public function testRun($runData) {
+ $this->config->expects($this->any())
+ ->method('getAppValue')
+ ->willReturnCallback(function($app, $key, $default) use ($runData) {
+ if($app === 'core' && $key === 'backgroundjobs_mode') {
+ return 'cron';
+ }
+ if($app = 'user_ldap') {
+ // for getCycle()
+ if($key === 'background_sync_prefix') {
+ return $runData['scheduledCycle']['prefix'];
+ }
+ if($key === 'background_sync_offset') {
+ return $runData['scheduledCycle']['offset'];
+ }
+ // for qualifiesToRun()
+ if($key === $runData['scheduledCycle']['prefix'] . '_lastChange') {
+ return time() - 60*40;
+ }
+ // for getMinPagingSize
+ if($key === $runData['scheduledCycle']['prefix'] . 'ldap_paging_size') {
+ return $runData['pagingSize'];
+ }
+ }
+
+ return $default;
+ });
+ $this->config->expects($this->exactly(3))
+ ->method('setAppValue')
+ ->withConsecutive(
+ ['user_ldap', 'background_sync_prefix', $runData['expectedNextCycle']['prefix']],
+ ['user_ldap', 'background_sync_offset', $runData['expectedNextCycle']['offset']],
+ ['user_ldap', 'background_sync_interval', $this->anything()]
+ );
+ $this->config->expects($this->any())
+ ->method('getAppKeys')
+ ->with('user_ldap')
+ ->willReturn([$runData['scheduledCycle']['prefix'] . 'ldap_paging_size']);
+
+ $this->helper->expects($this->any())
+ ->method('getServerConfigurationPrefixes')
+ ->with(true)
+ ->willReturn($runData['prefixes']);
+
+ $connection = $this->createMock(Connection::class);
+ $this->connectionFactory->expects($this->any())
+ ->method('get')
+ ->willReturn($connection);
+ $connection->expects($this->any())
+ ->method('__get')
+ ->willReturnCallback(function ($key) use ($runData) {
+ if($key === 'ldapPagingSize') {
+ return $runData['pagingSize'];
+ }
+ return null;
+ });
+
+ /** @var Access|\PHPUnit_Framework_MockObject_MockObject $access */
+ $access = $this->createMock(Access::class);
+ $this->accessFactory->expects($this->any())
+ ->method('get')
+ ->with($connection)
+ ->willReturn($access);
+
+ $access->expects($this->once())
+ ->method('fetchListOfUsers')
+ ->willReturn(array_pad([], $runData['usersThisCycle'], 'someUser'));
+ $access->connection = $connection;
+ $access->userManager = $this->userManager;
+
+ $this->mapper->expects($this->any())
+ ->method('count')
+ ->willReturn($runData['mappedUsers']);
+
+ $this->sync->run($this->arguments);
+ }
+
}