summaryrefslogtreecommitdiffstats
path: root/apps/files_external/lib/Lib
diff options
context:
space:
mode:
authorMorris Jobke <hey@morrisjobke.de>2017-01-30 17:15:57 -0600
committerGitHub <noreply@github.com>2017-01-30 17:15:57 -0600
commit687e38c40949ac291c036523e6d8cb5f1d8dd180 (patch)
treebe8cf978fbdb1ca1f14d6e3ef0a2da5705d3173c /apps/files_external/lib/Lib
parentf70f427a631436f22eb90f01f74f2e2996cbf75f (diff)
parent90c011379c09821887f9a17e5068ec7f590efc05 (diff)
downloadnextcloud-server-687e38c40949ac291c036523e6d8cb5f1d8dd180.tar.gz
nextcloud-server-687e38c40949ac291c036523e6d8cb5f1d8dd180.zip
Merge pull request #2970 from nextcloud/notify-self-test
Add self-test for files_external:notify
Diffstat (limited to 'apps/files_external/lib/Lib')
-rw-r--r--apps/files_external/lib/Lib/Notify/SMBNotifyHandler.php150
-rw-r--r--apps/files_external/lib/Lib/Storage/SMB.php51
2 files changed, 162 insertions, 39 deletions
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/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);
}
}