diff options
author | Andreas Pflug <dev@admin4.org> | 2017-01-31 02:27:29 +0100 |
---|---|---|
committer | Andreas Pflug <dev@admin4.org> | 2017-01-31 02:27:29 +0100 |
commit | 07b203d12ffda9c6a92e374272d5c188855520a3 (patch) | |
tree | 56317aad08549c0c911f7b41e3772960086aee71 | |
parent | b64e48335f63662a43d0b7198fd013d4af521996 (diff) | |
parent | e50320dc71135bf546c757f7dea6e23f5f48a906 (diff) | |
download | nextcloud-server-07b203d12ffda9c6a92e374272d5c188855520a3.tar.gz nextcloud-server-07b203d12ffda9c6a92e374272d5c188855520a3.zip |
Merge branch 'master' of https://github.com/nextcloud/server into ldap_no-memberof-with-memberuid
44 files changed, 1037 insertions, 192 deletions
diff --git a/3rdparty b/3rdparty -Subproject f2d8ba7bfebb769835b637f01eaa602e36cdcca +Subproject 489bcf4f81e462f4d74f0b76f58caeabd58e75d diff --git a/apps/federation/l10n/lv.js b/apps/federation/l10n/lv.js index 8ceb8c09f16..ebb8c434086 100644 --- a/apps/federation/l10n/lv.js +++ b/apps/federation/l10n/lv.js @@ -4,7 +4,9 @@ OC.L10N.register( "Added to the list of trusted servers" : "Sarakstam pievieno uzticamo serveri", "Server is already in the list of trusted servers." : "Serveris jau ir uzticamo serveru sarakstā .", "No server to federate with found" : "Nav atrasts neviens serveris", + "Could not add server" : "Nevarēja pievienot serveri", "Federation" : "Federācija", + "Federation allows you to connect with other trusted servers to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "Federācija ļauj savienot ar citiem uzticamiem serveriem ar Exchange lietotāja direktoriju. Piemēram, tas tiks izmantots, lai automātiski pieslēgtu ārējiem lietotājiem integrēto koplietošanu.", "Trusted servers" : "Uzticami serveri", "+ Add trusted server" : "+ pievietot uzticamiem serveriem", "Trusted server" : "Uzticams serveris", diff --git a/apps/federation/l10n/lv.json b/apps/federation/l10n/lv.json index 14dbab413d5..0a175e09e02 100644 --- a/apps/federation/l10n/lv.json +++ b/apps/federation/l10n/lv.json @@ -2,7 +2,9 @@ "Added to the list of trusted servers" : "Sarakstam pievieno uzticamo serveri", "Server is already in the list of trusted servers." : "Serveris jau ir uzticamo serveru sarakstā .", "No server to federate with found" : "Nav atrasts neviens serveris", + "Could not add server" : "Nevarēja pievienot serveri", "Federation" : "Federācija", + "Federation allows you to connect with other trusted servers to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "Federācija ļauj savienot ar citiem uzticamiem serveriem ar Exchange lietotāja direktoriju. Piemēram, tas tiks izmantots, lai automātiski pieslēgtu ārējiem lietotājiem integrēto koplietošanu.", "Trusted servers" : "Uzticami serveri", "+ Add trusted server" : "+ pievietot uzticamiem serveriem", "Trusted server" : "Uzticams serveris", diff --git a/apps/files/l10n/lv.js b/apps/files/l10n/lv.js index 64db0c754a8..7a86ef07b5e 100644 --- a/apps/files/l10n/lv.js +++ b/apps/files/l10n/lv.js @@ -14,6 +14,7 @@ OC.L10N.register( "Upload cancelled." : "Augšupielāde ir atcelta.", "Unable to upload {filename} as it is a directory or has 0 bytes" : "Neizdodas augšupielādēt {filename}, jo tā ir vai nu mape vai 0 baitu saturoša datne.", "Not enough free space, you are uploading {size1} but only {size2} is left" : "Nav pietiekami daudz brīvas vietas. Tiek augšupielādēti {size1}, bet pieejami tikai {size2}", + "Target folder \"{dir}\" does not exist any more" : "Mape \"{dir}\" vairs neeksistē", "Not enough free space" : "Nav pietiekami daudz brīvas vietas", "Uploading..." : "Augšupielādē...", "..." : "...", diff --git a/apps/files/l10n/lv.json b/apps/files/l10n/lv.json index 1ef5db26718..fe675e6d1fc 100644 --- a/apps/files/l10n/lv.json +++ b/apps/files/l10n/lv.json @@ -12,6 +12,7 @@ "Upload cancelled." : "Augšupielāde ir atcelta.", "Unable to upload {filename} as it is a directory or has 0 bytes" : "Neizdodas augšupielādēt {filename}, jo tā ir vai nu mape vai 0 baitu saturoša datne.", "Not enough free space, you are uploading {size1} but only {size2} is left" : "Nav pietiekami daudz brīvas vietas. Tiek augšupielādēti {size1}, bet pieejami tikai {size2}", + "Target folder \"{dir}\" does not exist any more" : "Mape \"{dir}\" vairs neeksistē", "Not enough free space" : "Nav pietiekami daudz brīvas vietas", "Uploading..." : "Augšupielādē...", "..." : "...", diff --git a/apps/files_external/3rdparty/composer/autoload_classmap.php b/apps/files_external/3rdparty/composer/autoload_classmap.php index e6bba3a9a15..97f4ce99cda 100644 --- a/apps/files_external/3rdparty/composer/autoload_classmap.php +++ b/apps/files_external/3rdparty/composer/autoload_classmap.php @@ -7,6 +7,7 @@ $baseDir = $vendorDir; return array( 'Icewind\\SMB\\AbstractShare' => $vendorDir . '/icewind/smb/src/AbstractShare.php', + 'Icewind\\SMB\\Change' => $vendorDir . '/icewind/smb/src/Change.php', 'Icewind\\SMB\\Connection' => $vendorDir . '/icewind/smb/src/Connection.php', 'Icewind\\SMB\\ErrorCodes' => $vendorDir . '/icewind/smb/src/ErrorCodes.php', 'Icewind\\SMB\\Exception\\AccessDeniedException' => $vendorDir . '/icewind/smb/src/Exception/AccessDeniedException.php', @@ -15,6 +16,7 @@ return array( 'Icewind\\SMB\\Exception\\ConnectException' => $vendorDir . '/icewind/smb/src/Exception/ConnectException.php', 'Icewind\\SMB\\Exception\\ConnectionException' => $vendorDir . '/icewind/smb/src/Exception/ConnectionException.php', 'Icewind\\SMB\\Exception\\ConnectionRefusedException' => $vendorDir . '/icewind/smb/src/Exception/ConnectionRefusedException.php', + 'Icewind\\SMB\\Exception\\DependencyException' => $vendorDir . '/icewind/smb/src/Exception/DependencyException.php', 'Icewind\\SMB\\Exception\\Exception' => $vendorDir . '/icewind/smb/src/Exception/Exception.php', 'Icewind\\SMB\\Exception\\FileInUseException' => $vendorDir . '/icewind/smb/src/Exception/FileInUseException.php', 'Icewind\\SMB\\Exception\\ForbiddenException' => $vendorDir . '/icewind/smb/src/Exception/ForbiddenException.php', @@ -31,12 +33,14 @@ return array( 'Icewind\\SMB\\Exception\\TimedOutException' => $vendorDir . '/icewind/smb/src/Exception/TimedOutException.php', 'Icewind\\SMB\\FileInfo' => $vendorDir . '/icewind/smb/src/FileInfo.php', 'Icewind\\SMB\\IFileInfo' => $vendorDir . '/icewind/smb/src/IFileInfo.php', + 'Icewind\\SMB\\INotifyHandler' => $vendorDir . '/icewind/smb/src/INotifyHandler.php', 'Icewind\\SMB\\IShare' => $vendorDir . '/icewind/smb/src/IShare.php', 'Icewind\\SMB\\NativeFileInfo' => $vendorDir . '/icewind/smb/src/NativeFileInfo.php', 'Icewind\\SMB\\NativeServer' => $vendorDir . '/icewind/smb/src/NativeServer.php', 'Icewind\\SMB\\NativeShare' => $vendorDir . '/icewind/smb/src/NativeShare.php', 'Icewind\\SMB\\NativeState' => $vendorDir . '/icewind/smb/src/NativeState.php', 'Icewind\\SMB\\NativeStream' => $vendorDir . '/icewind/smb/src/NativeStream.php', + 'Icewind\\SMB\\NotifyHandler' => $vendorDir . '/icewind/smb/src/NotifyHandler.php', 'Icewind\\SMB\\Parser' => $vendorDir . '/icewind/smb/src/Parser.php', 'Icewind\\SMB\\RawConnection' => $vendorDir . '/icewind/smb/src/RawConnection.php', 'Icewind\\SMB\\Server' => $vendorDir . '/icewind/smb/src/Server.php', diff --git a/apps/files_external/3rdparty/composer/autoload_static.php b/apps/files_external/3rdparty/composer/autoload_static.php index 9fa922caeab..c1a3a0492d0 100644 --- a/apps/files_external/3rdparty/composer/autoload_static.php +++ b/apps/files_external/3rdparty/composer/autoload_static.php @@ -37,6 +37,7 @@ class ComposerStaticInit98fe9b281934250b3a93f69a5ce843b3 public static $classMap = array ( 'Icewind\\SMB\\AbstractShare' => __DIR__ . '/..' . '/icewind/smb/src/AbstractShare.php', + 'Icewind\\SMB\\Change' => __DIR__ . '/..' . '/icewind/smb/src/Change.php', 'Icewind\\SMB\\Connection' => __DIR__ . '/..' . '/icewind/smb/src/Connection.php', 'Icewind\\SMB\\ErrorCodes' => __DIR__ . '/..' . '/icewind/smb/src/ErrorCodes.php', 'Icewind\\SMB\\Exception\\AccessDeniedException' => __DIR__ . '/..' . '/icewind/smb/src/Exception/AccessDeniedException.php', @@ -45,6 +46,7 @@ class ComposerStaticInit98fe9b281934250b3a93f69a5ce843b3 'Icewind\\SMB\\Exception\\ConnectException' => __DIR__ . '/..' . '/icewind/smb/src/Exception/ConnectException.php', 'Icewind\\SMB\\Exception\\ConnectionException' => __DIR__ . '/..' . '/icewind/smb/src/Exception/ConnectionException.php', 'Icewind\\SMB\\Exception\\ConnectionRefusedException' => __DIR__ . '/..' . '/icewind/smb/src/Exception/ConnectionRefusedException.php', + 'Icewind\\SMB\\Exception\\DependencyException' => __DIR__ . '/..' . '/icewind/smb/src/Exception/DependencyException.php', 'Icewind\\SMB\\Exception\\Exception' => __DIR__ . '/..' . '/icewind/smb/src/Exception/Exception.php', 'Icewind\\SMB\\Exception\\FileInUseException' => __DIR__ . '/..' . '/icewind/smb/src/Exception/FileInUseException.php', 'Icewind\\SMB\\Exception\\ForbiddenException' => __DIR__ . '/..' . '/icewind/smb/src/Exception/ForbiddenException.php', @@ -61,12 +63,14 @@ class ComposerStaticInit98fe9b281934250b3a93f69a5ce843b3 'Icewind\\SMB\\Exception\\TimedOutException' => __DIR__ . '/..' . '/icewind/smb/src/Exception/TimedOutException.php', 'Icewind\\SMB\\FileInfo' => __DIR__ . '/..' . '/icewind/smb/src/FileInfo.php', 'Icewind\\SMB\\IFileInfo' => __DIR__ . '/..' . '/icewind/smb/src/IFileInfo.php', + 'Icewind\\SMB\\INotifyHandler' => __DIR__ . '/..' . '/icewind/smb/src/INotifyHandler.php', 'Icewind\\SMB\\IShare' => __DIR__ . '/..' . '/icewind/smb/src/IShare.php', 'Icewind\\SMB\\NativeFileInfo' => __DIR__ . '/..' . '/icewind/smb/src/NativeFileInfo.php', 'Icewind\\SMB\\NativeServer' => __DIR__ . '/..' . '/icewind/smb/src/NativeServer.php', 'Icewind\\SMB\\NativeShare' => __DIR__ . '/..' . '/icewind/smb/src/NativeShare.php', 'Icewind\\SMB\\NativeState' => __DIR__ . '/..' . '/icewind/smb/src/NativeState.php', 'Icewind\\SMB\\NativeStream' => __DIR__ . '/..' . '/icewind/smb/src/NativeStream.php', + 'Icewind\\SMB\\NotifyHandler' => __DIR__ . '/..' . '/icewind/smb/src/NotifyHandler.php', 'Icewind\\SMB\\Parser' => __DIR__ . '/..' . '/icewind/smb/src/Parser.php', 'Icewind\\SMB\\RawConnection' => __DIR__ . '/..' . '/icewind/smb/src/RawConnection.php', 'Icewind\\SMB\\Server' => __DIR__ . '/..' . '/icewind/smb/src/Server.php', diff --git a/apps/files_external/3rdparty/icewind/smb/src/Change.php b/apps/files_external/3rdparty/icewind/smb/src/Change.php new file mode 100644 index 00000000000..9dfd57b3973 --- /dev/null +++ b/apps/files_external/3rdparty/icewind/smb/src/Change.php @@ -0,0 +1,40 @@ +<?php +/** + * @copyright Copyright (c) 2016 Robin Appelman <robin@icewind.nl> + * This file is licensed under the Licensed under the MIT license: + * http://opensource.org/licenses/MIT + * + */ + +namespace Icewind\SMB; + +class Change { + private $code; + + private $path; + + /** + * Change constructor. + * + * @param $code + * @param $path + */ + public function __construct($code, $path) { + $this->code = $code; + $this->path = $path; + } + + /** + * @return integer + */ + public function getCode() { + return $this->code; + } + + /** + * @return string + */ + public function getPath() { + return $this->path; + } +} diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/DependencyException.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/DependencyException.php new file mode 100644 index 00000000000..39735578798 --- /dev/null +++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/DependencyException.php @@ -0,0 +1,11 @@ +<?php +/** + * Copyright (c) 2016 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Licensed under the MIT license: + * http://opensource.org/licenses/MIT + */ + +namespace Icewind\SMB\Exception; + +class DependencyException extends Exception { +} diff --git a/apps/files_external/3rdparty/icewind/smb/src/INotifyHandler.php b/apps/files_external/3rdparty/icewind/smb/src/INotifyHandler.php new file mode 100644 index 00000000000..1ee59b26ddd --- /dev/null +++ b/apps/files_external/3rdparty/icewind/smb/src/INotifyHandler.php @@ -0,0 +1,46 @@ +<?php +/** + * @copyright Copyright (c) 2016 Robin Appelman <robin@icewind.nl> + * This file is licensed under the Licensed under the MIT license: + * http://opensource.org/licenses/MIT + * + */ + +namespace Icewind\SMB; + + +interface INotifyHandler { + // https://msdn.microsoft.com/en-us/library/dn392331.aspx + const NOTIFY_ADDED = 1; + const NOTIFY_REMOVED = 2; + const NOTIFY_MODIFIED = 3; + const NOTIFY_RENAMED_OLD = 4; + const NOTIFY_RENAMED_NEW = 5; + const NOTIFY_ADDED_STREAM = 6; + const NOTIFY_REMOVED_STREAM = 7; + const NOTIFY_MODIFIED_STREAM = 8; + const NOTIFY_REMOVED_BY_DELETE = 9; + + /** + * Get all changes detected since the start of the notify process or the last call to getChanges + * + * @return Change[] + */ + public function getChanges(); + + /** + * Listen actively to all incoming changes + * + * Note that this is a blocking process and will cause the process to block forever if not explicitly terminated + * + * @param callable $callback + */ + public function listen($callback); + + /** + * Stop listening for changes + * + * Note that any pending changes will be discarded + */ + public function stop(); +} diff --git a/apps/files_external/3rdparty/icewind/smb/src/NotifyHandler.php b/apps/files_external/3rdparty/icewind/smb/src/NotifyHandler.php new file mode 100644 index 00000000000..194e848502b --- /dev/null +++ b/apps/files_external/3rdparty/icewind/smb/src/NotifyHandler.php @@ -0,0 +1,88 @@ +<?php +/** + * @copyright Copyright (c) 2016 Robin Appelman <robin@icewind.nl> + * This file is licensed under the Licensed under the MIT license: + * http://opensource.org/licenses/MIT + * + */ + +namespace Icewind\SMB; + + +class NotifyHandler implements INotifyHandler { + /** + * @var Connection + */ + private $connection; + + /** + * @var string + */ + private $path; + + private $listening = true; + + /** + * @param Connection $connection + * @param string $path + */ + public function __construct(Connection $connection, $path) { + $this->connection = $connection; + $this->path = $path; + } + + /** + * Get all changes detected since the start of the notify process or the last call to getChanges + * + * @return Change[] + */ + public function getChanges() { + if (!$this->listening) { + return []; + } + stream_set_blocking($this->connection->getOutputStream(), 0); + $lines = []; + while (($line = $this->connection->readLine())) { + $lines[] = $line; + } + stream_set_blocking($this->connection->getOutputStream(), 1); + return array_values(array_filter(array_map([$this, 'parseChangeLine'], $lines))); + } + + /** + * Listen actively to all incoming changes + * + * Note that this is a blocking process and will cause the process to block forever if not explicitly terminated + * + * @param callable $callback + */ + public function listen($callback) { + if ($this->listening) { + $this->connection->read(function ($line) use ($callback) { + return $callback($this->parseChangeLine($line)); + }); + } + } + + private function parseChangeLine($line) { + $code = (int)substr($line, 0, 4); + if ($code === 0) { + return null; + } + $subPath = str_replace('\\', '/', substr($line, 5)); + if ($this->path === '') { + return new Change($code, $subPath); + } else { + return new Change($code, $this->path . '/' . $subPath); + } + } + + public function stop() { + $this->listening = false; + $this->connection->close(); + } + + public function __destruct() { + $this->stop(); + } +} diff --git a/apps/files_external/l10n/zh_CN.js b/apps/files_external/l10n/zh_CN.js index fcbee03772f..786d85e9099 100644 --- a/apps/files_external/l10n/zh_CN.js +++ b/apps/files_external/l10n/zh_CN.js @@ -1,32 +1,82 @@ OC.L10N.register( "files_external", { - "Step 1 failed. Exception: %s" : "步骤 1 失败。异常:%s", - "Step 2 failed. Exception: %s" : "步骤 2 失败。异常:%s", + "Fetching request tokens failed. Verify that your app key and secret are correct." : "获取 request token 失败. 请验证您的 appkey 和密钥是否正确.", + "Fetching access tokens failed. Verify that your app key and secret are correct." : "获取 access token 失败. 请验证您的 appkey 和密钥是否正确.", + "Please provide a valid app key and secret." : "请提供有效的 appkey 和密钥.", + "Step 1 failed. Exception: %s" : "步骤 1 失败. 异常: %s", + "Step 2 failed. Exception: %s" : "步骤 2 失败. 异常: %s", "External storage" : "外部存储", + "Dropbox App Configuration" : "Dropbox 配置", + "Google Drive App Configuration" : "Google Drive 配置", "Personal" : "个人", "System" : "系统", "Grant access" : "授权", + "Error configuring OAuth1" : "OAuth1 配置错误", + "Error configuring OAuth2" : "OAuth2 配置错误", + "Generate keys" : "生成密钥", + "Error generating key pair" : "生成密钥对错误", + "All users. Type to select user or group." : "全部用户. 点击选择用户或分组.", + "(group)" : "(分组)", + "Compatibility with Mac NFD encoding (slow)" : "兼用 Mac NFD 编码 (慢)", + "Admin defined" : "管理员定义", "Saved" : "已保存", + "Saving..." : "正在保存...", + "Save" : "保存", + "Empty response from the server" : "服务器响应为空", + "Couldn't access. Please logout and login to activate this mount point" : "无法连接. 请注销并重新登录以激活挂载点.", + "Couldn't get the information from the remote server: {code} {type}" : "无法从远程服务器获取信息: {code} {type}", + "Couldn't get the list of external mount points: {type}" : "无法获取外部挂载点列表: {type}", + "There was an error with message: " : "错误信息: ", "External mount error" : "外部挂载错误", "external-storage" : "外部存储", + "Couldn't get the list of Windows network drive mount points: empty response from the server" : "无法获取 Windows 网络磁盘挂载点列表: 服务器响应为空", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "一些外部挂载点没有连接. 请检查标红的行以获取更多信息.", + "Please enter the credentials for the {mount} mount" : "请输入 {mount} 挂载点的凭据", "Username" : "用户名", "Password" : "密码", - "Save" : "保存", + "Credentials saved" : "凭据已保存", + "Credentials saving failed" : "凭据保存失败", + "Credentials required" : "需要凭据", + "Storage with id \"%i\" not found" : "未找到 ID 为 \"%i\" 的存储", + "Invalid backend or authentication mechanism class" : "无效的后端或认证类型", "Invalid mount point" : "无效的挂载点", + "Objectstore forbidden" : "对象存储禁止访问", + "Invalid storage backend \"%s\"" : "无效的存储后端 \"%s\"", + "Not permitted to use backend \"%s\"" : "不允许使用 \"%s\"", + "Not permitted to use authentication mechanism \"%s\"" : "不允许使用认证方式 \"%s\"", + "Unsatisfied backend parameters" : "无法满足后端条件", + "Unsatisfied authentication mechanism parameters" : "无法满足认证类型条件", + "Insufficient data: %s" : "数据不足: %s", "%s" : "%s", + "Storage with id \"%i\" is not user editable" : "无法编辑 ID 为 \"%i\" 的存储", "Access key" : "Access key", "Secret key" : "Secret key", "Builtin" : "内置", "None" : "无", + "OAuth1" : "OAuth1", + "App key" : "App key", + "App secret" : "App 密钥", + "OAuth2" : "OAuth2", + "Client ID" : "Client ID", + "Client secret" : "客户端密钥", + "OpenStack" : "OpenStack", + "Tenant name" : "租户名称", + "Identity endpoint URL" : "身份识别 URL", + "Rackspace" : "Rackspace", "API key" : "API密匙", + "Global credentials" : "全局凭据", + "Log-in credentials, save in database" : "登录凭据, 保存在数据库中", "Username and password" : "用户名和密码", + "Log-in credentials, save in session" : "登录凭据, 存储在会话中", + "User entered, store in database" : "用户登录, 存储在数据库中", "RSA public key" : "RSA 公钥", "Public key" : "公钥", "Amazon S3" : "Amazon S3", + "Bucket" : "Bucket", "Hostname" : "主机名", "Port" : "端口", - "Region" : "地区", + "Region" : "区域", "Enable SSL" : "启用 SSL", "Enable Path Style" : "启用 Path Style", "WebDAV" : "WebDAV", @@ -40,20 +90,23 @@ OC.L10N.register( "Google Drive" : "Google Drive", "Local" : "本地", "Location" : "地点", - "ownCloud" : "ownCloud", + "Nextcloud" : "Nextcloud", "SFTP" : "SFTP", "Root" : "根路径", - "SFTP with secret key login" : "包含secret key的SFTP", + "SFTP with secret key login" : "包含 secret key 的SFTP", "SMB / CIFS" : "SMB / CIFS", "Share" : "共享", "Domain" : "域名", "SMB / CIFS using OC login" : "SMB / CIFS 使用 OC 登录信息", + "Username as share" : "以用户名作为共享名", "OpenStack Object Storage" : "OpenStack 对象存储", - "<b>Note:</b> " : "<b>注意:</b>", - "<b>Note:</b> The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>注意:</b> PHP 中的 cURL 支持未启用或未安装。对 %s 的挂载无法进行。请联系系统管理员进行安装。", - "<b>Note:</b> The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>注意:</b> PHP 中的 FTP 支持未启用或未安装。对 %s 的挂载无法进行。请联系系统管理员进行安装。", - "<b>Note:</b> \"%s\" is not installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>注意:</b>“%s”尚未安装。对 %s 的挂载无法进行。请联系系统管理员进行安装。", - "No external storage configured" : "未配置外部存储", + "Service name" : "服务名称", + "Request timeout (seconds)" : "请求超时时间 (秒)", + "External storages" : "外部存储", + "The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "没有安装或启用 PHP 中的 cURL 支持. 无法挂载 %s. 请联系您的系统管理员安装.", + "The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "没有安装或启用 PHP 中的 FTP 支持. 无法挂载 %s. 请联系您的系统管理员安装.", + "\"%s\" is not installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "没有安装 \"%s\". 无法挂载 %s. 请联系您的系统管理员安装.", + "No external storage configured" : "没有配置外部存储", "You can add external storages in the personal settings" : "您可以在个人设置中添加外部存储", "Name" : "名称", "Storage type" : "存储类型", @@ -61,8 +114,9 @@ OC.L10N.register( "Enable encryption" : "启用加密", "Enable previews" : "启用预览", "Enable sharing" : "启用分享", + "Check for changes" : "检查修改", "Never" : "从不", - "External Storage" : "外部存储", + "Once every direct access" : "每次直接访问", "Folder name" : "目录名称", "Authentication" : "认证", "Configuration" : "配置", @@ -71,6 +125,7 @@ OC.L10N.register( "Advanced settings" : "高级选项", "Delete" : "删除", "Allow users to mount external storage" : "允许用户挂载外部存储", - "Allow users to mount the following external storage" : "允许用户挂载以下外部存储" + "Allow users to mount the following external storage" : "允许用户挂载以下外部存储", + "Couldn't get the information from the ownCloud server: {code} {type}" : "无法从 ownCloud 服务器获取信息: {code} {type}" }, "nplurals=1; plural=0;"); diff --git a/apps/files_external/l10n/zh_CN.json b/apps/files_external/l10n/zh_CN.json index 286156dac52..b6a656d6b4a 100644 --- a/apps/files_external/l10n/zh_CN.json +++ b/apps/files_external/l10n/zh_CN.json @@ -1,30 +1,80 @@ { "translations": { - "Step 1 failed. Exception: %s" : "步骤 1 失败。异常:%s", - "Step 2 failed. Exception: %s" : "步骤 2 失败。异常:%s", + "Fetching request tokens failed. Verify that your app key and secret are correct." : "获取 request token 失败. 请验证您的 appkey 和密钥是否正确.", + "Fetching access tokens failed. Verify that your app key and secret are correct." : "获取 access token 失败. 请验证您的 appkey 和密钥是否正确.", + "Please provide a valid app key and secret." : "请提供有效的 appkey 和密钥.", + "Step 1 failed. Exception: %s" : "步骤 1 失败. 异常: %s", + "Step 2 failed. Exception: %s" : "步骤 2 失败. 异常: %s", "External storage" : "外部存储", + "Dropbox App Configuration" : "Dropbox 配置", + "Google Drive App Configuration" : "Google Drive 配置", "Personal" : "个人", "System" : "系统", "Grant access" : "授权", + "Error configuring OAuth1" : "OAuth1 配置错误", + "Error configuring OAuth2" : "OAuth2 配置错误", + "Generate keys" : "生成密钥", + "Error generating key pair" : "生成密钥对错误", + "All users. Type to select user or group." : "全部用户. 点击选择用户或分组.", + "(group)" : "(分组)", + "Compatibility with Mac NFD encoding (slow)" : "兼用 Mac NFD 编码 (慢)", + "Admin defined" : "管理员定义", "Saved" : "已保存", + "Saving..." : "正在保存...", + "Save" : "保存", + "Empty response from the server" : "服务器响应为空", + "Couldn't access. Please logout and login to activate this mount point" : "无法连接. 请注销并重新登录以激活挂载点.", + "Couldn't get the information from the remote server: {code} {type}" : "无法从远程服务器获取信息: {code} {type}", + "Couldn't get the list of external mount points: {type}" : "无法获取外部挂载点列表: {type}", + "There was an error with message: " : "错误信息: ", "External mount error" : "外部挂载错误", "external-storage" : "外部存储", + "Couldn't get the list of Windows network drive mount points: empty response from the server" : "无法获取 Windows 网络磁盘挂载点列表: 服务器响应为空", + "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "一些外部挂载点没有连接. 请检查标红的行以获取更多信息.", + "Please enter the credentials for the {mount} mount" : "请输入 {mount} 挂载点的凭据", "Username" : "用户名", "Password" : "密码", - "Save" : "保存", + "Credentials saved" : "凭据已保存", + "Credentials saving failed" : "凭据保存失败", + "Credentials required" : "需要凭据", + "Storage with id \"%i\" not found" : "未找到 ID 为 \"%i\" 的存储", + "Invalid backend or authentication mechanism class" : "无效的后端或认证类型", "Invalid mount point" : "无效的挂载点", + "Objectstore forbidden" : "对象存储禁止访问", + "Invalid storage backend \"%s\"" : "无效的存储后端 \"%s\"", + "Not permitted to use backend \"%s\"" : "不允许使用 \"%s\"", + "Not permitted to use authentication mechanism \"%s\"" : "不允许使用认证方式 \"%s\"", + "Unsatisfied backend parameters" : "无法满足后端条件", + "Unsatisfied authentication mechanism parameters" : "无法满足认证类型条件", + "Insufficient data: %s" : "数据不足: %s", "%s" : "%s", + "Storage with id \"%i\" is not user editable" : "无法编辑 ID 为 \"%i\" 的存储", "Access key" : "Access key", "Secret key" : "Secret key", "Builtin" : "内置", "None" : "无", + "OAuth1" : "OAuth1", + "App key" : "App key", + "App secret" : "App 密钥", + "OAuth2" : "OAuth2", + "Client ID" : "Client ID", + "Client secret" : "客户端密钥", + "OpenStack" : "OpenStack", + "Tenant name" : "租户名称", + "Identity endpoint URL" : "身份识别 URL", + "Rackspace" : "Rackspace", "API key" : "API密匙", + "Global credentials" : "全局凭据", + "Log-in credentials, save in database" : "登录凭据, 保存在数据库中", "Username and password" : "用户名和密码", + "Log-in credentials, save in session" : "登录凭据, 存储在会话中", + "User entered, store in database" : "用户登录, 存储在数据库中", "RSA public key" : "RSA 公钥", "Public key" : "公钥", "Amazon S3" : "Amazon S3", + "Bucket" : "Bucket", "Hostname" : "主机名", "Port" : "端口", - "Region" : "地区", + "Region" : "区域", "Enable SSL" : "启用 SSL", "Enable Path Style" : "启用 Path Style", "WebDAV" : "WebDAV", @@ -38,20 +88,23 @@ "Google Drive" : "Google Drive", "Local" : "本地", "Location" : "地点", - "ownCloud" : "ownCloud", + "Nextcloud" : "Nextcloud", "SFTP" : "SFTP", "Root" : "根路径", - "SFTP with secret key login" : "包含secret key的SFTP", + "SFTP with secret key login" : "包含 secret key 的SFTP", "SMB / CIFS" : "SMB / CIFS", "Share" : "共享", "Domain" : "域名", "SMB / CIFS using OC login" : "SMB / CIFS 使用 OC 登录信息", + "Username as share" : "以用户名作为共享名", "OpenStack Object Storage" : "OpenStack 对象存储", - "<b>Note:</b> " : "<b>注意:</b>", - "<b>Note:</b> The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>注意:</b> PHP 中的 cURL 支持未启用或未安装。对 %s 的挂载无法进行。请联系系统管理员进行安装。", - "<b>Note:</b> The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>注意:</b> PHP 中的 FTP 支持未启用或未安装。对 %s 的挂载无法进行。请联系系统管理员进行安装。", - "<b>Note:</b> \"%s\" is not installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "<b>注意:</b>“%s”尚未安装。对 %s 的挂载无法进行。请联系系统管理员进行安装。", - "No external storage configured" : "未配置外部存储", + "Service name" : "服务名称", + "Request timeout (seconds)" : "请求超时时间 (秒)", + "External storages" : "外部存储", + "The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "没有安装或启用 PHP 中的 cURL 支持. 无法挂载 %s. 请联系您的系统管理员安装.", + "The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "没有安装或启用 PHP 中的 FTP 支持. 无法挂载 %s. 请联系您的系统管理员安装.", + "\"%s\" is not installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "没有安装 \"%s\". 无法挂载 %s. 请联系您的系统管理员安装.", + "No external storage configured" : "没有配置外部存储", "You can add external storages in the personal settings" : "您可以在个人设置中添加外部存储", "Name" : "名称", "Storage type" : "存储类型", @@ -59,8 +112,9 @@ "Enable encryption" : "启用加密", "Enable previews" : "启用预览", "Enable sharing" : "启用分享", + "Check for changes" : "检查修改", "Never" : "从不", - "External Storage" : "外部存储", + "Once every direct access" : "每次直接访问", "Folder name" : "目录名称", "Authentication" : "认证", "Configuration" : "配置", @@ -69,6 +123,7 @@ "Advanced settings" : "高级选项", "Delete" : "删除", "Allow users to mount external storage" : "允许用户挂载外部存储", - "Allow users to mount the following external storage" : "允许用户挂载以下外部存储" + "Allow users to mount the following external storage" : "允许用户挂载以下外部存储", + "Couldn't get the information from the ownCloud server: {code} {type}" : "无法从 ownCloud 服务器获取信息: {code} {type}" },"pluralForm" :"nplurals=1; plural=0;" }
\ No newline at end of file diff --git a/apps/files_external/lib/Command/Notify.php b/apps/files_external/lib/Command/Notify.php index 913299b59b4..a55b16a45c4 100644 --- a/apps/files_external/lib/Command/Notify.php +++ b/apps/files_external/lib/Command/Notify.php @@ -27,7 +27,11 @@ use OC\Core\Command\Base; use OCA\Files_External\Lib\InsufficientDataForMeaningfulAnswerException; use OCA\Files_External\Lib\StorageConfig; use OCA\Files_External\Service\GlobalStoragesService; +use OCP\Files\Notify\IChange; +use OCP\Files\Notify\INotifyHandler; +use OCP\Files\Notify\IRenameChange; use OCP\Files\Storage\INotifyStorage; +use OCP\Files\Storage\IStorage; use OCP\Files\StorageNotAvailableException; use OCP\IDBConnection; use Symfony\Component\Console\Input\InputArgument; @@ -123,14 +127,16 @@ class Notify extends Base { $verbose = $input->getOption('verbose'); $path = trim($input->getOption('path'), '/'); - $storage->listen($path, function ($type, $path, $renameTarget) use ($mount, $verbose, $output) { + $notifyHandler = $storage->notify($path); + $this->selfTest($storage, $notifyHandler, $verbose, $output); + $notifyHandler->listen(function (IChange $change) use ($mount, $verbose, $output) { if ($verbose) { - $this->logUpdate($type, $path, $renameTarget, $output); + $this->logUpdate($change, $output); } - if ($type == INotifyStorage::NOTIFY_RENAMED) { - $this->markParentAsOutdated($mount->getId(), $renameTarget); + if ($change instanceof IRenameChange) { + $this->markParentAsOutdated($mount->getId(), $change->getTargetPath()); } - $this->markParentAsOutdated($mount->getId(), $path); + $this->markParentAsOutdated($mount->getId(), $change->getPath()); }); } @@ -147,8 +153,8 @@ class Notify extends Base { $this->updateQuery->execute([$parent, $mountId]); } - private function logUpdate($type, $path, $renameTarget, OutputInterface $output) { - switch ($type) { + private function logUpdate(IChange $change, OutputInterface $output) { + switch ($change->getType()) { case INotifyStorage::NOTIFY_ADDED: $text = 'added'; break; @@ -165,11 +171,42 @@ class Notify extends Base { return; } - $text .= ' ' . $path; - if ($type === INotifyStorage::NOTIFY_RENAMED) { - $text .= ' to ' . $renameTarget; + $text .= ' ' . $change->getPath(); + if ($change instanceof IRenameChange) { + $text .= ' to ' . $change->getTargetPath(); } $output->writeln($text); } + + private function selfTest(IStorage $storage, INotifyHandler $notifyHandler, $verbose, OutputInterface $output) { + usleep(100 * 1000); //give time for the notify to start + $storage->file_put_contents('/.nc_test_file.txt', 'test content'); + $storage->mkdir('/.nc_test_folder'); + $storage->file_put_contents('/.nc_test_folder/subfile.txt', 'test content'); + $storage->unlink('/.nc_test_file.txt'); + $storage->unlink('/.nc_test_folder/subfile.txt'); + $storage->rmdir('/.nc_test_folder'); + usleep(100 * 1000); //time for all changes to be processed + + $foundRootChange = false; + $foundSubfolderChange = false; + + $changes = $notifyHandler->getChanges(); + foreach ($changes as $change) { + if ($change->getPath() === '/.nc_test_file.txt') { + $foundRootChange = true; + } else if ($change->getPath() === '/.nc_test_folder/subfile.txt') { + $foundSubfolderChange = true; + } + } + + if ($foundRootChange && $foundSubfolderChange && $verbose) { + $output->writeln('<info>Self-test successful</info>'); + } else if ($foundRootChange && !$foundSubfolderChange) { + $output->writeln('<error>Error while running self-test, change is subfolder not detected</error>'); + } else if (!$foundRootChange) { + $output->writeln('<error>Error while running self-test, no changes detected</error>'); + } + } } diff --git a/apps/files_external/lib/Lib/Notify/SMBNotifyHandler.php b/apps/files_external/lib/Lib/Notify/SMBNotifyHandler.php new file mode 100644 index 00000000000..9ac74b32ad8 --- /dev/null +++ b/apps/files_external/lib/Lib/Notify/SMBNotifyHandler.php @@ -0,0 +1,150 @@ +<?php +/** + * @copyright Copyright (c) 2017 Robin Appelman <robin@icewind.nl> + * + * @author Robin Appelman <robin@icewind.nl> + * + * @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\Files_External\Lib\Notify; + +use OC\Files\Notify\Change; +use OC\Files\Notify\RenameChange; +use OCP\Files\Notify\IChange; +use OCP\Files\Notify\INotifyHandler; + +class SMBNotifyHandler implements INotifyHandler { + /** + * @var \Icewind\SMB\INotifyHandler + */ + private $shareNotifyHandler; + + /** + * @var string + */ + private $root; + + private $oldRenamePath = null; + + /** + * SMBNotifyHandler constructor. + * + * @param \Icewind\SMB\INotifyHandler $shareNotifyHandler + * @param string $root + */ + public function __construct(\Icewind\SMB\INotifyHandler $shareNotifyHandler, $root) { + $this->shareNotifyHandler = $shareNotifyHandler; + $this->root = $root; + } + + private function relativePath($fullPath) { + if ($fullPath === $this->root) { + return ''; + } else if (substr($fullPath, 0, strlen($this->root)) === $this->root) { + return substr($fullPath, strlen($this->root)); + } else { + return null; + } + } + + public function listen(callable $callback) { + $oldRenamePath = null; + $this->shareNotifyHandler->listen(function (\Icewind\SMB\Change $shareChange) use ($callback) { + $change = $this->mapChange($shareChange); + if (!is_null($change)) { + return $callback($change); + } else { + return true; + } + }); + } + + /** + * Get all changes detected since the start of the notify process or the last call to getChanges + * + * @return IChange[] + */ + public function getChanges() { + $shareChanges = $this->shareNotifyHandler->getChanges(); + $changes = []; + foreach ($shareChanges as $shareChange) { + $change = $this->mapChange($shareChange); + if ($change) { + $changes[] = $change; + } + } + return $changes; + } + + /** + * Stop listening for changes + * + * Note that any pending changes will be discarded + */ + public function stop() { + $this->shareNotifyHandler->stop(); + } + + /** + * @param \Icewind\SMB\Change $change + * @return IChange|null + */ + private function mapChange(\Icewind\SMB\Change $change) { + $path = $this->relativePath($change->getPath()); + if (is_null($path)) { + return null; + } + if ($change->getCode() === \Icewind\SMB\INotifyHandler::NOTIFY_RENAMED_OLD) { + $this->oldRenamePath = $path; + return null; + } + $type = $this->mapNotifyType($change->getCode()); + if (is_null($type)) { + return null; + } + if ($type === IChange::RENAMED) { + if (!is_null($this->oldRenamePath)) { + $result = new RenameChange($type, $this->oldRenamePath, $path); + $this->oldRenamePath = null; + } else { + $result = null; + } + } else { + $result = new Change($type, $path); + } + return $result; + } + + private function mapNotifyType($smbType) { + switch ($smbType) { + case \Icewind\SMB\INotifyHandler::NOTIFY_ADDED: + return IChange::ADDED; + case \Icewind\SMB\INotifyHandler::NOTIFY_REMOVED: + return IChange::REMOVED; + case \Icewind\SMB\INotifyHandler::NOTIFY_MODIFIED: + case \Icewind\SMB\INotifyHandler::NOTIFY_ADDED_STREAM: + case \Icewind\SMB\INotifyHandler::NOTIFY_MODIFIED_STREAM: + case \Icewind\SMB\INotifyHandler::NOTIFY_REMOVED_STREAM: + return IChange::MODIFIED; + case \Icewind\SMB\INotifyHandler::NOTIFY_RENAMED_NEW: + return IChange::RENAMED; + default: + return null; + } + } +} diff --git a/apps/files_external/lib/Lib/Storage/SFTP.php b/apps/files_external/lib/Lib/Storage/SFTP.php index 9d20742fcb0..1d9affa8d68 100644 --- a/apps/files_external/lib/Lib/Storage/SFTP.php +++ b/apps/files_external/lib/Lib/Storage/SFTP.php @@ -207,7 +207,7 @@ class SFTP extends \OC\Files\Storage\Common { try { $storage_view = \OCP\Files::getStorage('files_external'); if ($storage_view) { - return \OC::$server->getConfig()->getSystemValue('datadirectory') . + return \OC::$server->getConfig()->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . $storage_view->getAbsolutePath('') . 'ssh_hostKeys'; } diff --git a/apps/files_external/lib/Lib/Storage/SMB.php b/apps/files_external/lib/Lib/Storage/SMB.php index 7ffc078df6f..690f8e2a334 100644 --- a/apps/files_external/lib/Lib/Storage/SMB.php +++ b/apps/files_external/lib/Lib/Storage/SMB.php @@ -46,6 +46,9 @@ use Icewind\Streams\IteratorDirectory; use OC\Cache\CappedMemoryCache; use OC\Files\Filesystem; use OC\Files\Storage\Common; +use OCA\Files_External\Lib\Notify\SMBNotifyHandler; +use OCP\Files\Notify\IChange; +use OCP\Files\Notify\IRenameChange; use OCP\Files\Storage\INotifyStorage; use OCP\Files\StorageNotAvailableException; @@ -149,7 +152,7 @@ class SMB extends Common implements INotifyStorage { foreach ($files as $file) { $this->statCache[$path . '/' . $file->getName()] = $file; } - return array_filter($files, function(IFileInfo $file) { + return array_filter($files, function (IFileInfo $file) { return !$file->isHidden(); }); } catch (ConnectException $e) { @@ -486,48 +489,18 @@ class SMB extends Common implements INotifyStorage { } public function listen($path, callable $callback) { - $fullPath = $this->buildPath($path); - $oldRenamePath = null; - $this->share->notify($fullPath)->listen(function (Change $change) use (&$oldRenamePath, $callback) { - $path = $this->relativePath($change->getPath()); - if (is_null($path)) { - return true; - } - if ($change->getCode() === INotifyHandler::NOTIFY_RENAMED_OLD) { - $oldRenamePath = $path; - return true; - } - $type = $this->mapNotifyType($change->getCode()); - if (is_null($type)) { - return true; - } - if ($type === INotifyStorage::NOTIFY_RENAMED) { - if (!is_null($oldRenamePath)) { - $result = $callback($type, $oldRenamePath, $path); - $oldRenamePath = null; - } + $this->notify($path)->listen(function (IChange $change) use ($callback) { + if ($change instanceof IRenameChange) { + return $callback($change->getType(), $change->getPath(), $change->getTargetPath()); } else { - $result = $callback($type, $path); + return $callback($change->getType(), $change->getPath()); } - return $result; }); } - private function mapNotifyType($smbType) { - switch ($smbType) { - case INotifyHandler::NOTIFY_ADDED: - return INotifyStorage::NOTIFY_ADDED; - case INotifyHandler::NOTIFY_REMOVED: - return INotifyStorage::NOTIFY_REMOVED; - case INotifyHandler::NOTIFY_MODIFIED: - case INotifyHandler::NOTIFY_ADDED_STREAM: - case INotifyHandler::NOTIFY_MODIFIED_STREAM: - case INotifyHandler::NOTIFY_REMOVED_STREAM: - return INotifyStorage::NOTIFY_MODIFIED; - case INotifyHandler::NOTIFY_RENAMED_NEW: - return INotifyStorage::NOTIFY_RENAMED; - default: - return null; - } + public function notify($path) { + $path = '/' . ltrim($path, '/'); + $shareNotifyHandler = $this->share->notify($this->buildPath($path)); + return new SMBNotifyHandler($shareNotifyHandler, $this->root); } } diff --git a/apps/files_external/tests/Storage/SmbTest.php b/apps/files_external/tests/Storage/SmbTest.php index 150d4d3a035..45c01a0c59e 100644 --- a/apps/files_external/tests/Storage/SmbTest.php +++ b/apps/files_external/tests/Storage/SmbTest.php @@ -27,7 +27,10 @@ namespace OCA\Files_External\Tests\Storage; +use OC\Files\Notify\Change; +use OC\Files\Notify\RenameChange; use \OCA\Files_External\Lib\Storage\SMB; +use OCP\Files\Notify\IChange; /** * Class SmbTest @@ -37,6 +40,10 @@ use \OCA\Files_External\Lib\Storage\SMB; * @package OCA\Files_External\Tests\Storage */ class SmbTest extends \Test\Files\Storage\Storage { + /** + * @var SMB instance + */ + protected $instance; protected function setUp() { parent::setUp(); @@ -85,4 +92,44 @@ class SmbTest extends \Test\Files\Storage\Storage { $this->assertEquals('smb::testuser@testhost//someshare//someroot/', $this->instance->getId()); $this->instance = null; } + + public function testNotifyGetChanges() { + $notifyHandler = $this->instance->notify(''); + usleep(100 * 1000); //give time for the notify to start + $this->instance->file_put_contents('/newfile.txt', 'test content'); + $this->instance->rename('/newfile.txt', 'renamed.txt'); + $this->instance->unlink('/renamed.txt'); + usleep(100 * 1000); //time for all changes to be processed + + $changes = $notifyHandler->getChanges(); + $notifyHandler->stop(); + + $expected = [ + new Change(IChange::ADDED, 'newfile.txt'), + new RenameChange(IChange::RENAMED, 'newfile.txt', 'renamed.txt'), + new Change(IChange::REMOVED, 'renamed.txt') + ]; + + foreach ($expected as $expectedChange) { + $this->assertContains($expectedChange, $changes, '', false, false); // dont check object identity + } + } + + public function testNotifyListen() { + $notifyHandler = $this->instance->notify(''); + usleep(100 * 1000); //give time for the notify to start + $this->instance->file_put_contents('/newfile.txt', 'test content'); + $this->instance->unlink('/newfile.txt'); + usleep(100 * 1000); //time for all changes to be processed + + $result = null; + + // since the notify handler buffers untill we start listening we will get the above changes + $notifyHandler->listen(function (IChange $change) use (&$result) { + $result = $change; + return false;//stop listening + }); + + $this->assertEquals(new Change(IChange::ADDED, 'newfile.txt'), $result); + } } diff --git a/apps/files_trashbin/lib/Trashbin.php b/apps/files_trashbin/lib/Trashbin.php index e73d6b0ac69..2e66a6b96e1 100644 --- a/apps/files_trashbin/lib/Trashbin.php +++ b/apps/files_trashbin/lib/Trashbin.php @@ -902,7 +902,7 @@ class Trashbin { * @return integer size of the folder */ private static function calculateSize($view) { - $root = \OC::$server->getConfig()->getSystemValue('datadirectory') . $view->getAbsolutePath(''); + $root = \OC::$server->getConfig()->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . $view->getAbsolutePath(''); if (!file_exists($root)) { return 0; } diff --git a/apps/theming/lib/Util.php b/apps/theming/lib/Util.php index 9fea56838ad..5c9ccb3baa6 100644 --- a/apps/theming/lib/Util.php +++ b/apps/theming/lib/Util.php @@ -128,7 +128,7 @@ class Util { } catch (AppPathNotFoundException $e) {} if($this->config->getAppValue('theming', 'logoMime', '') !== '' && $this->rootFolder->nodeExists('/themedinstancelogo')) { - return $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data/') . '/themedinstancelogo'; + return $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/themedinstancelogo'; } return \OC::$SERVERROOT . '/core/img/logo.svg'; } diff --git a/apps/twofactor_backupcodes/l10n/lv.js b/apps/twofactor_backupcodes/l10n/lv.js index 8d0aba6bab3..80d28c47db7 100644 --- a/apps/twofactor_backupcodes/l10n/lv.js +++ b/apps/twofactor_backupcodes/l10n/lv.js @@ -11,6 +11,8 @@ OC.L10N.register( "An error occurred while generating your backup codes" : "Radās kļūda, ģenerējot jūsu dublējuma kodus", "Nextcloud backup codes" : "Nextcloud dublēšanas kodi", "Two-factor authentication" : "Divpakāpju autentifikācija", + "You successfully logged in using two-factor authentication (%1$s)" : "Esat veiksmīgi pieteicies, izmantojot divpakāpju autentifikācija (%1$s)", + "You created two-factor backup codes for your account" : "Jūs izveidojāt divpakāpju dublējumu kodus savam kontam", "Backup code" : "Dublēšanas kods", "Use backup code" : "Izmantojiet dublēšanas kodu" }, diff --git a/apps/twofactor_backupcodes/l10n/lv.json b/apps/twofactor_backupcodes/l10n/lv.json index 35cd09352c2..6a65642a248 100644 --- a/apps/twofactor_backupcodes/l10n/lv.json +++ b/apps/twofactor_backupcodes/l10n/lv.json @@ -9,6 +9,8 @@ "An error occurred while generating your backup codes" : "Radās kļūda, ģenerējot jūsu dublējuma kodus", "Nextcloud backup codes" : "Nextcloud dublēšanas kodi", "Two-factor authentication" : "Divpakāpju autentifikācija", + "You successfully logged in using two-factor authentication (%1$s)" : "Esat veiksmīgi pieteicies, izmantojot divpakāpju autentifikācija (%1$s)", + "You created two-factor backup codes for your account" : "Jūs izveidojāt divpakāpju dublējumu kodus savam kontam", "Backup code" : "Dublēšanas kods", "Use backup code" : "Izmantojiet dublēšanas kodu" },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);" diff --git a/core/css/apps.scss b/core/css/apps.scss index bb9326fd22d..f1ddc95e092 100644 --- a/core/css/apps.scss +++ b/core/css/apps.scss @@ -62,12 +62,26 @@ em { -ms-user-select: none; user-select: none; border-right: 1px solid #eee; + display: flex; + flex-direction: column; > ul { position: relative; height: 100%; width: inherit; overflow: auto; box-sizing: border-box; + > li { + &:focus, + &:hover, + &.active, + a.selected { + &, + > a { + opacity: 1; + box-shadow: inset 2px 0 #0082c9; + } + } + } } li { position: relative; @@ -104,16 +118,6 @@ em { color: #000; opacity: .57; } - li:hover > a, - li:focus > a, - a:focus, - .selected, - .selected a, - .active, - .active a { - opacity: 1; - box-shadow: inset 2px 0 #0082c9; - } li > a:first-child img { margin-bottom: -3px; margin-right: 11px; @@ -559,7 +563,6 @@ em { background-color: #fff; color: #333; border-radius: 3px; - border-top-right-radius: 0; z-index: 110; margin: 5px; margin-top: -5px; @@ -592,7 +595,6 @@ em { transform: translateX(50%); right: 50%; margin-right: 0; - border-top-right-radius: 3px; &:after { right: 50%; transform: translateX(50%); @@ -603,8 +605,6 @@ em { right: auto; left: 0; margin-right: 0; - border-top-left-radius: 0; - border-top-right-radius: 3px; &:after { left: 6px; right: auto; @@ -639,6 +639,7 @@ em { margin: 0; font-weight: inherit; box-shadow: none; + color: #333 !important; /* Overwrite app-navigation li */ /* prevent .action class to break the design */ &.action { padding: inherit !important; @@ -653,15 +654,15 @@ em { cursor: pointer; white-space: nowrap; } + span { + -ms-filter: 'progid:DXImageTransform.Microsoft.Alpha(Opacity=70)' !important; + filter: alpha(opacity = 70) !important; + opacity: .7 !important; + } > p { width: 150px; line-height: 1.6em; padding: 8px 0; - > span { - -ms-filter: 'progid:DXImageTransform.Microsoft.Alpha(Opacity=70)' !important; - filter: alpha(opacity = 70) !important; - opacity: .7 !important; - } } /* Add padding if contains icon+text */ &:not(:empty) { @@ -680,7 +681,8 @@ em { padding: 18px 0 18px 36px; min-width: 0; /* Overwrite icons*/ min-height: 0; - background-position: 10px center + background-position: 10px center; + opacity: 0.7; /* Default button icon override */ } } } diff --git a/core/css/header.scss b/core/css/header.scss index 21b8cff4d28..2b73937a3c4 100644 --- a/core/css/header.scss +++ b/core/css/header.scss @@ -20,6 +20,21 @@ -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; + + /* Dropdown menu arrow */ + &.menu:after, + .menu:after { + border: 10px solid transparent; + border-color: transparent; + border-bottom-color: #fff; + bottom: 100%; + content: ' '; + height: 0; + width: 0; + position: absolute; + pointer-events: none; + margin-left: -10px; + } } /* removed until content-focusing issue is fixed */ @@ -194,21 +209,8 @@ border-top-right-radius: 0; display: none; box-sizing: border-box; - /*overflow-y: auto; - overflow-x: hidden;*/ z-index: 2000; &:after { - bottom: 100%; - border: solid transparent; - content: ' '; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - border-color: rgba(0, 0, 0, 0); - border-bottom-color: rgba(255, 255, 255, 0.97); - border-width: 10px; - margin-left: -10px; left: 47%; } * { @@ -381,16 +383,6 @@ &:after { /* position of dropdown arrow */ right: 15px; - border: 10px solid transparent; - border-color: transparent; - border-bottom-color: #fff; - bottom: 100%; - content: ' '; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - margin-left: -10px; } a { display: block; diff --git a/core/l10n/zh_CN.js b/core/l10n/zh_CN.js index 47101cfe384..1ce7f1c45f3 100644 --- a/core/l10n/zh_CN.js +++ b/core/l10n/zh_CN.js @@ -146,7 +146,7 @@ OC.L10N.register( "An error occurred. Please try again" : "发生错误. 请重试.", "{sharee} (group)" : "{sharee} (分组)", "{sharee} (remote)" : "{sharee} (外部)", - "{sharee} (email)" : "{sharee} (邮件)", + "{sharee} (email)" : "{sharee} (邮件)", "Share" : "分享", "Share with people on other servers using their Federated Cloud ID username@example.com/nextcloud" : "使用联合云ID与其他服务器的用户分享, 如 用户名@example.com/nextcloud", "Share with users or by mail..." : "通过邮件分享...", @@ -309,13 +309,13 @@ OC.L10N.register( "Thu." : "周四", "Fri." : "周五", "Sat." : "周六", - "Su" : "日", - "Mo" : "一", + "Su" : "日", + "Mo" : "一", "Tu" : "二", - "We" : "三", + "We" : "三", "Th" : "四", "Fr" : "五", - "Sa" : "六", + "Sa" : "六", "January" : "一月", "February" : "二月", "March" : "三月", diff --git a/core/l10n/zh_CN.json b/core/l10n/zh_CN.json index 23134b325d7..bac9b3468a1 100644 --- a/core/l10n/zh_CN.json +++ b/core/l10n/zh_CN.json @@ -144,7 +144,7 @@ "An error occurred. Please try again" : "发生错误. 请重试.", "{sharee} (group)" : "{sharee} (分组)", "{sharee} (remote)" : "{sharee} (外部)", - "{sharee} (email)" : "{sharee} (邮件)", + "{sharee} (email)" : "{sharee} (邮件)", "Share" : "分享", "Share with people on other servers using their Federated Cloud ID username@example.com/nextcloud" : "使用联合云ID与其他服务器的用户分享, 如 用户名@example.com/nextcloud", "Share with users or by mail..." : "通过邮件分享...", @@ -307,13 +307,13 @@ "Thu." : "周四", "Fri." : "周五", "Sat." : "周六", - "Su" : "日", - "Mo" : "一", + "Su" : "日", + "Mo" : "一", "Tu" : "二", - "We" : "三", + "We" : "三", "Th" : "四", "Fr" : "五", - "Sa" : "六", + "Sa" : "六", "January" : "一月", "February" : "二月", "March" : "三月", diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index 5e00b31ae41..9c4a2f2728b 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -131,6 +131,9 @@ return array( 'OCP\\Files\\NotEnoughSpaceException' => $baseDir . '/lib/public/Files/NotEnoughSpaceException.php', 'OCP\\Files\\NotFoundException' => $baseDir . '/lib/public/Files/NotFoundException.php', 'OCP\\Files\\NotPermittedException' => $baseDir . '/lib/public/Files/NotPermittedException.php', + 'OCP\\Files\\Notify\\IChange' => $baseDir . '/lib/public/Files/Notify/IChange.php', + 'OCP\\Files\\Notify\\INotifyHandler' => $baseDir . '/lib/public/Files/Notify/INotifyHandler.php', + 'OCP\\Files\\Notify\\IRenameChange' => $baseDir . '/lib/public/Files/Notify/IRenameChange.php', 'OCP\\Files\\ObjectStore\\IObjectStore' => $baseDir . '/lib/public/Files/ObjectStore/IObjectStore.php', 'OCP\\Files\\ReservedWordException' => $baseDir . '/lib/public/Files/ReservedWordException.php', 'OCP\\Files\\SimpleFS\\ISimpleFile' => $baseDir . '/lib/public/Files/SimpleFS/ISimpleFile.php', @@ -527,6 +530,8 @@ return array( 'OC\\Files\\Node\\NonExistingFile' => $baseDir . '/lib/private/Files/Node/NonExistingFile.php', 'OC\\Files\\Node\\NonExistingFolder' => $baseDir . '/lib/private/Files/Node/NonExistingFolder.php', 'OC\\Files\\Node\\Root' => $baseDir . '/lib/private/Files/Node/Root.php', + 'OC\\Files\\Notify\\Change' => $baseDir . '/lib/private/Files/Notify/Change.php', + 'OC\\Files\\Notify\\RenameChange' => $baseDir . '/lib/private/Files/Notify/RenameChange.php', 'OC\\Files\\ObjectStore\\HomeObjectStoreStorage' => $baseDir . '/lib/private/Files/ObjectStore/HomeObjectStoreStorage.php', 'OC\\Files\\ObjectStore\\Mapper' => $baseDir . '/lib/private/Files/ObjectStore/Mapper.php', 'OC\\Files\\ObjectStore\\NoopScanner' => $baseDir . '/lib/private/Files/ObjectStore/NoopScanner.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index 040a1e0d2d3..de1047e9729 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -161,6 +161,9 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OCP\\Files\\NotEnoughSpaceException' => __DIR__ . '/../../..' . '/lib/public/Files/NotEnoughSpaceException.php', 'OCP\\Files\\NotFoundException' => __DIR__ . '/../../..' . '/lib/public/Files/NotFoundException.php', 'OCP\\Files\\NotPermittedException' => __DIR__ . '/../../..' . '/lib/public/Files/NotPermittedException.php', + 'OCP\\Files\\Notify\\IChange' => __DIR__ . '/../../..' . '/lib/public/Files/Notify/IChange.php', + 'OCP\\Files\\Notify\\INotifyHandler' => __DIR__ . '/../../..' . '/lib/public/Files/Notify/INotifyHandler.php', + 'OCP\\Files\\Notify\\IRenameChange' => __DIR__ . '/../../..' . '/lib/public/Files/Notify/IRenameChange.php', 'OCP\\Files\\ObjectStore\\IObjectStore' => __DIR__ . '/../../..' . '/lib/public/Files/ObjectStore/IObjectStore.php', 'OCP\\Files\\ReservedWordException' => __DIR__ . '/../../..' . '/lib/public/Files/ReservedWordException.php', 'OCP\\Files\\SimpleFS\\ISimpleFile' => __DIR__ . '/../../..' . '/lib/public/Files/SimpleFS/ISimpleFile.php', @@ -557,6 +560,8 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OC\\Files\\Node\\NonExistingFile' => __DIR__ . '/../../..' . '/lib/private/Files/Node/NonExistingFile.php', 'OC\\Files\\Node\\NonExistingFolder' => __DIR__ . '/../../..' . '/lib/private/Files/Node/NonExistingFolder.php', 'OC\\Files\\Node\\Root' => __DIR__ . '/../../..' . '/lib/private/Files/Node/Root.php', + 'OC\\Files\\Notify\\Change' => __DIR__ . '/../../..' . '/lib/private/Files/Notify/Change.php', + 'OC\\Files\\Notify\\RenameChange' => __DIR__ . '/../../..' . '/lib/private/Files/Notify/RenameChange.php', 'OC\\Files\\ObjectStore\\HomeObjectStoreStorage' => __DIR__ . '/../../..' . '/lib/private/Files/ObjectStore/HomeObjectStoreStorage.php', 'OC\\Files\\ObjectStore\\Mapper' => __DIR__ . '/../../..' . '/lib/private/Files/ObjectStore/Mapper.php', 'OC\\Files\\ObjectStore\\NoopScanner' => __DIR__ . '/../../..' . '/lib/private/Files/ObjectStore/NoopScanner.php', diff --git a/lib/l10n/zh_CN.js b/lib/l10n/zh_CN.js index 05aa8cab94e..e2c683b68bb 100644 --- a/lib/l10n/zh_CN.js +++ b/lib/l10n/zh_CN.js @@ -2,19 +2,24 @@ OC.L10N.register( "lib", { "Cannot write into \"config\" directory!" : "无法写入 \"config\" 目录!", - "This can usually be fixed by giving the webserver write access to the config directory" : "对 Web 服务器设置 config 目录的写权限可以修复这个问题.", + "This can usually be fixed by giving the webserver write access to the config directory" : "您可以设置 Web 服务器对 config 目录的写权限修复这个问题", "See %s" : "查看 %s", - "This can usually be fixed by %sgiving the webserver write access to the config directory%s." : "对 Web 服务器%s设置 config 目录%s的写权限可以修复这个问题.", + "This can usually be fixed by %sgiving the webserver write access to the config directory%s." : "您可以由 %s 设置 Web 服务器对 config 目录 %s 的写权限修复这个问题", + "The files of the app %$1s were not replaced correctly. Make sure it is a version compatible with the server." : "应用 %$1s 的文件替换不正确. 请确认版本与当前服务器兼容.", "Sample configuration detected" : "示例配置检测", + "It has been detected that the sample configuration has been copied. This can break your installation and is unsupported. Please read the documentation before performing changes on config.php" : "您似乎直接把 config.php 的样例文件直接复制使用. 这可能会破坏您的安装. 在对 config.php 进行修改之前请先阅读相关文档.", "%1$s and %2$s" : "%1$s 和 %2$s", "%1$s, %2$s and %3$s" : "%1$s, %2$s 和 %3$s", "%1$s, %2$s, %3$s and %4$s" : "%1$s, %2$s, %3$s 和 %4$s", "%1$s, %2$s, %3$s, %4$s and %5$s" : "%1$s, %2$s, %3$s, %4$s 和 %5$s", "PHP %s or higher is required." : "要求 PHP 版本 %s 或者更高。", "PHP with a version lower than %s is required." : "需要版本低于 %s 的PHP.", + "%sbit or higher PHP required." : "需要 %s 或更高版本的 PHP", "Following databases are supported: %s" : "支持以下数据库: %s", "The command line tool %s could not be found" : "命令行工具 %s 未找到", "The library %s is not available." : "库文件 %s 不可用", + "Library %s with a version higher than %s is required - available version %s." : "%s 需要 %s 或更高的版本 - 可用版本 %s.", + "Library %s with a version lower than %s is required - available version %s." : "%s 需要 %s 或更低的版本 - 可用版本 %s.", "Following platforms are supported: %s" : "支持以下平台:%s", "Server version %s or higher is required." : "需要服务器版本 %s 或更高版本。", "Server version %s or lower is required." : "需要服务器版本 %s 或更低版本。", @@ -31,6 +36,7 @@ OC.L10N.register( "_%n hour ago_::_%n hours ago_" : ["%n 小时前"], "_%n minute ago_::_%n minutes ago_" : ["%n 分钟前"], "seconds ago" : "秒前", + "Module with id: %s does not exist. Please enable it in your apps settings or contact your administrator." : "ID 为 %s 的模块不存在. 请在应用设置中启用或联系您的管理员.", "File name is a reserved word" : "文件名包含敏感字符", "File name contains at least one invalid character" : "文件名中存在至少一个非法字符", "File name is too long" : "文件名过长", @@ -64,27 +70,37 @@ OC.L10N.register( "Invalid Federated Cloud ID" : "无效的联合云ID", "%s shared »%s« with you" : "%s 向您分享了 »%s«", "%s via %s" : "%s 通过 %s", - "Sharing %s failed, because the file does not exist" : "共享 %s 失败,因为文件不存在。", + "Sharing %s failed, because the backend does not allow shares from type %i" : "分享 %s 失败, 因为后端不允许分享 %i 类型", + "Sharing %s failed, because the file does not exist" : "分享 %s 失败, 因为文件不存在.", "You are not allowed to share %s" : "您无权分享 %s", - "Sharing %s failed, because the user %s does not exist" : "共享 %s 失败,因为用户 %s 不存在", - "Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "共享 %s 失败,因为用户 %s 不是 %s 所属的任何组的用户", - "Sharing %s failed, because this item is already shared with %s" : "共享 %s 失败,因为它已经共享给 %s", - "Sharing %s failed, because the group %s does not exist" : "共享 %s 失败,因为 %s 组不存在", - "Sharing %s failed, because %s is not a member of the group %s" : "共享 %s 失败,因为 %s 不是 %s 组的成员", - "Sharing %s failed, because sharing with links is not allowed" : "共享 %s 失败,因为不允许用链接共享", + "Sharing %s failed, because you can not share with yourself" : "分享 %s 失败, 因为您不能分享给自己", + "Sharing %s failed, because the user %s does not exist" : "分享 %s 失败, 因为用户 %s 不存在", + "Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "分享 %s 失败, 因为用户 %s 不是 %s 所属的任何组的用户", + "Sharing %s failed, because this item is already shared with %s" : "分享 %s 失败, 因为该项已经分享给用户 %s", + "Sharing %s failed, because this item is already shared with user %s" : "分享 %s 失败, 因为该项已经分享给用户 %s", + "Sharing %s failed, because the group %s does not exist" : "分享 %s 失败, 因为 %s 分组不存在", + "Sharing %s failed, because %s is not a member of the group %s" : "分享 %s 失败, 因为 %s 不是 %s 分组的成员", + "You need to provide a password to create a public link, only protected links are allowed" : "链接分享需要密码, 您需要提供一个密码以创建公开连接", + "Sharing %s failed, because sharing with links is not allowed" : "分享 %s 失败, 因为不允许使用链接分享", "Not allowed to create a federated share with the same user" : "不能给你自己分享文件", - "Sharing %s failed, could not find %s, maybe the server is currently unreachable." : "文件:%s 分享失败,联合云无法找到 %s,请检查设置或联系管理员。", + "Sharing %s failed, could not find %s, maybe the server is currently unreachable." : "分享 %s 失败, 无法找到 %s, 该服务当前无法连接.", "Share type %s is not valid for %s" : "%s 不是 %s 的合法共享类型", "Setting permissions for %s failed, because the permissions exceed permissions granted to %s" : "设置 %s 权限失败,因为权限超出了 %s 已有权限。", "Setting permissions for %s failed, because the item was not found" : "设置 %s 的权限失败,因为未找到到对应项", - "Sharing backend %s must implement the interface OCP\\Share_Backend" : "共享后端 %s 必须实现 OCP\\Share_Backend 接口", - "Sharing backend %s not found" : "未找到共享后端 %s", - "Sharing backend for %s not found" : "%s 的共享后端未找到", - "Sharing %s failed, because the permissions exceed permissions granted to %s" : "共享 %s 失败,因为权限超过了 %s 已有权限", - "Sharing %s failed, because resharing is not allowed" : "共享 %s 失败,因为不允许二次共享", - "Sharing %s failed, because the sharing backend for %s could not find its source" : "共享 %s 失败,因为 %s 使用的共享后端未找到它的来源", - "Sharing %s failed, because the file could not be found in the file cache" : "共享 %s 失败,因为未在文件缓存中找到文件。", + "Cannot set expiration date. Shares cannot expire later than %s after they have been shared" : "无法设置过期时间. 过期时间不能晚于其分享时间 %s", + "Cannot set expiration date. Expiration date is in the past" : "无法设置过期时间. 过期时间不能为过去", + "Cannot clear expiration date. Shares are required to have an expiration date." : "无法清除过期时间. 每个分享必须有一个过期时间", + "Sharing backend %s must implement the interface OCP\\Share_Backend" : "分享后端 %s 必须实现 OCP\\Share_Backend 接口", + "Sharing backend %s not found" : "%s 的分享后端未找到", + "Sharing backend for %s not found" : "%s 的分享后端未找到", + "Sharing failed, because the user %s is the original sharer" : "分享失败, 因为用户 %s 是原始的分享者.", + "Sharing %s failed, because the permissions exceed permissions granted to %s" : "分享 %s 失败, 因为权限超过了 %s 的已有权限", + "Sharing %s failed, because resharing is not allowed" : "分享 %s 失败, 因为不允许二次共享", + "Sharing %s failed, because the sharing backend for %s could not find its source" : "分享 %s 失败, 因为无法找到 %s 分享后端的来源", + "Sharing %s failed, because the file could not be found in the file cache" : "分享 %s 失败, 因为文件缓存中找不到该文件", "Cannot increase permissions of %s" : "无法提升 %s 的权限", + "Files can't be shared with delete permissions" : "无法分享有删除权限的文件", + "Files can't be shared with create permissions" : "无法分享有创建权限的文件", "Expiration date is in the past" : "到期日期已过.", "Cannot set expiration date more than %s days in the future" : "无法将过期日期设置为超过 %s 天.", "Could not find category \"%s\"" : "无法找到分类 \"%s\"", @@ -102,13 +118,13 @@ OC.L10N.register( "Thu." : "周四", "Fri." : "周五", "Sat." : "周六", - "Su" : "日", - "Mo" : "一", + "Su" : "日", + "Mo" : "一", "Tu" : "二", - "We" : "三", + "We" : "三", "Th" : "四", "Fr" : "五", - "Sa" : "六", + "Sa" : "六", "January" : "一月", "February" : "二月", "March" : "三月", @@ -150,6 +166,7 @@ OC.L10N.register( "No app name specified" : "没有指定的 App 名称", "App '%s' could not be installed!" : "应用程序 '%s' 无法被安装!", "App \"%s\" cannot be installed because the following dependencies are not fulfilled: %s" : "应用程序 \"%s\" 无法被安装,因为为满足下列依赖关系: %s", + "a safe home for all your data" : "给您所有的数据一个安全的家", "File is currently busy, please try again later" : "文件当前正忙,请稍后再试", "Can't read file" : "无法读取文件", "Application is not enabled" : "应用程序未启用", @@ -159,7 +176,10 @@ OC.L10N.register( "No database drivers (sqlite, mysql, or postgresql) installed." : "没有安装数据库驱动 (SQLite、MySQL 或 PostgreSQL)。", "Cannot write into \"config\" directory" : "无法写入“config”目录", "Cannot write into \"apps\" directory" : "无法写入“apps”目录", + "This can usually be fixed by %sgiving the webserver write access to the apps directory%s or disabling the appstore in the config file." : "您可以由 %s 设置 Web 服务器对应用目录 %s 的写权限或在配置文件中禁用应用商店可以修复这个问题.", "Cannot create \"data\" directory (%s)" : "无法创建“apps”目录 (%s)", + "This can usually be fixed by <a href=\"%s\" target=\"_blank\" rel=\"noreferrer\">giving the webserver write access to the root directory</a>." : "点击 <a href=\"%s\" target=\"_blank\" rel=\"noreferrer\">设置 Web 服务器对根目录的写入权限</a> 可修复这个问题.", + "Permissions can usually be fixed by %sgiving the webserver write access to the root directory%s." : "您可以由 %s 设置 Web 服务器对根目录 %s 的写权限可以修复这个问题.", "Setting locale to %s failed" : "设置语言为 %s 失败", "Please install one of these locales on your system and restart your webserver." : "请在您的系统中安装下述一种语言并重启 Web 服务器.", "Please ask your server administrator to install the module." : "请联系服务器管理员安装模块.", @@ -170,6 +190,7 @@ OC.L10N.register( "To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini" : "请在 php.ini 中设置 <code>mbstring.func_overload</code> 为 <code>0</code> 以解决该问题", "libxml2 2.7.0 is at least required. Currently %s is installed." : "至少需要 libxml2 2.7.0. 当前安装 %s.", "To fix this issue update your libxml2 version and restart your web server." : "升级您的 libxml2 版本然后重启 Web 服务器以解决该问题.", + "PHP is apparently set up to strip inline doc blocks. This will make several core apps inaccessible." : "PHP 被设置为移除内联块, 这将导致多个核心应用无法访问.", "This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "这可能由缓存/加速器导致的, 例如 Zend OPcache 或 eAccelerator.", "PHP modules have been installed, but they are still listed as missing?" : "PHP 模块已经安装, 但仍然显示未安装?", "Please ask your server administrator to restart the web server." : "请联系服务器管理员重启 Web 服务器.", diff --git a/lib/l10n/zh_CN.json b/lib/l10n/zh_CN.json index 0bcf8862f1a..f5b88f87ad9 100644 --- a/lib/l10n/zh_CN.json +++ b/lib/l10n/zh_CN.json @@ -1,18 +1,23 @@ { "translations": { "Cannot write into \"config\" directory!" : "无法写入 \"config\" 目录!", - "This can usually be fixed by giving the webserver write access to the config directory" : "对 Web 服务器设置 config 目录的写权限可以修复这个问题.", + "This can usually be fixed by giving the webserver write access to the config directory" : "您可以设置 Web 服务器对 config 目录的写权限修复这个问题", "See %s" : "查看 %s", - "This can usually be fixed by %sgiving the webserver write access to the config directory%s." : "对 Web 服务器%s设置 config 目录%s的写权限可以修复这个问题.", + "This can usually be fixed by %sgiving the webserver write access to the config directory%s." : "您可以由 %s 设置 Web 服务器对 config 目录 %s 的写权限修复这个问题", + "The files of the app %$1s were not replaced correctly. Make sure it is a version compatible with the server." : "应用 %$1s 的文件替换不正确. 请确认版本与当前服务器兼容.", "Sample configuration detected" : "示例配置检测", + "It has been detected that the sample configuration has been copied. This can break your installation and is unsupported. Please read the documentation before performing changes on config.php" : "您似乎直接把 config.php 的样例文件直接复制使用. 这可能会破坏您的安装. 在对 config.php 进行修改之前请先阅读相关文档.", "%1$s and %2$s" : "%1$s 和 %2$s", "%1$s, %2$s and %3$s" : "%1$s, %2$s 和 %3$s", "%1$s, %2$s, %3$s and %4$s" : "%1$s, %2$s, %3$s 和 %4$s", "%1$s, %2$s, %3$s, %4$s and %5$s" : "%1$s, %2$s, %3$s, %4$s 和 %5$s", "PHP %s or higher is required." : "要求 PHP 版本 %s 或者更高。", "PHP with a version lower than %s is required." : "需要版本低于 %s 的PHP.", + "%sbit or higher PHP required." : "需要 %s 或更高版本的 PHP", "Following databases are supported: %s" : "支持以下数据库: %s", "The command line tool %s could not be found" : "命令行工具 %s 未找到", "The library %s is not available." : "库文件 %s 不可用", + "Library %s with a version higher than %s is required - available version %s." : "%s 需要 %s 或更高的版本 - 可用版本 %s.", + "Library %s with a version lower than %s is required - available version %s." : "%s 需要 %s 或更低的版本 - 可用版本 %s.", "Following platforms are supported: %s" : "支持以下平台:%s", "Server version %s or higher is required." : "需要服务器版本 %s 或更高版本。", "Server version %s or lower is required." : "需要服务器版本 %s 或更低版本。", @@ -29,6 +34,7 @@ "_%n hour ago_::_%n hours ago_" : ["%n 小时前"], "_%n minute ago_::_%n minutes ago_" : ["%n 分钟前"], "seconds ago" : "秒前", + "Module with id: %s does not exist. Please enable it in your apps settings or contact your administrator." : "ID 为 %s 的模块不存在. 请在应用设置中启用或联系您的管理员.", "File name is a reserved word" : "文件名包含敏感字符", "File name contains at least one invalid character" : "文件名中存在至少一个非法字符", "File name is too long" : "文件名过长", @@ -62,27 +68,37 @@ "Invalid Federated Cloud ID" : "无效的联合云ID", "%s shared »%s« with you" : "%s 向您分享了 »%s«", "%s via %s" : "%s 通过 %s", - "Sharing %s failed, because the file does not exist" : "共享 %s 失败,因为文件不存在。", + "Sharing %s failed, because the backend does not allow shares from type %i" : "分享 %s 失败, 因为后端不允许分享 %i 类型", + "Sharing %s failed, because the file does not exist" : "分享 %s 失败, 因为文件不存在.", "You are not allowed to share %s" : "您无权分享 %s", - "Sharing %s failed, because the user %s does not exist" : "共享 %s 失败,因为用户 %s 不存在", - "Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "共享 %s 失败,因为用户 %s 不是 %s 所属的任何组的用户", - "Sharing %s failed, because this item is already shared with %s" : "共享 %s 失败,因为它已经共享给 %s", - "Sharing %s failed, because the group %s does not exist" : "共享 %s 失败,因为 %s 组不存在", - "Sharing %s failed, because %s is not a member of the group %s" : "共享 %s 失败,因为 %s 不是 %s 组的成员", - "Sharing %s failed, because sharing with links is not allowed" : "共享 %s 失败,因为不允许用链接共享", + "Sharing %s failed, because you can not share with yourself" : "分享 %s 失败, 因为您不能分享给自己", + "Sharing %s failed, because the user %s does not exist" : "分享 %s 失败, 因为用户 %s 不存在", + "Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "分享 %s 失败, 因为用户 %s 不是 %s 所属的任何组的用户", + "Sharing %s failed, because this item is already shared with %s" : "分享 %s 失败, 因为该项已经分享给用户 %s", + "Sharing %s failed, because this item is already shared with user %s" : "分享 %s 失败, 因为该项已经分享给用户 %s", + "Sharing %s failed, because the group %s does not exist" : "分享 %s 失败, 因为 %s 分组不存在", + "Sharing %s failed, because %s is not a member of the group %s" : "分享 %s 失败, 因为 %s 不是 %s 分组的成员", + "You need to provide a password to create a public link, only protected links are allowed" : "链接分享需要密码, 您需要提供一个密码以创建公开连接", + "Sharing %s failed, because sharing with links is not allowed" : "分享 %s 失败, 因为不允许使用链接分享", "Not allowed to create a federated share with the same user" : "不能给你自己分享文件", - "Sharing %s failed, could not find %s, maybe the server is currently unreachable." : "文件:%s 分享失败,联合云无法找到 %s,请检查设置或联系管理员。", + "Sharing %s failed, could not find %s, maybe the server is currently unreachable." : "分享 %s 失败, 无法找到 %s, 该服务当前无法连接.", "Share type %s is not valid for %s" : "%s 不是 %s 的合法共享类型", "Setting permissions for %s failed, because the permissions exceed permissions granted to %s" : "设置 %s 权限失败,因为权限超出了 %s 已有权限。", "Setting permissions for %s failed, because the item was not found" : "设置 %s 的权限失败,因为未找到到对应项", - "Sharing backend %s must implement the interface OCP\\Share_Backend" : "共享后端 %s 必须实现 OCP\\Share_Backend 接口", - "Sharing backend %s not found" : "未找到共享后端 %s", - "Sharing backend for %s not found" : "%s 的共享后端未找到", - "Sharing %s failed, because the permissions exceed permissions granted to %s" : "共享 %s 失败,因为权限超过了 %s 已有权限", - "Sharing %s failed, because resharing is not allowed" : "共享 %s 失败,因为不允许二次共享", - "Sharing %s failed, because the sharing backend for %s could not find its source" : "共享 %s 失败,因为 %s 使用的共享后端未找到它的来源", - "Sharing %s failed, because the file could not be found in the file cache" : "共享 %s 失败,因为未在文件缓存中找到文件。", + "Cannot set expiration date. Shares cannot expire later than %s after they have been shared" : "无法设置过期时间. 过期时间不能晚于其分享时间 %s", + "Cannot set expiration date. Expiration date is in the past" : "无法设置过期时间. 过期时间不能为过去", + "Cannot clear expiration date. Shares are required to have an expiration date." : "无法清除过期时间. 每个分享必须有一个过期时间", + "Sharing backend %s must implement the interface OCP\\Share_Backend" : "分享后端 %s 必须实现 OCP\\Share_Backend 接口", + "Sharing backend %s not found" : "%s 的分享后端未找到", + "Sharing backend for %s not found" : "%s 的分享后端未找到", + "Sharing failed, because the user %s is the original sharer" : "分享失败, 因为用户 %s 是原始的分享者.", + "Sharing %s failed, because the permissions exceed permissions granted to %s" : "分享 %s 失败, 因为权限超过了 %s 的已有权限", + "Sharing %s failed, because resharing is not allowed" : "分享 %s 失败, 因为不允许二次共享", + "Sharing %s failed, because the sharing backend for %s could not find its source" : "分享 %s 失败, 因为无法找到 %s 分享后端的来源", + "Sharing %s failed, because the file could not be found in the file cache" : "分享 %s 失败, 因为文件缓存中找不到该文件", "Cannot increase permissions of %s" : "无法提升 %s 的权限", + "Files can't be shared with delete permissions" : "无法分享有删除权限的文件", + "Files can't be shared with create permissions" : "无法分享有创建权限的文件", "Expiration date is in the past" : "到期日期已过.", "Cannot set expiration date more than %s days in the future" : "无法将过期日期设置为超过 %s 天.", "Could not find category \"%s\"" : "无法找到分类 \"%s\"", @@ -100,13 +116,13 @@ "Thu." : "周四", "Fri." : "周五", "Sat." : "周六", - "Su" : "日", - "Mo" : "一", + "Su" : "日", + "Mo" : "一", "Tu" : "二", - "We" : "三", + "We" : "三", "Th" : "四", "Fr" : "五", - "Sa" : "六", + "Sa" : "六", "January" : "一月", "February" : "二月", "March" : "三月", @@ -148,6 +164,7 @@ "No app name specified" : "没有指定的 App 名称", "App '%s' could not be installed!" : "应用程序 '%s' 无法被安装!", "App \"%s\" cannot be installed because the following dependencies are not fulfilled: %s" : "应用程序 \"%s\" 无法被安装,因为为满足下列依赖关系: %s", + "a safe home for all your data" : "给您所有的数据一个安全的家", "File is currently busy, please try again later" : "文件当前正忙,请稍后再试", "Can't read file" : "无法读取文件", "Application is not enabled" : "应用程序未启用", @@ -157,7 +174,10 @@ "No database drivers (sqlite, mysql, or postgresql) installed." : "没有安装数据库驱动 (SQLite、MySQL 或 PostgreSQL)。", "Cannot write into \"config\" directory" : "无法写入“config”目录", "Cannot write into \"apps\" directory" : "无法写入“apps”目录", + "This can usually be fixed by %sgiving the webserver write access to the apps directory%s or disabling the appstore in the config file." : "您可以由 %s 设置 Web 服务器对应用目录 %s 的写权限或在配置文件中禁用应用商店可以修复这个问题.", "Cannot create \"data\" directory (%s)" : "无法创建“apps”目录 (%s)", + "This can usually be fixed by <a href=\"%s\" target=\"_blank\" rel=\"noreferrer\">giving the webserver write access to the root directory</a>." : "点击 <a href=\"%s\" target=\"_blank\" rel=\"noreferrer\">设置 Web 服务器对根目录的写入权限</a> 可修复这个问题.", + "Permissions can usually be fixed by %sgiving the webserver write access to the root directory%s." : "您可以由 %s 设置 Web 服务器对根目录 %s 的写权限可以修复这个问题.", "Setting locale to %s failed" : "设置语言为 %s 失败", "Please install one of these locales on your system and restart your webserver." : "请在您的系统中安装下述一种语言并重启 Web 服务器.", "Please ask your server administrator to install the module." : "请联系服务器管理员安装模块.", @@ -168,6 +188,7 @@ "To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini" : "请在 php.ini 中设置 <code>mbstring.func_overload</code> 为 <code>0</code> 以解决该问题", "libxml2 2.7.0 is at least required. Currently %s is installed." : "至少需要 libxml2 2.7.0. 当前安装 %s.", "To fix this issue update your libxml2 version and restart your web server." : "升级您的 libxml2 版本然后重启 Web 服务器以解决该问题.", + "PHP is apparently set up to strip inline doc blocks. This will make several core apps inaccessible." : "PHP 被设置为移除内联块, 这将导致多个核心应用无法访问.", "This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "这可能由缓存/加速器导致的, 例如 Zend OPcache 或 eAccelerator.", "PHP modules have been installed, but they are still listed as missing?" : "PHP 模块已经安装, 但仍然显示未安装?", "Please ask your server administrator to restart the web server." : "请联系服务器管理员重启 Web 服务器.", diff --git a/lib/private/Files/Notify/Change.php b/lib/private/Files/Notify/Change.php new file mode 100644 index 00000000000..78cc007b27d --- /dev/null +++ b/lib/private/Files/Notify/Change.php @@ -0,0 +1,65 @@ +<?php +/** + * @copyright Copyright (c) 2017 Robin Appelman <robin@icewind.nl> + * + * @author Robin Appelman <robin@icewind.nl> + * + * @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 OC\Files\Notify; + +use OCP\Files\Notify\IChange; + +class Change implements IChange { + /** @var int */ + private $type; + + /** @var string */ + private $path; + + /** + * Change constructor. + * + * @param int $type + * @param string $path + */ + public function __construct($type, $path) { + $this->type = $type; + $this->path = $path; + } + + /** + * Get the type of the change + * + * @return int IChange::ADDED, IChange::REMOVED, IChange::MODIFIED or IChange::RENAMED + */ + public function getType() { + return $this->type; + } + + /** + * Get the path of the file that was changed relative to the root of the storage + * + * Note, for rename changes this path is the old path for the file + * + * @return mixed + */ + public function getPath() { + return $this->path; + } +} diff --git a/lib/private/Files/Notify/RenameChange.php b/lib/private/Files/Notify/RenameChange.php new file mode 100644 index 00000000000..b83dffa0cb2 --- /dev/null +++ b/lib/private/Files/Notify/RenameChange.php @@ -0,0 +1,52 @@ +<?php +/** + * @copyright Copyright (c) 2017 Robin Appelman <robin@icewind.nl> + * + * @author Robin Appelman <robin@icewind.nl> + * + * @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 OC\Files\Notify; + +use OCP\Files\Notify\IRenameChange; + +class RenameChange extends Change implements IRenameChange { + /** @var string */ + private $targetPath; + + /** + * Change constructor. + * + * @param int $type + * @param string $path + * @param string $targetPath + */ + public function __construct($type, $path, $targetPath) { + parent::__construct($type, $path); + $this->targetPath = $targetPath; + } + + /** + * Get the new path of the renamed file relative to the storage root + * + * @return string + */ + public function getTargetPath() { + return $this->targetPath; + } +} diff --git a/lib/private/Files/Storage/Local.php b/lib/private/Files/Storage/Local.php index 4fe7dcafbbf..80d48680be1 100644 --- a/lib/private/Files/Storage/Local.php +++ b/lib/private/Files/Storage/Local.php @@ -205,18 +205,7 @@ class Local extends \OC\Files\Storage\Common { } public function file_get_contents($path) { - // file_get_contents() has a memory leak: https://bugs.php.net/bug.php?id=61961 - $fileName = $this->getSourcePath($path); - - $fileSize = filesize($fileName); - if ($fileSize === 0) { - return ''; - } - - $handle = fopen($fileName, 'rb'); - $content = fread($handle, $fileSize); - fclose($handle); - return $content; + return file_get_contents($this->getSourcePath($path)); } public function file_put_contents($path, $data) { diff --git a/lib/private/Repair/MoveUpdaterStepFile.php b/lib/private/Repair/MoveUpdaterStepFile.php index fabaff40d24..feb8a291282 100644 --- a/lib/private/Repair/MoveUpdaterStepFile.php +++ b/lib/private/Repair/MoveUpdaterStepFile.php @@ -44,7 +44,7 @@ class MoveUpdaterStepFile implements IRepairStep { public function run(IOutput $output) { - $dataDir = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT); + $dataDir = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data'); $instanceId = $this->config->getSystemValue('instanceid', null); if(!is_string($instanceId) || empty($instanceId)) { diff --git a/lib/private/Setup/Sqlite.php b/lib/private/Setup/Sqlite.php index 63b970be42e..4d860103b60 100644 --- a/lib/private/Setup/Sqlite.php +++ b/lib/private/Setup/Sqlite.php @@ -33,7 +33,7 @@ class Sqlite extends AbstractDatabase { } public function setupDatabase($username) { - $datadir = \OC::$server->getSystemConfig()->getValue('datadirectory'); + $datadir = \OC::$server->getSystemConfig()->getValue('datadirectory', \OC::$SERVERROOT . '/data'); //delete the old sqlite database first, might cause infinte loops otherwise if(file_exists("$datadir/owncloud.db")) { diff --git a/lib/private/User/User.php b/lib/private/User/User.php index 4b37efe0705..c37bb59028e 100644 --- a/lib/private/User/User.php +++ b/lib/private/User/User.php @@ -267,7 +267,7 @@ class User implements IUser { if ($this->backend->implementsActions(Backend::GET_HOME) and $home = $this->backend->getHome($this->uid)) { $this->home = $home; } elseif ($this->config) { - $this->home = $this->config->getSystemValue('datadirectory') . '/' . $this->uid; + $this->home = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/' . $this->uid; } else { $this->home = \OC::$SERVERROOT . '/data/' . $this->uid; } diff --git a/lib/public/Files/Notify/IChange.php b/lib/public/Files/Notify/IChange.php new file mode 100644 index 00000000000..1e6aaa8abe0 --- /dev/null +++ b/lib/public/Files/Notify/IChange.php @@ -0,0 +1,56 @@ +<?php +/** + * @copyright Copyright (c) 2017 Robin Appelman <robin@icewind.nl> + * + * @author Robin Appelman <robin@icewind.nl> + * + * @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 OCP\Files\Notify; + +/** + * Represents a detected change in the storage + * + * @since 12.0.0 + */ +interface IChange { + const ADDED = 1; + const REMOVED = 2; + const MODIFIED = 3; + const RENAMED = 4; + + /** + * Get the type of the change + * + * @return int IChange::ADDED, IChange::REMOVED, IChange::MODIFIED or IChange::RENAMED + * + * @since 12.0.0 + */ + public function getType(); + + /** + * Get the path of the file that was changed relative to the root of the storage + * + * Note, for rename changes this path is the old path for the file + * + * @return mixed + * + * @since 12.0.0 + */ + public function getPath(); +} diff --git a/lib/public/Files/Notify/INotifyHandler.php b/lib/public/Files/Notify/INotifyHandler.php new file mode 100644 index 00000000000..7e0e6a610d8 --- /dev/null +++ b/lib/public/Files/Notify/INotifyHandler.php @@ -0,0 +1,64 @@ +<?php +/** + * @copyright Copyright (c) 2017 Robin Appelman <robin@icewind.nl> + * + * @author Robin Appelman <robin@icewind.nl> + * + * @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 OCP\Files\Notify; + +/** + * Provides access to detected changes in the storage by either actively listening + * or getting the list of changes that happened in the background + * + * @since 12.0.0 + */ +interface INotifyHandler { + /** + * Start listening for update notifications + * + * The provided callback will be called for every incoming notification with the following parameters + * - IChange|IRenameChange $change + * + * Note that this call is blocking and will not exit on it's own, to stop listening for notifications return `false` from the callback + * + * @param callable $callback + * + * @since 12.0.0 + */ + public function listen(callable $callback); + + /** + * Get all changes detected since the start of the notify process or the last call to getChanges + * + * @return IChange[] + * + * @since 12.0.0 + */ + public function getChanges(); + + /** + * Stop listening for changes + * + * Note that any pending changes will be discarded + * + * @since 12.0.0 + */ + public function stop(); +} diff --git a/lib/public/Files/Notify/IRenameChange.php b/lib/public/Files/Notify/IRenameChange.php new file mode 100644 index 00000000000..c95499a7e74 --- /dev/null +++ b/lib/public/Files/Notify/IRenameChange.php @@ -0,0 +1,40 @@ +<?php +/** + * @copyright Copyright (c) 2017 Robin Appelman <robin@icewind.nl> + * + * @author Robin Appelman <robin@icewind.nl> + * + * @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 OCP\Files\Notify; + +/** + * Represents a detected rename change + * + * @since 12.0.0 + */ +interface IRenameChange extends IChange { + /** + * Get the new path of the renamed file relative to the storage root + * + * @return string + * + * @since 12.0.0 + */ + public function getTargetPath(); +} diff --git a/lib/public/Files/Storage/INotifyStorage.php b/lib/public/Files/Storage/INotifyStorage.php index e99124abdfd..c6fdd44724f 100644 --- a/lib/public/Files/Storage/INotifyStorage.php +++ b/lib/public/Files/Storage/INotifyStorage.php @@ -23,6 +23,8 @@ namespace OCP\Files\Storage; +use OCP\Files\Notify\INotifyHandler; + /** * Storage backend that support active notifications * @@ -48,6 +50,17 @@ interface INotifyStorage { * @param callable $callback * * @since 9.1.0 + * @deprecated 12.0.0 use INotifyStorage::notify()->listen() instead */ public function listen($path, callable $callback); + + /** + * Start the notification handler for this storage + * + * @param $path + * @return INotifyHandler + * + * @since 12.0.0 + */ + public function notify($path); } diff --git a/settings/l10n/sv.js b/settings/l10n/sv.js index 803021a8d31..964c65427cd 100644 --- a/settings/l10n/sv.js +++ b/settings/l10n/sv.js @@ -203,7 +203,7 @@ OC.L10N.register( "To run this you need the PHP posix extension. See {linkstart}PHP documentation{linkend} for more details." : "För att köra detta behöver du PHP posix tillägget. Se {linkstart}PHP dokumentationen{linkend} för ytterligare detaljer.", "Version" : "Version", "Sharing" : "Dela", - "Allow apps to use the Share API" : "Tillåt applikationer att använda delat API", + "Allow apps to use the Share API" : "Tillåt applikationer att använda API för delning", "Allow users to share via link" : "Tillåt användare att dela via länk", "Allow public uploads" : "Tillåt offentlig uppladdning", "Enforce password protection" : "Tillämpa lösenordskydd", diff --git a/settings/l10n/sv.json b/settings/l10n/sv.json index 4024d1b622a..8bfa6e9b38e 100644 --- a/settings/l10n/sv.json +++ b/settings/l10n/sv.json @@ -201,7 +201,7 @@ "To run this you need the PHP posix extension. See {linkstart}PHP documentation{linkend} for more details." : "För att köra detta behöver du PHP posix tillägget. Se {linkstart}PHP dokumentationen{linkend} för ytterligare detaljer.", "Version" : "Version", "Sharing" : "Dela", - "Allow apps to use the Share API" : "Tillåt applikationer att använda delat API", + "Allow apps to use the Share API" : "Tillåt applikationer att använda API för delning", "Allow users to share via link" : "Tillåt användare att dela via länk", "Allow public uploads" : "Tillåt offentlig uppladdning", "Enforce password protection" : "Tillämpa lösenordskydd", diff --git a/settings/l10n/zh_CN.js b/settings/l10n/zh_CN.js index e7edc0dd002..9392b2d92e1 100644 --- a/settings/l10n/zh_CN.js +++ b/settings/l10n/zh_CN.js @@ -229,7 +229,7 @@ OC.L10N.register( "How to do backups" : "如何备份", "Advanced monitoring" : "高级监控", "Performance tuning" : "性能优化", - "Improving the config.php" : "正在优化 config.php", + "Improving the config.php" : "优化 config.php", "Theming" : "主题", "Hardening and security guidance" : "强化和安全指南", "Developer documentation" : "开发者文档", diff --git a/settings/l10n/zh_CN.json b/settings/l10n/zh_CN.json index 4e0f050f3c4..46079a83ceb 100644 --- a/settings/l10n/zh_CN.json +++ b/settings/l10n/zh_CN.json @@ -227,7 +227,7 @@ "How to do backups" : "如何备份", "Advanced monitoring" : "高级监控", "Performance tuning" : "性能优化", - "Improving the config.php" : "正在优化 config.php", + "Improving the config.php" : "优化 config.php", "Theming" : "主题", "Hardening and security guidance" : "强化和安全指南", "Developer documentation" : "开发者文档", |